dataflake.org

Home Documentation Software Old Stuff

Negative cache key and unicode login attributes (Resolved)

Request LDAP User Folder -- bug report -- by eleddy
Posted on Jan 9, 2009 1:14 am
Subscribe

Enter your email address to receive mail on every change to this issue.

Entries (Latest first)


  Resolve by Jens Vagelpohl on May 27, 2009 9:33 am
  A fix to regenerate the hash key when the admin clears the caches from the ZMI is now checked in:

http://svn.dataflake.org/viewvc?view=revision&revision=1791

http://svn.dataflake.org/viewvc?view=revision&revision=1790

I have not done anything with the unicode cache key issue because I fear what you already noted, a ripple effect throughout the code. I have added a note to the AD RWADME:

http://svn.dataflake.org/viewvc?view=revision&revision=1793

 

  Comment by Elizabeth Leddy on Feb 9, 2009 6:16 pm
  I actually wanted to update this ticket but wasn't sure how - hoping
responding to this email will filter it correctly...

I kept having issues and the shared cache thing was indeed because
multiple sites had the same hash code. This happened because we have
a template acl_users (its such a PIA to set up) and then adjust the
server it points to. So on import of acl_users, the hash code would
be the last saved export, which everyone was sharing (except a few -
making this a hard bug to find). I realize this isn't a comon use
case, so I just customized my instance such that clearing the cache
resets the hash code. Maybe its a harmless 1 line addition that could
save people like me?

wrt the unicode thing, it was starting to ripple everywhere in the
code, having some unicode and some not so I removed the fix in the
product and made my own membership tool that filters it out. I never
called getUserByAttr in my own code, but there are a plethora of ways
that unicode can get in there, including just simply looking up a user
object with a unicode login name. I never intentionally use unicode
because all it seems to give me is headaches and I don't need to worry
about it at this point so I avoid it. Honestly I didn't investigate
too much because as soon as I found the choke point and patched it it
was good enough for me. I do know that I patched getMemberById in the
membership tool to filter out unicode and that stopped the issue at
the source. I also know that active directory stores sAMAccount names
as unicode so it wouldn't hurt to either post a notice in the README
that unicode is not supported.

Thanks!



On Feb 8, 2009, at 12:04 PM, JTracker wrote:

> Issue followup (Comment) by Jens Vagelpohl (jens@dataflake.org):
>
> "Negative cache key and unicode login attributes"
> http://www.dataflake.org/tracker/issue_00629
>
> ----------
>
> About the "shared" cache: For a while now, the different
> LDAPUserFolder instances have had a distinguising hash value that is
> used to keep caches apart. You may find caches being shared if you
> have not followed the recommended upgrade procedure of deleting and
> recreating the LDAPUserFolder instances when you update the software.
>
> How do you get unicode values into the getUserByAttr? I don't think
> that is possible *unless* you call the method directly from your own
> code and feed it unicode values.
>
>
>
> ----------
>
> Sent automatically by JTracker "Report Bugs" at http://www.dataflake.org/tracker

 

  Comment by Jens Vagelpohl on Feb 8, 2009 8:04 pm
  About the "shared" cache: For a while now, the different LDAPUserFolder instances have had a distinguising hash value that is used to keep caches apart. You may find caches being shared if you have not followed the recommended upgrade procedure of deleting and recreating the LDAPUserFolder instances when you update the software.

How do you get unicode values into the getUserByAttr? I don't think that is possible *unless* you call the method directly from your own code and feed it unicode values.

 

  Comment by eleddy on Jan 15, 2009 8:15 am
  confession: we are using active directory so I don't know if this applies everywhere, but it seems to be a benevolent fix that could benefit others

use case: one zope instance with multiple plone sites, all hooked up to active directory for different trees. Users in Site1 should never see content from Site2 and vice versa. User1 logs into Site1 where they should, has permissions as role 'Manager' and all is gravy. User1 can then switch their url to point to Site2 and receive the role of 'Manager' since this role exists in both sites. This happens because the negative cache key is exactly the same for both sites.

This wasn't an issue for me until I patched the unicode negative_cache_key bug, since the login was never cached.

the fix: Ideally I would have liked the cache key to include the portal id, but I don't think that's possible so I added a configurable attribute, similar to a domain. This way login across multiple portals with caching is possible if wanted (sadly I can think of a use case). There is probably a better way to do this but this is whats patched in our live stuff right now and, well, sometimes the investigation ends there.

-----------------
LDAPMultiPlugins/ActiveDirectoryMultiPlugin.py
-----------------
...
_properties = LDAPPluginBase._properties + (
{'id':'groupid_attr', 'type':'string', 'mode':'w'},
{'id':'grouptitle_attr', 'type':'string', 'mode':'w'},
{'id':'group_class', 'type':'string', 'mode':'w'},
{'id':'group_recurse', 'type':'int', 'mode':'w'},
{'id':'group_recurse_depth', 'type':'int', 'mode':'w'},
{'id':'auth_domain', 'type':'int', 'mode':'w'},
)

groupid_attr = 'objectGUID'
grouptitle_attr = 'cn'
group_class = 'group'
group_recurse = 1
group_recurse_depth = 1
auth_domain = 'PloneActiveDirectory'

def __init__(self, id, title='', groupid_attr='objectGUID',
grouptitle_attr='cn', group_class='group', group_recurse=1,
group_recurse_depth=1, auth_domain='PloneActiveDirectory'):
""" Initialize a new instance """
self.id = id
self.title = title
self.groupid_attr = groupid_attr
self.grouptitle_attr = grouptitle_attr
self.group_class = group_class
self.group_recurse = group_recurse
self.group_recurse_depth = group_recurse_depth
self.auth_domain = auth_domain
...
-----------------
LDAPUserFolder/LDAPUserFolder.py/getUserByAttr
-----------------
...
cache_type = pwd and 'authenticated' or 'anonymous'
auth_domain = ''
if self.hasProperty('auth_domain'):
auth_domain = self.auth_domain
negative_cache_key = '%s:%s:%s' % (value.encode('ascii', 'ignore'), auth_domain.encode('ascii', 'ignore'),sha.new(pwd or '').digest())

if cache:
...


 

  Initial Request by eleddy on Jan 9, 2009 1:14 am
  Just upgraded to the latest folder product and noticed that if looking up a user with a unicode login(getUserByAttr) then the negative_cache_key breaks from a (my favorite!) UnicodeDecodeError which then gets swallowed so its not too obvious.

Line 676 in LDAPUserFolder.py
negative_cache_key = '%s:%s' % (value, sha.new(pwd or '').digest())

below is the test case, I think the Cyrillic guy in another bug could have the same thing?
>>> import sha
>>> value = u'grouppract'
>>> pwd = None
>>> negative_cache_key = '%s:%s' % (value, sha.new(pwd or '').digest())
Traceback (most recent call last):
File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xda in position 0: ordinal not in range(128)

I patched my instance with the line below and it seems to work fine so far:
negative_cache_key = '%s:%s' % (value.encode('ascii', 'ignore'), sha.new(pwd or '').digest())