I've been trying to get Membership 0.7.6 working with LoginManager-0-8-8b1 (and it's associated ZPatterns) under Zope 2.2.2 on RedHat 6.2. After probing around it seems that there is a problem storing member passwords. The following trace from print statements inserted in PersistentUserSource illustrates the problem: ================================================================== using crypt encodePassword( testing , scheme=' CRYPT ', salt= U3 ) ==> {CRYPT}U35nKDwqMBaD2addUser setting password for aral to "{CRYPT}U35nKDwqMBaD2" password = "{CRYPT}R0nzSkU8huehY" setting again with direct assignment password = "{CRYPT}U35nKDwqMBaD2" authenticateUser(self, aral , testing ) comparePassword( testing , {CRYPT}U35nKDwqMBaD2 ) using crypt encodePassword( testing , scheme=' CRYPT ', salt= U3 ) ==> {CRYPT}U35nKDwqMBaD2 comparePassword ==> {CRYPT}U35nKDwqMBaD2 == {CRYPT}U35nKDwqMBaD2 passwords matched ================================================================== Source bits with print statements follows at the end of this article. The problem seems to be that: ...manage_changeProperties(password = new_value) doesn't change the password correctly, but ...password = new_value works. Does anyone know what's really going on here? Modified from PersistentUserSource.py:PersistentUserSource: def authenticateUser(self,user,password,request): name = user.getUserName() ok=0 print 'authenticateUser(self,',name,',',password,')' if self.cacheGetAuth(name, password): return 1 if hasattr(self, 'userAuthenticate'): old_au = setuid(self.REQUEST, _LoggingInUser) try: ok = self.userAuthenticate( self, request, user=user, password=password) if ok: print 'self authenticated' finally: setuid(self.REQUEST, old_au) else: # Why does the following always return '{CRYPT}R0nzSkU8huehY' ??? encpw = user.propertysheets.SystemProperties.password print 'comparePassword(',password,',',encpw,')' ok = self.comparePassword(password, encpw) if ok: print 'passwords matched' if ok: self.cacheSetAuth(name, password) return ok def addUser(self, userid, password, roles, domains): user = self.newItem(userid) user.propertysheets.RestrictedProperties.manage_changeProperties(roles = roles) user.propertysheets.SystemProperties.manage_changeProperties(domains = domains) epass=self.encodePassword(password) # This always sets the password to '{CRYPT}R0nzSkU8huehY' !!! print 'addUser setting password for %s to "%s"' % (userid, epass) user.propertysheets.SystemProperties.manage_changeProperties(password = epass) print ' password = "%s"' % user.propertysheets.SystemProperties.password # This works - what is broken with the manage_changeProperties call? print 'setting again with direct assignment' user.propertysheets.SystemProperties.password = epass print ' password = "%s"' % user.propertysheets.SystemProperties.password return user Modified from LoginManager/UserSources.py:BasicUserSource def encodePassword(self, text, scheme='CRYPT', salt=None): """Encode a password""" if scheme == 'CRYPT' and crypt is not None: print ' using crypt' if salt is None: salt = whrandom.randint(0, 2**12-1) salt = saltdict[salt >> 6] + saltdict[salt & 0x3f] pw = '{CRYPT}' + crypt.crypt(text, salt) elif scheme == 'SHA': pw = '{SHA}' + binascii.b2a_base64(sha.sha(text).digest())[:-1] elif scheme == 'SSHA': if salt is None: # XXX random salt selection could be much better... salt = hex(whrandom.randint(0, sys.maxint-1))[2:] salt = sha.sha(salt).digest() ssha = sha.sha(text + salt).digest()+salt pw = '{SSHA}' + binascii.b2a_base64(ssha)[:-1] else: pw = text print "encodePassword(",text,", scheme='",scheme,"', salt=",salt,") ==> ",pw return pw def comparePassword(self, text, pw): """Check if password matches""" salt = self.extractSalt(pw) if pw[0] == '{': scheme = split(pw[1:], '}', 1)[0] else: scheme = '' text = self.encodePassword(text, scheme, salt) print 'comparePassword ==>',text,'==',pw return (text == pw)