Edgewall Software
Modify

Opened 15 years ago

Closed 10 years ago

#2310 closed enhancement (worksforme)

[patch] Domain\username problem in windows

Reported by: anonymous Owned by: Jonas Borgström
Priority: normal Milestone:
Component: general Version: 0.9b2
Severity: major Keywords: windows patch login authentication lower upper case ignore verify
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

Here at Bowne Rio, we started to use trac in Windows without the ignore_auth_case setting turned on. We have, then, standardized that the domain should be written in uppercase and the username in lowercase, since that seems to be the way subversion reports the usernames.

Some time after that, I've tried to turn on the trac auto-logon for users inside our intranet. I have expected that the ignore_auth_case setting would help us. Unfortunately, when we tried to turn it on, all the existing issues remained assigned to the 'other-case' usernames.

Aiming to fix that, my first idea was to update the database. But I've found it would be easier to try my first Python attempt.

Here it follows an auth.py patch to give the administrator the ability to force a fixed case for both Windows domain and username.

Since the ignore_auth_case setting didn't feet our needs, I've included the auth_domain_case and auth_username_case settings. Setting both to 'lower' is equivalent to set ignore_auth_case to true.

The two settings are expected under the [trac] section of trac.ini, as seen below:

[trac]
ignore_auth_case = [true|false]
auth_domain_case = [lower|upper]
auth_username_case = [lower|upper]

The patch:

--- .\trac\web\auth.py.orig	2005-09-25 17:06:28.000000000 -0200
+++ .\trac\web\auth.py	2005-11-04 23:54:05.000000000 -0200
@@ -20,12 +20,14 @@
 
 from trac.core import *
 from trac.web.api import IAuthenticator, IRequestHandler
 from trac.web.chrome import INavigationContributor
 from trac.util import escape, hex_entropy, TRUE
 
+LOWER = ['l', 'lo', 'lower']
+UPPER = ['u', 'up', 'upper']
 
 class LoginModule(Component):
     """Implements user authentication based on HTTP authentication provided by
     the web-server, combined with cookies for communicating the login
     information across the whole site.
 
@@ -48,17 +50,13 @@
         elif req.incookie.has_key('trac_auth'):
             authname = self._get_name_for_cookie(req, req.incookie['trac_auth'])
 
         if not authname:
             return None
 
-        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
-        ignore_case = ignore_case.strip().lower() in TRUE
-        if ignore_case:
-            authname = authname.lower()
-        return authname
+        return self._fix_auth_id_case(req, authname)
 
     # INavigationContributor methods
 
     def get_active_navigation_item(self, req):
         return 'login'
 
@@ -82,12 +80,52 @@
         elif req.path_info.startswith('/logout'):
             self._do_logout(req)
         self._redirect_back(req)
 
     # Internal methods
 
+    def _fix_auth_id_case(self, req, auth_id):
+        fixed_id = auth_id
+
+        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
+        ignore_case = ignore_case.strip().lower() in TRUE
+        if ignore_case:
+            fixed_id = fixed_id.lower()
+
+        auth_domain_case = self.env.config.get('trac', 'auth_domain_case')
+        lower_auth_domain_case = auth_domain_case.strip().lower() in LOWER
+        upper_auth_domain_case = auth_domain_case.strip().lower() in UPPER
+        change_domain_case = lower_auth_domain_case or upper_auth_domain_case
+
+        auth_username_case = self.env.config.get('trac', 'auth_username_case')
+        lower_auth_username_case = auth_username_case.strip().lower() in LOWER
+        upper_auth_username_case = auth_username_case.strip().lower() in UPPER
+        change_username_case = lower_auth_username_case or upper_auth_username_case
+
+        change_auth_case = change_domain_case or change_username_case
+        if change_domain_case:
+            expected_pair = fixed_id.split('\\')
+            has_domain_in_id = (len(expected_pair) == 2)
+            if has_domain_in_id:
+                domain_part = expected_pair[0]
+                username_part = expected_pair[1]
+
+                if lower_auth_domain_case:
+                    domain_part = domain_part.lower()
+                if upper_auth_domain_case:
+                    domain_part = domain_part.upper()
+
+                if lower_auth_username_case:
+                    username_part = username_part.lower()
+                if upper_auth_username_case:
+                    username_part = username_part.upper()
+
+                fixed_id = '%s\\%s' % (domain_part, username_part)
+
+        return fixed_id
+
     def _do_login(self, req):
         """Log the remote user in.
 
         This function expects to be called when the remote user name is
         available. The user name is inserted into the `auth_cookie` table and a
         cookie identifying the user on subsequent requests is sent back to the
@@ -98,17 +136,13 @@
         will be converted to lower case before being used. This is to avoid
         problems on installations authenticating against Windows which is not
         case sensitive regarding user names and domain names
         """
         assert req.remote_user, 'Authentication information not available.'
 
-        remote_user = req.remote_user
-        ignore_case = self.env.config.get('trac', 'ignore_auth_case')
-        ignore_case = ignore_case.strip().lower() in TRUE
-        if ignore_case:
-            remote_user = remote_user.lower()
+        remote_user = self._fix_auth_id_case(req, req.remote_user)
 
         assert req.authname in ('anonymous', remote_user), \
                'Already logged in as %s.' % req.authname
 
         cookie = hex_entropy()
         db = self.env.get_db_cnx()

Enrique Pessoa < enrique_dot_pessoa_at_bowne_dot_com >

Attachments (1)

web.auth.py.diff (4.4 KB ) - added by anonymous 15 years ago.
patch for web/auth.py

Download all attachments as: .zip

Change History (8)

by anonymous, 15 years ago

Attachment: web.auth.py.diff added

patch for web/auth.py

comment:1 by sid, 14 years ago

Keywords: patch added
Summary: Domain\username problem in windows - fixed[patch] Domain\username problem in windows

comment:2 by Christian Boos, 14 years ago

Keywords: windows added
Milestone: 0.10.4

#4561 was closed as duplicate.

What about a much simpler solution: if the authname contains a "\" character, then "normalize" it (e.g. everything to lower(), or domain in upper case and username in lower case)?

comment:3 by Christian Boos, 14 years ago

Milestone: 0.10.50.12

in reply to:  2 comment:4 by anonymous, 12 years ago

Replying to cboos:

#4561 was closed as duplicate.

What about a much simpler solution: if the authname contains a "\" character, then "normalize" it (e.g. everything to lower(), or domain in upper case and username in lower case)?

Wondering what's wrong with the patch? Somebody made it work, cannot we integrate it? 3 years and counting……

comment:5 by anonymous, 12 years ago

We had the issue where ActiveDirectory is case-insensitive, while Trac is case sensitive.

Setting "ignore_auth_case = true" is precisely what we want - lower case user names in trac. Subversion's authz file also uses lower case names. That ActiveDirectory lists First.Last (or FIRST.LAST in your case) in its LDAP store is a non-issue, because AD is case-insensitive.

"standardized that the domain should be written in uppercase and the username in lowercase" — that is impossible unless you found a setting in Microsoft ActiveDirectory to force case sensitivity on user names.

If not, your logins are still case-insensitive. You can *create* users in AD following a case convention, but can you force users to enter them in a particular case?

I suggest "notabug" for the resolution. Trac ignore_auth_case works fine as it is.

in reply to:  5 comment:6 by Remy Blank, 10 years ago

Keywords: verify added

Replying to anonymous:

I suggest "notabug" for the resolution. Trac ignore_auth_case works fine as it is.

Can anybody confirm this?

comment:7 by Remy Blank, 10 years ago

Milestone: next-major-0.1X
Resolution: worksforme
Status: newclosed

No reply, assuming comment:5 is accurate.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jonas Borgström.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jonas Borgström to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.