Hello,

thank you, but we have decide us to take LDAP for AD Authentication.

All users in AD Group "UsersFoo" will created as normal users in Baruwa. All 
E-Mail addresses provided in Exchange will created together with the user 
during the first login. Authentication with AD/LDAP Password and SamAccount.

Users in the AD Group "AdminFoo" will created as full admins in Baruwa.

In settings.py we are use this Variables:

AD_DNS_NAME = 'IP or DNS Name of Global Catalog Server'
AD_LDAP_PORT = 3268
AD_SEARCH_DN = 'dc=foo, dc=local'
AD_AUTH_DOMAIN = 'FOO'
AD_ADMIN_GROUP = 'AdminFoo'
AD_USER_GROUP = 'UsersFoo'
AD_SEARCH_FIELDS = ['mail','givenName','sn','SAMAccountName','memberOf','dn']
AD_LDAP_URL = 'ldap://%s:%s' % (AD_DNS_NAME,AD_LDAP_PORT)

And add the backend module to

AUTHENTICATION_BACKENDS = (
    'baruwa.auth.backend_name.ActiveDirectoryBackend',

And the content of the backend_name script in /auth:

---
import ldap
import logging
from django.contrib.auth.models import User
from baruwa.accounts.models import UserAddresses
from django.contrib.auth.backends import ModelBackend
from django.conf import settings

logger = logging.getLogger()
fh=logging.FileHandler('/etc/httpd/logs/baruwa-ldap.log')
fh.setLevel(logging.DEBUG)
logger.addHandler(fh)

# general function - belongs to utils
def get_exc_str(bClear=False):
   import sys, traceback
   x=sys.exc_info()
   if not x[0]:
      return "No py exception"
   out="%s/%s/%s" % (str(x[0]), str(traceback.extract_tb(x[2])), str(x[1]))
   if bClear:
      sys.exc_clear()
   return out

class ADUser(object):

    # class level, makes "operational error" problem by search occurs less
    ldap_connection = None
    AD_SEARCH_FIELDS = 
['mail','givenName','sn','sAMAccountName','dn','memberOf','proxyAddresses']

    @classmethod
    def get_ldap_url(cls):
        return 'ldap://%s:%s' % (settings.AD_DNS_NAME, settings.AD_LDAP_PORT)

    def __init__(self, username):
        self.username = username
        self.uname=username

        try:
            self.domain = self.username.split('\\')[0]
            self.uname=self.username.split('\\')[1]
            self.username = self.username.split('\\')[1]

            self.user_bind_name = "%s@%s" % (self.username, self.domain)
        except IndexError:
            self.domain=settings.AD_AUTH_DOMAIN
            self.user_bind_name = "%s@%s" % (self.username, self.domain)

        self.is_bound = False
        self.has_data = False

        self.first_name = None
        self.last_name = None
        self.email = None
        self.admin = False
        self.email_addresses = []

    def connect(self, password):
        self.password = password
        had_connection = ADUser.ldap_connection is not None
        ret = self._connect(password)
        # WORKAROUND: for invalid connection
        if not ret and had_connection and ADUser.ldap_connection is None:
            logger.warning("AD reset connection - invalid connection, try again 
with new connection")
            ret = self._connect(password)
        return ret

    def _connect(self, password):
        if not password:
            return False # Disallowing null or blank string as password
        try:
            if ADUser.ldap_connection is None:
                logger.info("AD auth backend ldap connecting")
                ADUser.ldap_connection = ldap.initialize(self.get_ldap_url())
                assert self.ldap_connection==ADUser.ldap_connection # python 
won't do that ;)
            self.ldap_connection.simple_bind_s(self.user_bind_name,password)
            self.is_bound = True
        except Exception, e:
            if str(e.message).find("connection invalid")>=0:
                logger.warning("AD reset connection - it looks like invalid: %s 
(%s)" % (str(e),  get_exc_str()))
                ADUser.ldap_connection = None
            else:
                logger.error("AD auth backend ldap - probably bad credentials: 
%s (%s)" % (str(e),  get_exc_str()))
            return False
        return True

    def disconnect(self):
        if self.is_bound:
            logger.info("AD auth backend ldap unbind")
            self.ldap_connection.unbind_s()
            self.is_bound=False

    def check_group(self,obj,group):

        found = False
#       logger.error("Reading Group %s - %s.\n",obj,group)

        try:
            assert self.ldap_connection
            res2 = self.ldap_connection.search_ext_s(obj,
                                 ldap.SCOPE_BASE,
                                 "(objectClass=*)",
                                 self.AD_SEARCH_FIELDS)
            if not res2:
                return False
            assert len(res2)>=1, "Result should contain at least one element: 
%s\n" % res
            result = res2[0][1]
            if result.has_key('sAMAccountName'):
                if result['sAMAccountName'][0] == group:
                    return True
            for group2 in result['memberOf']:
                if self.check_group (group2,group):
                    return True
        except Exception, e:
            logger.debug("AD auth backend error by fetching ldap data: %s 
(%s)\n" % (str(e),  get_exc_str()))

        return found

    def get_data(self):
        try:

#            assert self.ldap_connection
            res = self.ldap_connection.search_ext_s(settings.AD_SEARCH_DN,
                                 ldap.SCOPE_SUBTREE,
                                 "sAMAccountName=%s" % self.uname,
                                 self.AD_SEARCH_FIELDS)

#            self.disconnect()
            if not res:
                logger.error("b) AD auth ldap backend error by searching %s. No 
result.\n" % settings.AD_SEARCH_DN)
                return False
            assert len(res)>=1, "c) Result should contain at least one element: 
%s\n" % res
            result = res[0][1]
        except Exception, e:
#            self.disconnect()
            logger.error("a) Auth failed for (%s)\n" % self.uname )
            logger.error("a) AD auth backend error by fetching ldap data: %s 
(%s)\n" % (str(e),  get_exc_str()))
            return False

        try:

            self.first_name = None
            if result.has_key('givenName'):
                self.first_name = result['givenName'][0]

            self.last_name = None
            if result.has_key('sn'):
                self.last_name = result['sn'][0]

            self.email = None
            if result.has_key('mail'):
                self.email = result['mail'][0]

            if result.has_key('proxyAddresses'):
                for mail1 in result['proxyAddresses']:
                    if mail1.split(':')[0].upper() == "SMTP":
                        self.email_addresses.append(mail1.split(':')[1])
                        logger.error("Adding Address: %s\n",mail1)

            dn=res[0][0]
            if self.check_group(dn,settings.AD_ADMIN_GROUP):
                self.admin=True
            elif self.check_group(dn,settings.AD_USER_GROUP):
                self.admin=False
            else:
                logger.error("User %s not in group",username)
                return False
#           self.disconnect()
            self.has_data = True
        except Exception, e:
#            self.disconnect()
            logger.error("AD auth backend error by reading fetched data: %s 
(%s)\n" % (str(e),  get_exc_str()))
            return False

        return True

    def __del__(self):
        try:
            self.disconnect()

        except Exception, e:
            logger.error("AD auth backend error when disconnecting: %s (%s)\n" 
% (str(e),  get_exc_str()))
            return False

    def __str__(self):
        return "AdUser(<%s>, connected=%s, is_bound=%s, has_data=%s)\n" % 
(self.username, self.ldap_connection is not None, self.is_bound,
self.has_data)

class ActiveDirectoryBackend(ModelBackend):

    def authenticate(self,username=None,password=None):
        aduser = ADUser(username)

        if not aduser.connect(password):
            return None

        user = None
        try:
            user = User.objects.get(username="%s\\%s" % 
(aduser.domain,aduser.username))
        except User.DoesNotExist:
            logger.warning("User missing %s.\n" % username)
            user = User(username= "%s\\%s"%(aduser.domain,aduser.username), 
is_staff = False, is_superuser = False)

        if not aduser.get_data():
            logger.warning("AD auth backend failed when reading data for %s. No 
Group information available.\n" % username)
            user = None
            return None
        else:

            # NOTE: update user data exchange to User model
#            user.username==aduser.username
#           user.username="%s\\%s"%(aduser.domain,aduser.username)
            user.first_name=aduser.first_name
            user.last_name=aduser.last_name
            user.email=aduser.email
            user.is_superuser=aduser.admin
            xxuserid=user.id
            user.save()
            if not user.is_superuser:
                    for mail1 in aduser.email_addresses:
                        try:
                            userAddr = 
UserAddresses.objects.get(user=user,address=mail1)
                        except UserAddresses.DoesNotExist:
                            userAddr = UserAddresses(user=user, address=mail1)
                            userAddr.save()

            #user.set_password(password)

        logger.info("AD auth backend check passed for %s" % username)
        return user
--------------

Many thanks for your help.

Theo


-----Ursprüngliche Nachricht-----
Von: [email protected] [mailto:[email protected]] 
Im Auftrag von Andrew Colin Kissa
Gesendet: Donnerstag, 30. August 2012 21:04
An: Baruwa users list
Betreff: Re: [Baruwa] Add Domains to Domain Admins


On 30 Aug 2012, at 1:34 PM, Schroeder, Theo wrote:

> I add the Radius server to settings.py with:
> # Radius auth settings
> RADIUS_SECRET = {}
> #RADIUS_SECRET['127.0.0.1'] = 'secret'
> RADIUS_SECRET['10.10.10.1'] = 'test'
>
> Remove the # for    'baruwa.auth.radius.RadiusAuth',
>
> And add for my domain test.com in Baruwa the settings:
>
> Address: 10.10.10.1
> Protocol: Radius
> Port 1645
> Enabled Yes
> Split address No
>
> Because between the Baruwa Server and the Radius Server is a firewall,
> I can see that I have absolutely no request to the Radius Server, if I
> try to login with a user [email protected]
>
> For my understanding, the Baruwa Server should do a request for the user 
> [email protected] to the radius server now. But nothing happens.

It should make the request to the radius server, run a dump on the Baruwa 
server to see if the request out is made.

--
www.baruwa.org




_______________________________________________
Keep Baruwa FREE - http://pledgie.com/campaigns/12056

--
This message has been scanned for viruses and dangerous content by MailScanner, 
and is believed to be clean.


SCHMOLZ + BICKENBACH Edelstahl GmbH
Sitz der Gesellschaft Duesseldorf
HRB 50712 Amtsgericht Duesseldorf
Geschaeftsfuehrer:
Dr. Marcel Imhof
Dipl-Kfm. Oliver Karst

Der Austausch von Nachrichten mit SCHMOLZ + BICKENBACH Edelstahl GmbH via 
E-Mail dient ausschliesslich Informationszwecken. Rechtsgeschaeftliche 
Erklaerungen duerfen ueber dieses Medium nicht ausgetauscht werden. 
Verfaelschungen des urspruenglichen Inhaltes dieser Nachricht bei der 
Datenuebertragung koennen nicht ausgeschlossen werden.

Correspondence with SCHMOLZ + BICKENBACH Edelstahl GmbH via e-mail is only for 
information purposes. This medium is not to be used for the exchange of 
legally-binding communications. The falsification of the original content of 
this message in the course of data transmission cannot be excluded.

_______________________________________________
Keep Baruwa FREE - http://pledgie.com/campaigns/12056

Reply via email to