From 120e36c4c54b844fc6a3f7bca93a1629fb50f077 Mon Sep 17 00:00:00 2001 From: Nico von Geyso Date: Mon, 24 Sep 2012 18:38:14 +0200 Subject: use passwd_s for password changes with modify_s passwords will be saved in plain text (base64 encoded). To prevent this security issue we use passwd_s instead of modify_s. --- account.py | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'account.py') diff --git a/account.py b/account.py index e8a9aeb..8045016 100644 --- a/account.py +++ b/account.py @@ -30,10 +30,10 @@ class AccountService: * updates an account >> foo.change_mail('a@b.de') - >> foo.change_password('bar2') # changes root password - >> foo.change_password('bar2', 'gitlab') # changes password for gitlab - >> service.update(foo) # save changes in ldap backend - # save changes in ldap backend as admin user + >> foo.change_password('newpw','oldpw') # changes root password + >> foo.change_password('newpw','oldpw', 'gitlab') # changes password for gitlab + >> service.update(foo) # save changes in ldap backend + # save changes in ldap backend as admin user (no need for old password) >> service.update(foo, as_admin=True) * delete an account @@ -55,6 +55,7 @@ class AccountService: self.admin_user = admin_user self.admin_pass = admin_pass self.services = services + self.admin = False def auth(self, username, password): @@ -184,6 +185,7 @@ class AccountService: self.connection.simple_bind_s(dn, password) def _bind_as_admin(self): + self.admin = True self._bind('cn=%s,%s' % (self.admin_user, self.base_dn), self.admin_pass) def _bind_anonymous(self): @@ -192,24 +194,30 @@ class AccountService: def _unbind(self): self.connection.unbind_s() + self.admin = False def _alter_passwords(self, account): if account.new_password_root: - attr = [ - (ldap.MOD_REPLACE,'userPassword',account.new_password_root) - ] dn = 'uid=%s,ou=users,%s' % (account.uid, self.base_dn) - self.connection.modify_s(dn, attr) + old, new = account.new_password_root + if self.admin: + self.connection.passwd_s(dn, None, new) + else: + self.connection.passwd_s(dn, old, new) + + account.password = new + account.new_password_root = None - for service, password in account.new_password_services.items(): - attr = [ - (ldap.MOD_REPLACE, 'userPassword', password) - ] + for service, passwords in account.new_password_services.items(): dn = 'uid=%s,cn=%s,ou=services,%s' % (account.uid, service, self.base_dn) - self.connection.modify_s(dn, attr) + old, new = passwords + if self.admin: + self.connection.passwd_s(dn, None, new) + else: + self.connection.passwd_s(dn, old, new) account.new_password_services = {} @@ -234,7 +242,7 @@ class Account: return "" % self.uid - def change_password(self, new_password, service=None): + def change_password(self, new_password, old_password = '', service=None): """ Changes a password for a given service. You have to use the AccountService class to make the changes permanent. If no service is @@ -243,10 +251,13 @@ class Account: if isinstance(new_password, unicode): new_password = new_password.encode('utf8') + if isinstance(old_password, unicode): + old_password = old_password.encode('utf8') + if not service: - self.new_password_root = new_password + self.new_password_root = (old_password, new_password) else: - self.new_password_services[service] = new_password + self.new_password_services[service] = (old_password, new_password) def change_email(self, new_mail): -- cgit v1.2.3-1-g7c22