diff --git a/check-password b/check-password new file mode 100755 index 0000000..7978cb8 --- /dev/null +++ b/check-password @@ -0,0 +1,19 @@ +#!/usr/bin/python +import logging +import logging.handlers +import sys + +log = logging.getLogger() +log.setLevel(logging.DEBUG) +log.addHandler(logging.handlers.SysLogHandler(address = '/dev/log')) + +try: + from django.contrib.auth import authenticate + user, password = sys.argv[1:3] + user = authenticate(username=unicode(user, 'utf-8'), password=unicode(password, 'utf-8')) +except: + log.exception('django.contrib.auth.authenticate raised an exception') +else: + if user is None: + sys.exit(1) +sys.exit(0) diff --git a/pam.conf b/pam.conf new file mode 100644 index 0000000..d94d46b --- /dev/null +++ b/pam.conf @@ -0,0 +1,3 @@ +#%PAM-1.0 +auth required pam_python.so pam_django.py helper=/usr/local/lib/pam-django/check-password DJANGO_SETTINGS_MODULE=settings +account required pam_python.so pam_django.py diff --git a/pam_django.py b/pam_django.py index 67f162b..8a1a8f7 100644 --- a/pam_django.py +++ b/pam_django.py @@ -1,18 +1,21 @@ - +import os import syslog +import sys +import subprocess -def auth_log(msg): - syslog.openlog(facility=syslog.LOG_AUTH) - syslog.syslog("django_pam: " + msg) +def auth_log(msg, priority=syslog.LOG_NOTICE): + syslog.openlog(ident='pam-django', facility=syslog.LOG_AUTH) + syslog.syslog(priority, msg) syslog.closelog() def pam_sm_authenticate(pamh, flags, argv): - auth_log("pam_sm_authenticate") + auth_log('sys.path %r' % argv) + argv = dict(arg.split('=', 1) for arg in argv[1:] if '=' in arg) try: user = pamh.get_user(None) except pamh.exception, e: return e.pam_result - + if not user: return pamh.PAM_USER_UNKNOWN @@ -21,10 +24,16 @@ def pam_sm_authenticate(pamh, flags, argv): resp = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, 'Password:')) except pamh.exception, e: return e.pam_result - password = resp.resp - auth_log("%s %s %s" % (pamh.rhost, user, password)) - - return pamh.PAM_SUCCESS + env = os.environ.copy() + if 'DJANGO_SETTINGS_MODULE' in argv: + env['DJANGO_SETTINGS_MODULE'] = argv['DJANGO_SETTINGS_MODULE'] + ret = subprocess.call([argv['helper'], user, resp.resp], + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + if ret == 0: + auth_log('login success') + return pamh.PAM_SUCCESS + auth_log('login failure') + return pamh.PAM_AUTH_ERR def pam_sm_setcred(pamh, flags, argv): auth_log("pam_sm_setcred") @@ -45,3 +54,4 @@ def pam_sm_close_session(pamh, flags, argv): def pam_sm_chauthtok(pamh, flags, argv): auth_log("pam_sm_chauthtok") return pamh.PAM_SUCCESS + diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..6b0a0e3 --- /dev/null +++ b/settings.py @@ -0,0 +1,9 @@ +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': '/home/bdauvergne/Code/docbow/docbow.db', + } +} +INSTALLED_APPS=('django.contrib.auth',) +AUTHENTICATION_BACKENDS=('django.contrib.auth.backends.ModelBackend',) +SECRET_KEY='xxx'