summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2013-03-30 23:56:23 +0100
committerArthur de Jong <arthur@arthurdejong.org>2013-03-30 23:56:23 +0100
commitea6bff3e4490c24f71b803add8bda4e992ec7c0e (patch)
treef46da63c43cfa4d27cc3fada77dd9941cc90f07f
parent62a409cb43b441c32692f414a1867176d37034ac (diff)
Implement password modification in pynslcd
-rw-r--r--pynslcd/pam.py70
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