#!/usr/bin/env python # allows ldap authentication for ucsc local mirror configurations # this started out as trivial cookie games for local ucsc sessions # ross lazarus me fecit March 15 2007 # TODO: extend to provide public and private sessions # need an authentication scheme # ldap implemented here - YMMV # python login cgi modified from http://webpython.codepoint.net/safer_cgi_shell import os, Cookie, cgi, ldap form = cgi.FieldStorage() # only once! # adjust these to suit your ldap settings AUTH_LDAP_SERVER = 'rockport.bwh.harvard.edu' AUTH_LDAP_BASE_USER = "" # if you need a userid/password to bind AUTH_LDAP_BASE_PASS = "" AUTH_LDAP_BASE = "dc=channing,dc=harvard,dc=edu" AUTH_LDAP_SCOPE = ldap.SCOPE_SUBTREE AUTH_LDAP_FILTER = "(&(objectclass=person) (cn=%s))" # adjust these to suit your hg.conf session settings idCookie = 'MemeUserName' userCookie = 'MemeUserId' debug = 0 # show cookies def getCookies(): ccookies = {} if 'HTTP_COOKIE' in os.environ: hc = os.environ['HTTP_COOKIE'] hcs = hc.split('; ') for c in hcs: cookie = c.split('=') ccookies[cookie[0]] = cookie[1] return ccookies class LDAPBackend: """simple ldap authenticator will fail silently if there are problems with your ldap configuration hard to get a cgi to raise useful errors """ def authenticate(self, username=None, password=None): emessage = '' if username == None: username = '' base = AUTH_LDAP_BASE scope = AUTH_LDAP_SCOPE filter = AUTH_LDAP_FILTER % username if password == '': # don't ever allow empty password strings emessage = 'Empty LDAP passwords are not permitted...' return None,None,emessage # particularly if your ldap server allows anon binds!! try: l = ldap.open(AUTH_LDAP_SERVER) l.simple_bind_s(AUTH_LDAP_BASE_USER,AUTH_LDAP_BASE_PASS) except ldap.LDAPError: emessage = 'Unidentifiable LDAP bind error - bad configuration or LDAP server missing?' return None,None,emessage try: l.search(base, scope, filter) except: return None,None,'Not a known user or bad password (not telling which!)' try: # If the user does not exist in LDAP, Fail. r = l.result()[1] if (len(r) < 1): return None,None # Attempt to bind to the user's DN l.simple_bind_s(r[0][0],password) # since password > '', this will raise INVALID_CREDENTIALS if wrong password uid = r[0][1]['uidNumber'][0] # this will depend on your ldap setup but works for me uname = r[0][1]['uid'][0] return uid,uname,'Login ok' except ldap.INVALID_CREDENTIALS: # Name or password were bad. Fail. return None,None,'Not a known user or bad password (not telling which!)' def header(cookies={}, onload=''): print """\ %s Content-Type: text/html\n \n