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:


CategoryMoinMoinBug

MoinMoin: MoinMoinBugs/LdapUsernameIssues (last edited 2007年12月02日 13:39:39 by ThomasWaldmann )

AltStyle によって変換されたページ (->オリジナル) /