Description
LDAP is case-insensitive for usernames. MoinMoin is case-sensitive. Moin should get the proper case from LDAP when performing LDAP authentication.
There was some talk about this in #moin a while back:
11:09 < esk> so... LDAP usernames are usually case-insensitive, but moinmoin usernames are case-sensitive. Would it be reasonable to have moin log you in as the username returned by an ldap query instead of the username you entered? 11:09 < esk> (I think PAM handles logins this way) 11:10 < intgr> Yeah, you should always use the canonical username for every user. 11:11 -!- starshine_away is now known as starshine 11:11 < ThomasWaldmann> esk: what's the problem with just entering the name with correct casing? 11:11 < esk> bad users ;) 11:11 < esk> they are used to the case-insensitivity 11:11 < ThomasWaldmann> so you won't have bad users on the wiki 11:11 < ThomasWaldmann> (that could be sold as a feature :) 11:12 < intgr> Well, all the bad users will be impersonating you with ThomasWaLdmann :) 11:12 < intgr> s/with/as/ 11:13 < starshine> actually the flipside of that is you want them to feel like it's easy so they get hooked on wiki and make it grow. 11:14 * ThomasWaldmann looks in ldap_login src 11:14 < esk> it shouldn't take much to fix it... add an ldap_username_attribute to the config and add it to your list of attributes 11:16 < esk> in attrlist 11:16 < ThomasWaldmann> esk: it would be good to make a FeatureRequest for that and provide all details you know 11:16 < esk> okay 11:17 < ThomasWaldmann> the problem is that I don't use ldap myself, so I need rather concrete and clear requests 11:17 < ThomasWaldmann> useful information includes defaults for that lda_username_attribute (like you have it with AD, openldap, samba, whatever) 11:18 < ThomasWaldmann> esk: btw, did you try ldaps: ? 11:18 < esk> yes 11:18 < ThomasWaldmann> did it work "as is"? 11:19 < ThomasWaldmann> (btw, you can also attach a patch, if you already have done it) 11:19 < esk> it works fine if you use ldaps://ldap.server, I was trying with ldap.server and the TLS stuff 11:20 < esk> which was where I went wrong
Component selection
- general
- auth.py
Details
MoinMoin Version |
1.5.8 |
OS and Version |
RHEL 5 |
Python Version |
2.4 |
Server Setup |
apache |
Server Details |
|
Language you are using the wiki in (set in the browser/UserPreferences) |
|
Workaround
I changed the following and added 'ldap_username_attribute=sAMAccountName' in my farmconfig.
--- moin/auth.py.org 2007-08-08 14:24:01.000000000 -0600 +++ /usr/lib/python2.4/site-packages/MoinMoin/auth.py 2007-11-10 02:43:16.000000000 -0700 @@ -132,6 +132,8 @@ login = kw.get('login') logout = kw.get('logout') user_obj = kw.get('user_obj') + if user_obj and user_obj.name: + username = user_obj.name # Needed so ldap_login can change the username #request.log("auth.moin_cookie: name=%s login=%r logout=%r user_obj=%r" % (username, login, logout, user_obj)) if login: u = user.User(request, name=username, password=password, @@ -332,6 +334,8 @@ login = kw.get('login') logout = kw.get('logout') user_obj = kw.get('user_obj') + if user_obj and user_obj.name: + username = user_obj.name cfg = request.cfg verbose = cfg.ldap_verbose @@ -395,15 +399,22 @@ l.simple_bind_s(ldap_binddn.encode(coding), ldap_bindpw.encode(coding)) if verbose: request.log("LDAP: Bound with binddn %s" % ldap_binddn) + possible_attrs=[cfg.ldap_email_attribute, + cfg.ldap_aliasname_attribute, + cfg.ldap_surname_attribute, + cfg.ldap_givenname_attribute, + cfg.ldap_username_attribute, + ] + attrs = [] + for i in possible_attrs: + if i: + attrs.append(i) + # you can use %(username)s here to get the stuff entered in the form: filterstr = cfg.ldap_filter % locals() if verbose: request.log("LDAP: Searching %s" % filterstr) lusers = l.search_st(cfg.ldap_base, cfg.ldap_scope, filterstr.encode(coding), - attrlist=[cfg.ldap_email_attribute, - cfg.ldap_aliasname_attribute, - cfg.ldap_surname_attribute, - cfg.ldap_givenname_attribute, - ], timeout=cfg.ldap_timeout) + attrlist=attrs, timeout=cfg.ldap_timeout) # we remove entries with dn == None to get the real result list: lusers = [(dn, ldap_dict) for dn, ldap_dict in lusers if dn is not None] if verbose: @@ -421,12 +432,32 @@ return None, False # if ldap returns unusable results, we veto the user and don't let him in dn, ldap_dict = lusers[0] + + if cfg.ldap_username_attribute: + old_username = username + username = ldap_dict[cfg.ldap_username_attribute][0] + if old_username != username and verbose: + request.log("Changed username to %s." % (username,)) + if verbose: request.log("LDAP: DN found is %s, trying to bind with pw" % dn) l.simple_bind_s(dn, password.encode(coding)) if verbose: request.log("LDAP: Bound with dn %s (username: %s)" % (dn, username)) - email = ldap_dict.get(cfg.ldap_email_attribute, [''])[0] - email = email.decode(coding) + #u = user.User(request, auth_username=username, password=password, auth_method='ldap', auth_attribs=('name', 'password', 'email', 'mailto_author',)) + user_args = {} + user_args['auth_username'] = username + user_args['auth_method'] = 'ldap' + user_args['name'] = username + # FIXME: can this be left out? + user_args['password'] = password + user_args['auth_attribs'] = ('name','password',) + if cfg.ldap_aliasname_attribute or cfg.ldap_surname_attribute: + user_args['auth_attribs'] = user_args['auth_attribs'] + ('aliasname',) + email = '' + if cfg.ldap_email_attribute: + email = ldap_dict.get(cfg.ldap_email_attribute, [''])[0] + email = email.decode(coding) + user_args['auth_attribs'] = user_args['auth_attribs'] + ('email','mailto_author',) aliasname = '' try: @@ -442,10 +473,11 @@ aliasname = sn aliasname = aliasname.decode(coding) - u = user.User(request, auth_username=username, password=password, auth_method='ldap', auth_attribs=('name', 'password', 'email', 'mailto_author',)) - u.name = username - u.aliasname = aliasname - u.email = email + u = user.User(request, **user_args) + if 'email' in user_args['auth_attribs']: + u.email = email + if 'aliasname' in user_args['auth_attribs']: + u.aliasname = aliasname u.remember_me = 0 # 0 enforces cookie_lifetime config param if verbose: request.log("LDAP: creating userprefs with name %s email %s alias %s" % (username, email, aliasname)) @@ -455,7 +487,9 @@ if u: u.create_or_update(True) - return user_obj, True # == nop, moin_cookie has to set the cookie and return the user obj + if verbose: request.log("LDAP: Success!") + if verbose: request.log("LDAP: name: %s" % (u.name,)) + return u, True # moin_cookie still has to set the cookie and return the user obj, but make our changes stick except: import traceback
Discussion
Does this patch work for new users only or does it also fix the wrong case of already existing user names? -- AnkeHeinrich 2007-11-12 22:52:13
A tested patch based on current 1.6 branch (either latest beta/rc or hg checkout) would be appreciated.
Plan
- Priority:
- Assigned to:
- Status: