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:
