« Single Table Inheritance certainly *sounds* evilFind something to be sick in »

How to use "require group" with Trac and SSPI

04/03/06

Permalink 03:56:49 pm, by fumanchu Email , 317 words   English (US)
Categories: Python

How to use "require group" with Trac and SSPI

You may have run into this problem if you've ever tried to use "Require group" and "SSPIOmitDomain" simultaneously with mod_auth_sspi. I encountered it while trying to set up a new Trac site, to which I only wanted to allow access by staff members.

The problem seems to be that, if you set "SSPIOmitDomain On", then no SSPI call is made to check credentials. This could be because the domain is "omitted" before the authentication is done (I cared on Friday night, but I don't now). Regardless, the group requirement seems to fall through the sspi handler, at which point Apache complains that no group file could be found.

Anyway, rather than patch mod_auth_sspi, there's an easy workaround: use a PythonFixupHandler to strip the domain, instead of using SSPIOmitDomain.

from mod_python import apache

def strip_domain(req):
    if req.user:
        if "\\" in req.user:
            req.user = req.user.split("\\", 1)[1]
    return apache.OK
    ##else:
    ##    return apache.DECLINED

def lcase_user(req):
    if req.user:
        req.user = req.user.lower()
    return apache.OK
    ##else:
    ##    return apache.DECLINED

You should be able to use the same trick with "SSPIOfferBasic On". I threw in a lowercase function because I've also had problems with SSPIUsernameCase causing Apache to not start.

You can declare the fixup handler like so (Trac example):

<Location /incidents>
   SetHandler mod_python
   PythonHandler trac.web.modpython_frontend
   PythonOption TracUriRoot "/incidents"
   PythonOption TracEnv "C:/projects/incidents/trac"

   #NT Domain auth config
   AuthType SSPI
   AuthName "Amor Ministries"

   SSPIAuth On
   SSPIAuthoritative On
   SSPIDomain HQAMOR
   PythonFixupHandler fixupsspi::strip_domain fixupsspi::lcase_user

   Require group "HQAMOR\Amor Staff"
</Location>

Hope that helps someone. At the least, it should save you the trouble of porting mod_auth_sspi to a PythonAuthenHandler, as I tried to do first. Since there's limited access to the Apache connection objects in mod_python (e.g., you can't define connection cleanup functions), that's a whole 'nother barrel of fun...

3 comments

Comment from: Graham Dumpleton [Visitor]

Note that mod_python (up to and including 3.2.X) doesn't necessarily treat apache.DECLINED as it really should. Details can be found at:


http://issues.apache.org/jira/browse/MODPYTHON-129



The problem is that in mod_python it will keep running the mod_python handlers only while apache.OK is returned. A mod_python handler returning apache.DECLINED causes it to stop.

This means that were you to have:


PythonFixupHandler fixupsspi::strip_domain fixupsspi::lcase_user otherfixup::function


and either of the first two mod_python fixup handlers were to return apache.DECLINED, the final mod_python fixup handler would never be run when it it should always be run.

Until this issue is fixed, I would perhaps suggest you always have your fixup handlers always return apache.OK. For a fixup handler the result is effectively the same.


def strip_domain(req):
if req.user:
if "\" in req.user:
req.user = req.user.split("\", 1)[1]
return apache.OK

def lcase_user(req):
if req.user:
req.user = req.user.lower()
return apache.OK

04/03/06 @ 17:11
Comment from: fumanchu [Member] Email

How funny! I was returning apache.OK until I read that exact page today. I must have glossed over what the actual problem was and just scanned the "magic macro code", which reminded me to use apache.DECLINED. ;) Thanks for pointing out the error in my reading of the error. :)

04/03/06 @ 20:49
Comment from: JavaJunky [Visitor]

If like me you're using WSGI, this WSGI file should do the same thing as the above python fixup handler does:

import os
import trac.web.main

os.environ['TRAC_ENV'] = 'your_trac.db_here'
os.environ['PYTHON_EGG_CACHE'] = 'your_eggs_here'

def application(environ, start_response):
if "\" in environ['REMOTE_USER']:
environ['REMOTE_USER'] = environ['REMOTE_USER'].split("\", 1)[1]
return trac.web.main.dispatch_request(environ, start_response)

11/13/08 @ 08:23

Leave a comment


Your email address will not be revealed on this site.

Your URL will be displayed.

Please enter the phrase "I am a real human." in the textbox above.
(Line breaks become <br />)
(Name, email & website)
(Allow users to contact you through a message form (your email will not be revealed.)
February 2020
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29

Search

The requested Blog doesn't exist any more!

XML Feeds

powered by b2evolution