diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-03-30 23:56:23 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-03-30 23:56:23 +0100 |
commit | ea6bff3e4490c24f71b803add8bda4e992ec7c0e (patch) | |
tree | f46da63c43cfa4d27cc3fada77dd9941cc90f07f | |
parent | 62a409cb43b441c32692f414a1867176d37034ac (diff) |
Implement password modification in pynslcd
-rw-r--r-- | pynslcd/pam.py | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/pynslcd/pam.py b/pynslcd/pam.py index 74ae27a..a1a24d0 100644 --- a/pynslcd/pam.py +++ b/pynslcd/pam.py @@ -67,6 +67,18 @@ def authenticate(binddn, password): raise ldap.NO_SUCH_OBJECT() +def pwmod(conn, userdn, oldpassword, newpassword): + # perform request without old password + try: + conn.passwd_s(userdn, None, newpassword) + except ldap.LDAPError: + # retry with old password + if oldpassword: + conn.passwd_s(userdn, oldpassword, newpassword) + else: + raise + + class PAMRequest(common.Request): def validate(self, parameters): @@ -211,6 +223,62 @@ class PAMAuthorisationRequest(PAMRequest): self.write() +class PAMPasswordModificationRequest(PAMRequest): + + action = constants.NSLCD_ACTION_PAM_PWMOD + + def read_parameters(self, fp): + return dict(username=fp.read_string(), + service=fp.read_string(), + ruser=fp.read_string(), + rhost=fp.read_string(), + tty=fp.read_string(), + asroot=fp.read_int32(), + oldpassword=fp.read_string(), + newpassword=fp.read_string()) + # TODO: log call with parameters + + def write(self, rc=constants.NSLCD_PAM_SUCCESS, msg=''): + self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) + self.fp.write_int32(rc) + self.fp.write_string(msg) + self.fp.write_int32(constants.NSLCD_RESULT_END) + + def handle_request(self, parameters): + # fill in any missing userdn, etc. + self.validate(parameters) + # check if pam_password_prohibit_message is set + if cfg.pam_password_prohibit_message: + self.write(parameters, constants.NSLCD_PAM_PERM_DENIED, + cfg.pam_password_prohibit_message) + return + # check if the the user passed the rootpwmoddn + if parameters['asroot']: + binddn = cfg.rootpwmoddn + # check if rootpwmodpw should be used + if not parameters['oldpassword'] and calleruid == 0 and cfg.rootpwmoddn: + password = cfg.rootpwmoddn + else: + password = parameters['oldpassword'] + else: + binddn = parameters['userdn'] + password = parameters['oldpassword'] + # TODO: check if shadow properties allow password change + # perform password modification + try: + conn, authz, msg = authenticate(binddn, password) + pwmod(conn, parameters['userdn'], parameters['oldpassword'], parameters['newpassword']) + except ldap.INVALID_CREDENTIALS, e: + try: + msg = e[0]['desc'] + except: + msg = str(e) + logging.debug('pwmod failed: %s', msg) + self.write(constants.NSLCD_PAM_PERM_DENIED, msg) + return + logging.debug('pwmod successful') + self.write() + + #NSLCD_ACTION_PAM_SESS_O #NSLCD_ACTION_PAM_SESS_C -#NSLCD_ACTION_PAM_PWMOD |