Exemple #1
0
    def __init__(self, server, port, tls, no_verify, binddn, bindpw, anonymous):
        """
        Bind to an LDAP directory using passed credentials.
        """
        self.server = server
        self.port = port
        self.tls = tls
        self.binddn = binddn
        self.bindpw = bindpw
        schema = "ldap"
        if not HAS_LDAP:
            raise CommandExecutionError("Failed to connect to LDAP, module " "not loaded")
        try:
            if no_verify:
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
            if self.tls:
                schema = "ldaps"
            self.ldap = ldap.initialize("{0}://{1}:{2}".format(schema, self.server, self.port))
            self.ldap.protocol_version = 3  # ldap.VERSION3
            self.ldap.set_option(ldap.OPT_REFERRALS, 0)  # Needed for AD

            if not anonymous:
                self.ldap.simple_bind_s(self.binddn, self.bindpw)
        except Exception as ldap_error:
            raise CommandExecutionError(
                "Failed to bind to LDAP server {0}:{1} as {2}: {3}".format(
                    self.server, self.port, self.binddn, ldap_error
                )
            )
    def authenticate(self, username, password, options):
        """
        See abstract method documentation.
        """
        log.debug("Username: %s" % username)
        log.debug("Options: %s" % options)

        failure_mode = False  # reject but continue
        if options.get('continue-on-failure', 'False') == 'False':
            failure_mode = None  # reject and do not continue

        try:
            import ldap
        except:
            log.debug("User: %s, ACTIVEDIRECTORY: False (no ldap)" % (username))
            return (failure_mode, '')

        # do AD search (if required)
        vars = {'username': username, 'password': password}
        if 'search-fields' in options:
            try:
                # setup connection
                ldap.set_option(ldap.OPT_REFERRALS, 0)
                l = ldap.initialize(_get_subs(options, 'server', vars))
                l.protocol_version = 3
                l.simple_bind_s(_get_subs(options, 'search-user', vars), _get_subs(options, 'search-password', vars))
                scope = ldap.SCOPE_SUBTREE

                # setup search
                attributes = map(lambda s: s.strip().format(**vars), options['search-fields'].split(','))
                result = l.search(_get_subs(options, 'search-base', vars), scope, _get_subs(options, 'search-filter', vars), attributes)

                # parse results
                _, suser = l.result(result, 60)
                _, attrs = suser[0]
                log.debug(("AD Search attributes: %s" % attrs))
                if hasattr(attrs, 'has_key'):
                    for attr in attributes:
                        if attr in attrs:
                            vars[attr] = str(attrs[attr][0])
                        else:
                            vars[attr] = ""
            except Exception:
                log.exception('ACTIVEDIRECTORY Search Exception for User: %s' % username)
                return (failure_mode, '')
        # end search

        # bind as user to check their credentials
        try:
            # setup connection
            ldap.set_option(ldap.OPT_REFERRALS, 0)
            l = ldap.initialize(_get_subs(options, 'server', vars))
            l.protocol_version = 3
            l.simple_bind_s(_get_subs(options, 'bind-user', vars), _get_subs(options, 'bind-password', vars))
        except Exception:
            log.exception('ACTIVEDIRECTORY Authenticate Exception for User %s' % username)
            return (failure_mode, '')

        log.debug("User: %s, ACTIVEDIRECTORY: True" % (username))
        return (True, _get_subs(options, 'auto-register-username', vars))
Exemple #3
0
  def _ldget(self, url):
    """Get data from LDAP."""
    result = []

    ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self._cacertdir)
    l = ldap.initialize(url)
    l.protocol_version = ldap.VERSION3

    # Fetch paged results from ldap server.
    # This is needed because there is a size limit on the CERN ldap server
    # side to return at most 1000 entries per request.
    # For more information, see http://tools.ietf.org/html/rfc2696.html
    srv_ctrls = [ldap.controls.SimplePagedResultsControl(criticality=False, cookie="")]
    while True:
      srv_ctrls[0].size = 1000 # dont necessarily need to match the server limit
      s = l.search_ext('OU=Users,OU=Organic Units,DC=cern,DC=ch',
                       ldap.SCOPE_SUBTREE,
                       '(memberOf:1.2.840.113556.1.4.1941:=CN=cms-authorized-users,OU=e-groups,OU=Workgroups,DC=cern,DC=ch)',
                       ['sAMAccountName','displayName','employeeID','mail','altSecurityIdentities','userAccountControl'],
                       serverctrls=srv_ctrls,
                       sizelimit=0)
      _, res_data, _, srv_ctrls = l.result3(s, timeout=100)
      result.extend(res_data)
      if not srv_ctrls[0].cookie: break

    if not result:
      raise RuntimeError("Ldap returned no data for %s" % url)
    return result
Exemple #4
0
    def __init__(self, uri, base, login, password, certfile=None, timelimit=30):
        """
        Create a new LdapConnection.

        This already connects to the LDAP server. There is no lazy loading.
        """

        ## native python-ldap connection instance
        self._lo = None
        ## URI indicating the LDAP instance we should connect to
        self._uri = uri
        ## The Base of the LDAP we are working in
        self._base = base
        ## The dn we are authenticating with
        self._login = login
        ## The password for the login dn
        self._password = password
        ## If using SSL/TLS this is certificate of the server
        self._certfile = certfile
        # After storing all information, we connect to the server
        self._connect()
        ## Defines how long we will wait for result answers from the LDAP server
        self._timeout = 0
        ## Set timelimit, python-ldap defaults to 30
        ldap.set_option(ldap.OPT_TIMELIMIT, timelimit)
Exemple #5
0
    def ldap_search(self, searchFilter, baseDN):
        searchScope = ldap.SCOPE_SUBTREE
        retrieveAttributes = None

        try:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
            l = ldap.initialize(LDAP_URI)
            l.set_option(ldap.OPT_REFERRALS, 0)
            l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
            l.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
            l.set_option( ldap.OPT_X_TLS_DEMAND, True )
            l.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
            l.protocol_version = ldap.VERSION3

            l.simple_bind_s(LDAP_USERNAME, LDAP_PASSWORD)
            ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
            result_set = []
            while 1:
                result_type, result_data = l.result(ldap_result_id, 0)
                if (result_data == []):
                    break
                else:
                    if result_type == ldap.RES_SEARCH_ENTRY:
                        result_set.append(result_data)
            return result_set

        except ldap.LDAPError, e:
            logging.error(e)
            raise
Exemple #6
0
 def __init__(self, seid, sname, stype, surl, sconfig, login, password,
              verbose=0):
     """ Create a LDAPConnection instance.
     """
     self.config = self.configure(seid, sname, stype, surl, sconfig, login,
                                  password)
     self.verbose = verbose
     self.is_active_directory = (
         self.config["user-login-attr"] == "sAMAccountName")
     if verbose > 0:
         pprint(self.config)
     if self.is_active_directory:
         ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, 0)
     self.ldapobject = ldap.initialize(self.config["url"])
     self.ldapobject.protocol_version = 3
     if self.is_active_directory:
         self.ldapobject.set_option(ldap.OPT_REFERRALS, 0)
     self.ldapobject.simple_bind_s(self.config["data-cnx-dn"],
                                   self.config["data-cnx-password"])
     self.user_base_filters = [
         filter_format("(%s=%s)", ("objectClass", o))
         for o in self.config["user-classes"]]
     self.group_base_filters = [
         filter_format("(%s=%s)", ("objectClass", o))
         for o in self.config["group-classes"]]
     if verbose > 0:
         pprint(self.user_base_filters)
         pprint(self.group_base_filters)
    def __init__(self, *args, **kwargs):
        self.priv_required = kwargs.get("priv_required", False)
        self.server = kwargs["server"]
        self.base_dn = kwargs["base_dn"]
        self.bind_dn = kwargs.get("bind_dn", "")
        self.bind_pw = kwargs.get("bind_pw", "")
        self.userfilter = kwargs.get("userfilter", "uid=%s")
        self.groupfilter = kwargs.get("groupfilter", "cn=%s")

        self.people_rdn = kwargs.get("people_rdn", "ou=people")
        self.group_rdn = kwargs.get("group_rdn", "ou=groups")
        self.people_dn = "%s,%s" % (self.people_rdn, self.base_dn)
        self.group_dn = "%s,%s" % (self.group_rdn, self.base_dn)

        logger.info("Trying to connect to %s" % self.server)
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
        self.conn = ldap.initialize(self.server)
        # debug version
        # self.conn = ldap.initialize(self.server,trace_level=2)

        if not self.conn:
            logger.error("Could not initialize connection to %s" % self.server)
            return

        if self.priv_required:
            self.bind_priv()
Exemple #8
0
    def _search(cls, users, attr_idx):
        """Search LDAP directory for the indexed attr for users.

        Attr index can be UID_IDX, CN_IDX or MAIL_IDX.

        Return a list containing the results.

        """
        conf = ResourceLocator.default().get_conf()
        uri = conf.get_value(["rosa-ldap", "uri"])
        binddn = conf.get_value(["rosa-ldap", "binddn"])
        passwd = ""
        passwd_file = conf.get_value(["rosa-ldap", "password-file"],
                                     cls.PASSWD_FILE)
        if passwd_file:
            passwd = open(os.path.expanduser(passwd_file)).read().strip()
        basedn = conf.get_value(["rosa-ldap", "basedn"], "")
        filter_str = "(|(uid=" + ")(uid=".join(users) + "))"
        filter_more_str = conf.get_value(["rosa-ldap", "filter-more"], "")
        if filter_more_str:
            filter_str = "(&" + filter_str + filter_more_str + ")"
        user_attr_str = conf.get_value(["rosa-ldap", "attrs"], cls.USER_ATTRS)
        attr = user_attr_str.split()[attr_idx]

        tls_ca_file = conf.get_value(["rosa-ldap", "tls-ca-file"])
        if tls_ca_file:
            ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, tls_ca_file)
        conn = ldap.initialize(uri)
        conn.bind_s(binddn, passwd)
        results = conn.search_s(basedn, ldap.SCOPE_SUBTREE, filter_str, [attr])
        conn.unbind()
        return [result[1][attr][0] for result in results]
def query_user(UID,env):
        DN="%s,%s"%(env.PEOPLE,env.BASEDN)
        FILTER="(&(objectClass=posixAccount)(uid=%s))"%(UID)
        ATTR=[  "sn",
                "loginShell", 
                "employeeType",
                "employeeNumber",
                "uidnumber",
                "gidnumber",
                "uid",
                "gecos",
                "cn",
                "homeDirectory",
                "objectClass",
		"userPassword"
             ]
	options = [(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)]
	ldap.set_option(*options[0])
	connection = ldap.initialize(env.LDAPSERVER)
        connection.simple_bind_s()
        try:result = connection.search_s(DN, ldap.SCOPE_SUBTREE, FILTER, ATTR)
        except ldap.LDAPError, e:result = [("Generic error occured (are you logged in?)",{"": ""})]
        if result == []:result = [("No such user!",{"": ""})]
        connection.unbind()
        return result
def helper_next_free(TYPE, env):
	error = "OK"
	toprange = highest = 0
        DN="%s,%s"%(env.PEOPLE,env.BASEDN)
	FILTER="(uid=*)"
	ATTR=["uidNumber"]
	try:
		ranges = env.user_ranges()
		begin = ranges[TYPE][1]
		end= ranges[TYPE][2]
	except:begin=end=100
	try:
		options = [(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)]
		ldap.set_option(*options[0])
		connection = ldap.initialize(env.LDAPSERVER)
        	connection.simple_bind_s()
 		result = connection.search_s(DN, ldap.SCOPE_SUBTREE, FILTER, ATTR)
	except ldap.LDAPError, error: return "Generic error occured (are you logged in?)", toprange 
	connection.unbind()
	for dn,entry in result:
		current=entry[ATTR[0]][0]
		# get highest of all
		if (int(highest) < int(current)):highest=current
		# get highest in range
		if (int(current) < int(begin)):continue
		elif (int(current) > int(end)):continue
		elif (int(current) >= int(toprange)):toprange=current
	if (int(toprange) == int(end)):toprange=int(highest) + 1
	elif (int(toprange) == 0):toprange=int(highest) + 1
	else: toprange = int(toprange) + 1
	return error, toprange
Exemple #11
0
    def authenticate(self, username=None, password=None, **kwargs):
        if len(password) == 0:
            return None

        user = None
        try:
            #ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, 'cacert.pem')
            # HEFTODO re enable strict checking
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
            l = ldap.initialize(settings.AD_URL)
            l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
            binddn = "{0}@{1}".format(username, settings.AD_DOMAIN)
            l.simple_bind_s(binddn, password)
            # would throw if bind fails

            #get user info
            filter_string ='(sAMAccountName={0})'.format(username)
            ldap_user = l.search_ext_s(settings.AD_BASEDN ,ldap.SCOPE_ONELEVEL, filterstr=filter_string)[0][1]
            search_guid = ''.join('\\%02x' % ord(x) for x in ldap_user['objectGUID'][0])
            try:
                user = models.PS1User.objects.get(object_guid=search_guid)
                user.ldap_user = ldap_user
            except models.PS1User.DoesNotExist:
                django_user = models.PS1User(object_guid=search_guid)
                django_user.ldap_user = ldap_user
                django_user.save()
                user = django_user
            l.unbind_s()
        except ldap.INVALID_CREDENTIALS:
            pass
        return user
Exemple #12
0
	def __connect( self ):
		'''
		Connect to the URI in __init__, etc.
		'''
		
		# If trace_level is set to 1, passwords and other info will be output to stdout ...
		# don't do this unless you REALLY want to...which, if you do, I'd like to talk to you sometime
		self.__conn = LockingWrapper( obj = ldap.initialize( self.__uri, trace_level=0 ) )
		
		ldap.set_option( ldap.OPT_DEBUG_LEVEL, self.__debuglevel )
		#ldap.set_option( ldap.OPT_NETWORK_TIMEOUT, self.__timeout)
		self.__conn.set_option( ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3 )
		self.__conn.set_option( ldap.OPT_REFERRALS, 0 )
		self.__conn.set_option( ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND )

		# Die!!
		#self.__conn.timelimit = self.__timeout
		#self.__conn.timeout = self.__timeout
		#self.__conn.network_timeout = self.__timeout

		#if auth.ldap_tls_cacertfile:
		#	self.__conn.set_option( ldap.OPT_X_TLS_CACERTFILE, local_config['ldap_tls_cacertfile'])
		#if auth.ldap_tls_cacertdir:
		#	self.__conn.set_option( ldap.OPT_X_TLS_CACERTDIR, local_config['ldap_tls_cacertdir'])
		#self.__conn.set_option( ldap.OPT_X_SASL_SECPROPS, 'maxssf=0' )
		# FIXME: this should probably be in a try/except
		#self.__conn.bind_s( self.__binddn, self.__bindpw,
		#		self.__bind_type )
		self.__conn.simple_bind_s( self.__binddn, self.__bindpw )
Exemple #13
0
    def _cursor(self):
        if self.connection is None:
            try:
                logger.debug('Connecting to LDAP at %s with account %s' %(self.settings_dict['NAME'], self.settings_dict['USER']))
                
                if self.settings_dict['CACERT']:
                    logger.debug('Using CACERT: %s' % self.settings_dict['CACERT'])
                    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.settings_dict['CACERT'])

                self.connection = ldap.initialize(self.settings_dict['NAME'])

                if self.settings_dict['STARTTLS']:
                    logger.debug('Using STARTTLS')
                    self.connection.start_tls_s()

                self.connection.simple_bind_s(
                    self.settings_dict['USER'],
                    self.settings_dict['PASSWORD'])

            except ldap.SERVER_DOWN:
                logger.error('LDAP server is down')
                raise ServerDown

            except ldap.INVALID_CREDENTIALS:
                logger.error('Invalid credentials')
                raise InvalidCredentials
        
        return DatabaseCursor(self.connection)
Exemple #14
0
 def initialize(self):
     ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
     # XXX this creates option errors, no idea why. keep it around
     # if needed, seems to work fine without it
     #ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.certfile)
     self.ldo = ldap.initialize(self.host)
     self.ldo.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
def ldap_process(request):
    """Initiate a ldap login"""
    config = request.registry.settings
    urls = splitlines(config['velruse.providers.ldapprovider.urls'])
    bdn = config['velruse.providers.ldapprovider.basedn']
    verified_login = False
    username = request.POST.get('ldap_username', request.POST.get('username', ''))
    password = request.POST.get('ldap_password', request.POST.get('password', ''))
    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
    dn = bdn.replace('%LOGIN%', username)
    data = {}
    if urls:
        for url in urls:
            try:
                # We have suceed to connect, break the loop
                con = ldap.initialize(url)
                bind = con.simple_bind_s(dn, password)
                verified_login = True
                items = con.search_s(dn,ldap.SCOPE_SUBTREE)
                if items:
                    for item in items:
                        if item[0] == dn:
                            data = item[1]
                            break
            except Exception, e:
                pass
Exemple #16
0
    def conn(self):
        if not self.check_certificate:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

        conn = ldap.initialize(self.conn_string)
        if self.starttls:
            try:
                conn.start_tls_s()
            except ldap.LDAPError as e:
                logger.error("can't STARTTLS")
                if type(e.message) == dict and e.message.has_key("desc"):
                    logger.error(e.message['desc'])
                else:
                    logger.error(e)
                conn.unbind()
                return None
        try:
            conn.simple_bind_s(self.bind_dn, self.bind_pw)
        except ldap.INVALID_CREDENTIALS:
            logger.info("invalid credentials for bind dn: " + self.bind_dn)
            conn.unbind()
            return None
        except ldap.LDAPError as e:
            logger.error("LDAP error when binding")
            if type(e.message) == dict and e.message.has_key('desc'):
                logger.error(e.message['desc'])
            else:
                logger.error(e)
            conn.unbind()
            return None
        return conn
Exemple #17
0
    def configure_user(self, user):
        """
        Configures a user after creation and returns the updated user.

        By default, returns the user unmodified.
        """
        try:
            ldap.set_option(ldap.OPT_REFERRALS, 0)  # DO NOT TURN THIS OFF OR SEARCH WON'T WORK!

            # initialize
            l = ldap.initialize(settings.AD_LDAP_URL)

            # bind
            binddn = "%s@%s" % (settings.AD_LDAP_USER, settings.AD_NT4_DOMAIN)
            l.bind_s(binddn, settings.AD_LDAP_PW)

            # search
            result = l.search_ext_s(settings.AD_SEARCH_DN, ldap.SCOPE_SUBTREE, "%s=%s" % (settings.AD_LU_ACCOUNT_NAME, user), settings.AD_SEARCH_FIELDS)[0][1]
            l.unbind_s()

            # get personal info
            user.email = result.get(settings.AD_LU_MAIL, [None])[0]
            user.last_name = result.get(settings.AD_LU_SURNAME, [None])[0]
            user.first_name = result.get(settings.AD_LU_GIVEN_NAME, [None])[0]

        except Exception:
            return None

        user.is_staff = False
        user.is_superuser = False
        user.set_password(None)

        user.save()
        return user
Exemple #18
0
    def _ldap_connect(self):

        if self.disable_verify_cert:
            log.info("Disabling certificate verification")
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

        log.debug("Initializing ldap connection: %s" % (self.ldap_url))
        self.ldap = ldap.ldapobject.ReconnectLDAPObject(self.ldap_url,
                                                        retry_max=5, retry_delay=30)

        self.ldap.set_option(ldap.OPT_REFERRALS, 0)
        log.debug("LDAP Current OPT_REFERRALS: %s" % (self.ldap.get_option(ldap.OPT_REFERRALS)))

        self.ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 5)
        log.debug("LDAP Current OPT_NETWORK_TIMEOUT: %s" % (
            self.ldap.get_option(ldap.OPT_NETWORK_TIMEOUT)))

        try:
            log.debug("Attempting to authenticate: %s via %s" % (self.ldap_url, self.username))
            self.ldap.simple_bind_s("%s" % (self.username), "%s" % (self.password))
            log.debug("Authenticated Successfully")
        except ldap.SERVER_DOWN:
            log.debug("Can't connect to server: %s" % (self.ldap_url))
            log.debug("This can also happen if the server's certificate is invalid")
            exit(1)
        except ldap.INVALID_CREDENTIALS:
            log.debug("I don't have access to this DC: %s" % (self.ldap_url))
            exit(1)
        except ldap.LDAPError, e:
            log.debug("Unknown Error: %s", e)
            exit(1)
Exemple #19
0
def search(canonical_name):
    """
    Searches the LDAP server for all Organizational Units (OUs) whose Canonical
    Name (CN) contains the text argument canonical_name passed into the
    function.
    """
    ldap.set_option(ldap.OPT_REFERRALS, 0)
    l = ldap.initialize(settings.LDAP_URL)
    l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
    binddn = ''
    try:
        binddn = "%s@%s" % (settings.BIND_USER, settings.NT4_DOMAIN)
    except AttributeError:
        binddn = settings.BIND_USER
    l.simple_bind_s(binddn, settings.BIND_PASSWORD)
    base = settings.SEARCH_DN
    scope = ldap.SCOPE_SUBTREE
    retrieve_attributes = ['cn']

    filtered_name = ldap.filter.escape_filter_chars(canonical_name)
    filter = 'cn=*%s*' % filtered_name

    results = l.search_s(base, scope, filter, retrieve_attributes)

    #result_objects = [LDAPSearchResult(result) for result in results]
    result_objects = []
    for result in results:
        if result[0]:
            result_objects.append(LDAPSearchResult(result))
    return result_objects
Exemple #20
0
  def __init__(self, **kwargs):
    prop_defaults = {
        "uri": None,
        "user": None,
        "password": None,
        "user_base": None,
        "group_base": None,
        "servers_base": None,
        "ca_certfile": "/etc/ssl/certs/ca-certificates.crt",
        "default_shell": "/bin/bash",
        "min_uid": 3000,
        "max_uid": 1000000,
        "excluded_uids": [65534]
    }

    for (prop, default) in prop_defaults.iteritems():
        setattr(self, prop, kwargs.get(prop, default))

    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,self.ca_certfile)
    self.con = ldap.initialize(self.uri)
    self.con = ldap.ldapobject.ReconnectLDAPObject(
        self.uri,
        retry_max=10,
        retry_delay=5
    )
    self.con.set_option(ldap.OPT_X_TLS_DEMAND, True)
    self.con.start_tls_s()
    self.con.simple_bind_s(self.user, self.password)
Exemple #21
0
def enter_ldap():
    global ldap_instance
    if ldap_instance is None:
        try:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
            ldap_instance = ldap.initialize('ldap://%s' % CONF_MAP['UADM_LDAP_DC'])
            ldap_instance.set_option(ldap.OPT_REFERRALS, 0)
            ldap_instance.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
            ldap_instance.set_option(ldap.OPT_X_TLS,ldap.OPT_X_TLS_DEMAND)
            ldap_instance.set_option( ldap.OPT_X_TLS_DEMAND, True )
            ldap_instance.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
            ldap_instance.start_tls_s()
            user = DOMAIN_USER if DOMAIN_USER else ''
            password = DOMAIN_PASS if DOMAIN_PASS else ''
            if DOMAIN_USER:
                auth_tokens = ldap.sasl.digest_md5(user, password)
                ldap_instance.sasl_interactive_bind_s( "", auth_tokens )
            else:
                #try with anonymous login
                ldap_instance.simple_bind_s()

        except ldap.LDAPError, e:
            ldap_instance.unbind()
            ldap_instance = None
            raise
Exemple #22
0
  def add_ldap_config(self, ldap_config):
    ldap_url = ldap_config.LDAP_URL.get()
    if ldap_url is None:
      LOG.warn("Could not find LDAP URL required for authentication.")
      return None
    else:
      setattr(self._backend.settings, 'SERVER_URI', ldap_config.LDAP_URL.get())

    if ldap_url.lower().startswith('ldaps') and ldap_config.USE_START_TLS.get():
      LOG.warn("Cannot configure LDAP with SSL and enable STARTTLS.")

    if ldap_config.SEARCH_BIND_AUTHENTICATION.get():
      # New Search/Bind Auth
      base_dn = ldap_config.BASE_DN.get()
      user_name_attr = ldap_config.USERS.USER_NAME_ATTR.get()
      user_filter = ldap_config.USERS.USER_FILTER.get()
      if not user_filter.startswith('('):
        user_filter = '(' + user_filter + ')'

      if ldap_config.BIND_DN.get():
        bind_dn = ldap_config.BIND_DN.get()
        setattr(self._backend.settings, 'BIND_DN', bind_dn)

        bind_password = ldap_config.BIND_PASSWORD.get()
        if not bind_password:
          bind_password = ldap_config.BIND_PASSWORD_SCRIPT.get()
        setattr(self._backend.settings, 'BIND_PASSWORD', bind_password)

      if user_filter is None:
        search_bind_results = LDAPSearch(base_dn,
            ldap.SCOPE_SUBTREE, "(" + user_name_attr + "=%(user)s)")

      else:
        search_bind_results = LDAPSearch(base_dn,
            ldap.SCOPE_SUBTREE, "(&(" + user_name_attr + "=%(user)s)" + user_filter + ")")

      setattr(self._backend.settings, 'USER_SEARCH', search_bind_results)
    else:
      nt_domain = ldap_config.NT_DOMAIN.get()
      if nt_domain is None:
        pattern = ldap_config.LDAP_USERNAME_PATTERN.get()
        pattern = pattern.replace('<username>', '%(user)s')
        setattr(self._backend.settings, 'USER_DN_TEMPLATE', pattern)
      else:
        # %(user)s is a special string that will get replaced during the authentication process
        setattr(self._backend.settings, 'USER_DN_TEMPLATE', "%(user)s@" + nt_domain)

    # Certificate-related config settings
    if ldap_config.LDAP_CERT.get():
      setattr(self._backend.settings, 'START_TLS', ldap_config.USE_START_TLS.get())
      ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
      ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, ldap_config.LDAP_CERT.get())
    else:
      setattr(self._backend.settings, 'START_TLS', False)
      ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

    if ldap_config.FOLLOW_REFERRALS.get():
      ldap.set_option(ldap.OPT_REFERRALS, 1)
    else:
      ldap.set_option(ldap.OPT_REFERRALS, 0)
Exemple #23
0
def authenticateUser(session, req, username, password):
	"""authenticate the username/password combination.
	
	Only used if config.AUTH_TYPE=='FORM'.
	This sets session['username'], iff authentication is successful.
	This should raise an Exception if authentication fails (the caller must make sure to sanitize any error message, since there's no guarantee it won't contain passwords or other sensitive information).
	"""

	if password=='': raise Exception("empty password")  #the ldap bind does not fail for empty password, so must catch it before

	import ldap

	ldap.set_option(ldap.OPT_DEBUG_LEVEL,255)

	try:
		try:
			authenticated = False
			for host in ('dc2-rc', 'dc3-rc'):
				try:
					l = ldap.initialize("ldaps://%s:636/" % host)
					l.protocol_version = ldap.VERSION3
					l.simple_bind_s(
						core.getStdout("/n/sw/rc/bin/username2ldapatts -a distinguishedName %s" % core.shQuote(username)).strip(),
						password
					)  #will raise ldap.INVALID_CREDENTIALS in case of failure
					authenticated = True
					break
				except ldap.SERVER_DOWN, e:
					msg = "got ldap.SERVER_DOWN for [%s]: %s; will retry other hosts if available" % (host, e)
					core.log(msg, session, req)
					continue
			if not authenticated: raise Exception("cannot contact LDAP server(s)")
		except ldap.INVALID_CREDENTIALS:
			raise
def initLDAP():
    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
    try:
        l = ldap.initialize(ldapUri)
    except ldap.LDAPError, e:
        print e
        exit(1)
Exemple #25
0
  def __init__(self, ldap_config, ldap_url, bind_user=None, bind_password=None, cert_file=None):
    """
    Constructor initializes the LDAP connection
    """
    self.ldap_config = ldap_config

    if cert_file is not None:
      ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
      ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cert_file)

    if self.ldap_config.FOLLOW_REFERRALS.get():
      ldap.set_option(ldap.OPT_REFERRALS, 1)
    else:
      ldap.set_option(ldap.OPT_REFERRALS, 0)

    if ldap_config.DEBUG.get():
      ldap.set_option(ldap.OPT_DEBUG_LEVEL, ldap_config.DEBUG_LEVEL.get())

    self.ldap_handle = ldap.initialize(uri=ldap_url, trace_level=ldap_config.TRACE_LEVEL.get())

    if bind_user is not None:
      try:
        self.ldap_handle.simple_bind_s(bind_user, bind_password)
      except:
        msg = "Failed to bind to LDAP server as user %s" % bind_user
        LOG.exception(msg)
        raise RuntimeError(msg)
    else:
      try:
        # Do anonymous bind
        self.ldap_handle.simple_bind_s('','')
      except:
        msg = "Failed to bind to LDAP server anonymously"
        LOG.exception(msg)
        raise RuntimeError(msg)
    def __init__(self, app=web.app, session=session, **settings):
        # Get LDAP settings.
        self.basedn = cfg.ldap.get('basedn')
        self.domainadmin_dn = cfg.ldap.get('domainadmin_dn')

        # Initialize LDAP connection.
        try:
            # Get LDAP URI.
            uri = cfg.ldap.get('uri', 'ldap://127.0.0.1')

            # Detect STARTTLS support.
            if uri.startswith('ldaps://'):
                starttls = True
            else:
                starttls = False

            # Set necessary option for STARTTLS.
            if starttls:
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

            # Initialize connection.
            self.conn = ldap.initialize(uri, trace_level=iredutils.LDAP_CONN_TRACE_LEVEL,)

            # Set LDAP protocol version: LDAP v3.
            self.conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)

            if starttls:
                self.conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)

        except:
            return False

        # synchronous bind.
        self.conn.bind_s(cfg.ldap.get('bind_dn'), cfg.ldap.get('bind_pw'))
Exemple #27
0
	def connect(self, no_starttls=False):
		self.ldapdeleteControl = LDAPControl('1.2.840.113556.1.4.417', criticality=1)
		self.timeout = 5
		use_starttls = 2
		if no_starttls:
			use_starttls = 0

		fp = open(self.pw_file, 'r')
		login_pw = fp.readline()
		if login_pw[-1] == '\n':
			login_pw = login_pw[:-1]
		fp.close()

		try:
			self.lo = ldap.initialize(uri="ldap://%s:%s" % (self.host, self.port))
			if self.ca_file:
				ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca_file)
			if use_starttls:
				self.lo.start_tls_s()
			self.lo.simple_bind_s(self.login_dn, login_pw)

		except:
			ex = 'LDAP Connection to "%s:%s" as "%s" with password "%s" failed (TLS: %s, Certificate: %s)\n' % (self.host, self.port, self.login_dn, login_pw, not no_starttls, self.ca_file)
			import traceback
			raise Exception(ex + traceback.format_exc())

		self.lo.set_option(ldap.OPT_REFERRALS, 0)
Exemple #28
0
def open_ldap(url,base,search_flt,page_size=default_page_size):
   ldap.set_option(ldap.OPT_REFERRALS, 0)
   l = ldap.initialize(url)
   l.protocol_version = 3

   sasl_auth=ldap.sasl.sasl({},'GSSAPI')
   try:
      l.sasl_interactive_bind_s('',sasl_auth)
   except ldap.LOCAL_ERROR:
      print "Error: missing credential - Please run kinit"
      sys.exit()

   lc = SimplePagedResultsControl(
      ldap.LDAP_CONTROL_PAGE_OID,True,(page_size,'')
   )

   # Send search request
   msgid = l.search_ext(
     base,
     ldap.SCOPE_SUBTREE,
     search_flt,
     serverctrls=[lc]
   )

   return l,lc,msgid
Exemple #29
0
def get_ldap_connection(session, address, force = False):
    #clear cache
    clear_ldap_cache()
    # Get session data

    ldap_connections_key = address+"__"+session.session_key
    #try to get LDAP connection from key
    l = settings.LDAP_CONNECTIONS.get(ldap_connections_key, None)

    if 'ldap' not in session.keys():
        return l
    elif address not in session['ldap'].keys():
        return l
    elif force or l == None:
        # get session info
        data = session['ldap'][address]
        userDN = data['userDN']
        password = data['password']

        print "Connecting to LDAP", address
        server = 'ldaps://%s' % (address)

        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
        l = ldap.initialize(server)
        #l.start_tls_s()
        l.simple_bind_s(userDN, password)
        settings.LDAP_CONNECTIONS[ldap_connections_key] = {'connection':l,'updated_at':datetime.now()}
    else:
        print "Get LDAP connection (%s) from cache" % (address)
        l['updated_at'] = datetime.now();
        l = l['connection']
    return l
    def _bind_ad(self, user_dn=None, passwd=None):
        user = user_dn or self.bind_dn
        password = passwd or self.bind_pw

	if not self.ads.lower().startswith('ldap://') and not self.ads.lower().startswith('ldaps://'):
            ads = 'ldap://%s' % self.ads
        else:
            ads = self.ads

        try:
	    #ldaps support
	    if ads.lower().startswith('ldaps://'):
	      if self.ignoreunknowncertificate == True:
		self.log.debug('ignoring unknown certs...')
		ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
	      if self.customcacert:
		self.log.debug('adding custom cacertfile: %s' % self.customcacert)
		ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,self.customcacert)

            l = ldap.initialize(ads)
	    l.set_option(ldap.OPT_REFERRALS, 0)
        except:
            raise TracError('Unable to contact Active Directory >>>%s<<<' % ads)

        if not user:
            raise TracError('The bind_dn ini option must be set')
        if not password:
            raise TracError('The bind_pw ini option must be set')

        try:
            l.simple_bind_s(user, password)
        except Exception, e:
            self.log.debug('Unable to bind to Active Directory', exc_info=e)
            return None 
Exemple #31
0
from __future__ import print_function

import ldap

host = "localhost:1390"

print("API info:", ldap.get_option(ldap.OPT_API_INFO))
print("debug level:", ldap.get_option(ldap.OPT_DEBUG_LEVEL))
#print("Setting debug level to 255...")
#ldap.set_option(ldap.OPT_DEBUG_LEVEL,255)
#print("debug level:",ldap.get_option(ldap.OPT_DEBUG_LEVEL))
print("default size limit:", ldap.get_option(ldap.OPT_SIZELIMIT))
print("Setting default size limit to 10...")
ldap.set_option(ldap.OPT_SIZELIMIT, 10)
print("default size limit:", ldap.get_option(ldap.OPT_SIZELIMIT))
print("Creating connection to", host, "...")
l = ldap.init(host)
print("size limit:", l.get_option(ldap.OPT_SIZELIMIT))
print("Setting connection size limit to 20...")
l.set_option(ldap.OPT_SIZELIMIT, 20)
print("size limit:", l.get_option(ldap.OPT_SIZELIMIT))
#print("Setting time limit to 60 secs...")
l.set_option(ldap.OPT_TIMELIMIT, 60)
#print("time limit:",l.get_option(ldap.OPT_TIMELIMIT))
print("Binding...")
l.simple_bind_s("", "")
Exemple #32
0
except ImportError:
    LDAP_CONFIGURED = False

# LDAP configuration (optional)
if LDAP_CONFIGURED:
    try:
        import ldap
        import django_auth_ldap
        # Prepend LDAPBackend to the default ModelBackend
        AUTHENTICATION_BACKENDS = [
            'django_auth_ldap.backend.LDAPBackend',
            'django.contrib.auth.backends.ModelBackend',
        ]
        # Optionally disable strict certificate checking
        if LDAP_IGNORE_CERT_ERRORS:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
        # Enable logging for django_auth_ldap
        ldap_logger = logging.getLogger('django_auth_ldap')
        ldap_logger.addHandler(logging.StreamHandler())
        ldap_logger.setLevel(logging.DEBUG)
    except ImportError:
        raise ImproperlyConfigured(
            "LDAP authentication has been configured, but django-auth-ldap is not installed. You can remove "
            "netbox/ldap_config.py to disable LDAP.")

# Database
configuration.DATABASE.update({'ENGINE': 'django.db.backends.postgresql'})
DATABASES = {
    'default': configuration.DATABASE,
}
Exemple #33
0
    def login(self, user_obj, **kw):
        username = kw.get('username')
        password = kw.get('password')

        # we require non-empty password as ldap bind does a anon (not password
        # protected) bind if the password is empty and SUCCEEDS!
        if not password:
            return ContinueLogin(
                user_obj,
                _('Missing password. Please enter user name and password.'))

        try:
            try:
                u = None
                dn = None
                server = self.server_uri
                coding = self.coding
                logging.debug("Setting misc. ldap options...")
                ldap.set_option(ldap.OPT_PROTOCOL_VERSION,
                                ldap.VERSION3)  # ldap v2 is outdated
                ldap.set_option(ldap.OPT_REFERRALS, self.referrals)
                ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout)

                if hasattr(ldap, 'TLS_AVAIL') and ldap.TLS_AVAIL:
                    for option, value in (
                        (ldap.OPT_X_TLS_CACERTDIR, self.tls_cacertdir),
                        (ldap.OPT_X_TLS_CACERTFILE, self.tls_cacertfile),
                        (ldap.OPT_X_TLS_CERTFILE, self.tls_certfile),
                        (ldap.OPT_X_TLS_KEYFILE, self.tls_keyfile),
                        (ldap.OPT_X_TLS_REQUIRE_CERT, self.tls_require_cert),
                        (ldap.OPT_X_TLS, self.start_tls),
                            # (ldap.OPT_X_TLS_ALLOW, 1),
                    ):
                        if value is not None:
                            ldap.set_option(option, value)

                logging.debug("Trying to initialize {0!r}.".format(server))
                l = ldap.initialize(server)
                logging.debug("Connected to LDAP server {0!r}.".format(server))

                if self.start_tls and server.startswith('ldap:'):
                    logging.debug(
                        "Trying to start TLS to {0!r}.".format(server))
                    try:
                        l.start_tls_s()
                        logging.debug("Using TLS to {0!r}.".format(server))
                    except (ldap.SERVER_DOWN, ldap.CONNECT_ERROR) as err:
                        logging.warning(
                            "Couldn't establish TLS to {0!r} (err: {1!s}).".
                            format(server, err))
                        raise

                # you can use %(username)s and %(password)s here to get the stuff entered in the form:
                binddn = self.bind_dn % locals()
                bindpw = self.bind_pw % locals()
                l.simple_bind_s(binddn.encode(coding), bindpw.encode(coding))
                logging.debug("Bound with binddn {0!r}".format(binddn))

                # you can use %(username)s here to get the stuff entered in the form:
                filterstr = self.search_filter % locals()
                logging.debug("Searching {0!r}".format(filterstr))
                attrs = [
                    getattr(self, attr) for attr in [
                        'email_attribute',
                        'displayname_attribute',
                        'surname_attribute',
                        'givenname_attribute',
                    ] if getattr(self, attr) is not None
                ]
                lusers = l.search_st(self.base_dn,
                                     self.scope,
                                     filterstr.encode(coding),
                                     attrlist=attrs,
                                     timeout=self.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]
                for dn, ldap_dict in lusers:
                    logging.debug("dn:{0!r}".format(dn))
                    for key, val in ldap_dict.items():
                        logging.debug("    {0!r}: {1!r}".format(key, val))

                result_length = len(lusers)
                if result_length != 1:
                    if result_length > 1:
                        logging.warning(
                            "Search found more than one ({0}) matches for {1!r}."
                            .format(result_length, filterstr))
                    if result_length == 0:
                        logging.debug(
                            "Search found no matches for {0!r}.".format(
                                filterstr, ))
                    if self.report_invalid_credentials:
                        return ContinueLogin(
                            user_obj, _("Invalid username or password."))
                    else:
                        return ContinueLogin(user_obj)

                dn, ldap_dict = lusers[0]
                if not self.bind_once:
                    logging.debug(
                        "DN found is {0!r}, trying to bind with pw".format(dn))
                    l.simple_bind_s(dn, password.encode(coding))
                    logging.debug(
                        "Bound with dn {0!r} (username: {1!r})".format(
                            dn, username))

                if self.email_callback is None:
                    if self.email_attribute:
                        email = ldap_dict.get(self.email_attribute,
                                              [''])[0].decode(coding)
                    else:
                        email = None
                else:
                    email = self.email_callback(ldap_dict)

                display_name = ''
                try:
                    display_name = ldap_dict[self.displayname_attribute][0]
                except (KeyError, IndexError):
                    pass
                if not display_name:
                    sn = ldap_dict.get(self.surname_attribute, [''])[0]
                    gn = ldap_dict.get(self.givenname_attribute, [''])[0]
                    if sn and gn:
                        display_name = "{0}, {1}".format(sn, gn)
                    elif sn:
                        display_name = sn
                display_name = display_name.decode(coding)

                if self.name_callback:
                    username = self.name_callback(ldap_dict)

                if email:
                    u = user.User(auth_username=username,
                                  auth_method=self.name,
                                  auth_attribs=(
                                      'name',
                                      'password',
                                      'email',
                                      'mailto_author',
                                  ),
                                  trusted=self.trusted)
                    u.email = email
                else:
                    u = user.User(auth_username=username,
                                  auth_method=self.name,
                                  auth_attribs=(
                                      'name',
                                      'password',
                                      'mailto_author',
                                  ),
                                  trusted=self.trusted)
                u.name = username
                u.display_name = display_name
                logging.debug(
                    "creating user object with name {0!r} email {1!r} display name {2!r}"
                    .format(username, email, display_name))

            except ldap.INVALID_CREDENTIALS as err:
                logging.debug(
                    "invalid credentials (wrong password?) for dn {0!r} (username: {1!r})"
                    .format(dn, username))
                return CancelLogin(_("Invalid username or password."))

            if u and self.autocreate:
                logging.debug(
                    "calling create_or_update to autocreate user {0!r}".format(
                        u.name))
                u.create_or_update(True)
            return ContinueLogin(u)

        except ldap.SERVER_DOWN as err:
            # looks like this LDAP server isn't working, so we just try the next
            # authenticator object in cfg.auth list (there could be some second
            # ldap authenticator that queries a backup server or any other auth
            # method).
            logging.error(
                "LDAP server {0} failed ({1!s}). "
                "Trying to authenticate with next auth list entry.".format(
                    server, err))
            return ContinueLogin(
                user_obj, _("LDAP server %(server)s failed.", server=server))

        except:
            logging.exception("caught an exception, traceback follows...")
            return ContinueLogin(user_obj)
Exemple #34
0
# -*- coding: utf-8 -*-
#
# last tinkered with by korylprince at gmail.com on 2012-04-5
#

import sys
import logging
try:
    import ldap
    import ldap.filter
    ldap.set_option(ldap.OPT_REFERRALS, 0)
except Exception, e:
    logging.error('missing ldap, try "easy_install python-ldap"')
    raise e


def ldap_auth(server='ldap',
              port=None,
              base_dn='ou=users,dc=domain,dc=com',
              mode='uid',
              secure=False,
              cert_path=None,
              cert_file=None,
              bind_dn=None,
              bind_pw=None,
              filterstr='objectClass=*',
              username_attrib='uid',
              custom_scope='subtree',
              allowed_groups=None,
              manage_user=False,
              user_firstname_attrib='cn:1',
def func_get_ldap_connection():
    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
    conn = ldap.initialize(LDAP_PROVIDER_URL)
    return conn
Exemple #36
0
    def __eval_options(self, section, backend=None):
        settings = self.__domain

        settings["domain"] = self.__search_domain
        settings["emailaddress"] = self.__emailaddress
        
        section = self.__find_section(section)
        
        if self.has_option(section, "backend"):
            if backend is None:
                try:
                    backend = self.get(section, "backend")
                except NoOptionError:
                    raise Exception("Missing option <backend>")
                
            if backend in ("static", "static_append"):
                for opt in iter(self.options(section)):
                    if opt in ("action",
                               "account_type",
                               "account_name",
                               "account_name_short",
                               "display_name",
                               "server_url",
                               "server_name"):
                        tmp = self.get(section, opt)
                        result = self.__expand_vars(tmp)
                        result = self.__replace_makro(result)
                        settings[opt] = result
                    elif opt == "smtp":
                        service = self.__service(section, "smtp")
                    elif opt == "imap":
                        service = self.__service(section, "imap")
                    elif opt == "pop":
                        service = self.__service(section, "pop")
                    elif opt == "sign_mobileconfig":
                        try:
                            settings[opt] = self.getboolean(section, opt)
                        except:
                            logging.error("%s is not boolean!" % opt)
                            settings[opt] = False
                    elif opt in ("sign_cert", "sign_key"):
                        result = self.get(section, opt)
                        if os.path.exists(result):
                            settings[opt] = result
                        else:
                            logging.error("%s cannot read %s" % (opt, result))
                    else:
                        pass
                    
                    if opt in ("smtp", "imap", "pop"):
                        if backend == "static_append":
                            if settings.has_key(opt):
                                if self.debug:
                                    logging.debug("APPEND %s" % service)
                                settings[opt].append(service)
                            else:
                                if self.debug:
                                    logging.debug("APPEND NEW %s"
                                                  % service)
                                settings[opt] = [service]
                        else:
                            # do not include empty services
                            if len(service) != 0:
                                if self.debug:
                                    logging.debug("STATIC %s" % service)
                                service_category = OrderedDict()
                                service_category[opt] = [service]
                                settings.update(service_category)

                # always follow at the end!
                if "follow" in self.options(section):
                    tmp = self.get(section, "follow")
                    result = self.__expand_vars(tmp)
                    result = self.__replace_makro(result)
                    self.__eval_options(result)

            elif backend in ("ldap", "ldap_append"):
                try:
                    import ldap
                    import ldap.sasl
                except:
                    raise Exception("python ldap missing")

                ldap_cfg = dict(host = "ldap://127.0.0.1/",
                                base = "",
                                bindmethod = "simple",
                                binddn = None,
                                bindpw = None,
                                saslmech = None,
                                authzid = "",
                                filter = "(objectClass=*)",
                                result_attrs = [],
                                scope = "sub",
                                usetls = "no",
                                cipher = "TLSv1",
                                reqcert ="never",
                                cert = None,
                                key = None,
                                cacert = None)

                tls = False
                sasl = False

                for opt in iter(self.options(section)):
                    if opt in ("host",
                               "base",
                               "bindmethod",
                               "binddn",
                               "bindpw",
                               "saslmech",
                               "authzid",
                               "filter",
                               "result_attrs",
                               "scope",
                               "usetls",
                               "cipher",
                               "reqcert",
                               "cert",
                               "key",
                               "cacert"):
                        result = self.get(section, opt)
                        
                        if opt in ("host", "result_attrs"):
                            result = self.create_list(result)
                            
                        ldap_cfg[opt] = result
                
                # Do we connect with TLS?
                if ldap_cfg["usetls"].strip().lower() in TRUE:
                    if ldap_cfg["reqcert"] in ("never",
                                               "allow",
                                               "try",
                                               "demand"):
                        rc = ldap_cfg["reqcert"]
                        if rc == "never":
                            reqcert = ldap.OPT_X_TLS_NEVER
                        elif rc == "allow":
                            reqcert = ldap.OPT_X_TLS_ALLOW
                        elif rc == "try":
                            reqcert = ldap.OPT_X_TLS_TRY
                        elif rc == "demand":
                            reqcert = ldap.OPT_X_TLS_DEMAND

                    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, reqcert)
                    ldap.set_option(ldap.OPT_X_TLS_CIPHER_SUITE,
                                    ldap_cfg["cipher"])

                    if ldap_cfg["cacert"] is not None:
                        ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,
                                        ldap_cfg["cacert"])
                    if ldap_cfg["cert"] is not None:
                        ldap.set_option(ldap.OPT_X_TLS_CERTFILE,
                                        ldap_cfg["cert"])
                    if ldap_cfg["key"] is not None:
                        ldap.set_option(ldap.OPT_X_TLS_KEYFILE,
                                        ldap_cfg["key"])

                    tls = True
        
                # Are we SASL binding to our servers?
                if ldap_cfg["bindmethod"] == "sasl":
                    mech = ldap_cfg["saslmech"]

                    if mech is not None:
                        if mech.lower() == "digest-md5":
                            auth_tokens = ldap.sasl.digest_md5(
                                                        ldap_cfg["binddn"],
                                                        ldap_cfg["bindpw"])
                        elif mech.lower() == "cram-md5":
                            auth_tokens = ldap.sasl.cram_md5(
                                                        ldap_cfg["binddn"],
                                                        ldap_cfg["bindpw"])
                        elif mech.lower() == "external":
                            auth_tokens = ldap.sasl.external(
                                                        ldap_cfg["authzid"])
                        elif mech.lower() == "gssapi":
                            auth_tokens = ldap.sasl.gssapi(ldap_cfg["authzid"])

                    sasl = True
        
                con = None

                for server in iter(ldap_cfg["host"]):
                    try:
                        con = ldap.initialize(server)
                        if tls:
                            con.start_tls_s()
                        if sasl:
                            con.sasl_interactive_bind_s("", auth_tokens)
                        else:
                            con.simple_bind_s(ldap_cfg["binddn"],
                                              ldap_cfg["bindpw"])
                    except Exception, e:
                        logging.error("LDAP: %s" % e)
                        continue
                    break

                if con is not None:
                    if ldap_cfg["scope"] in ("sub", "subtree"):
                        scope = ldap.SCOPE_SUBTREE
                    elif ldap_cfg["scope"] in ("one", "onelevel"):
                        scope = ldap.SCOPE_ONELEVEL
                    elif ldap_cfg["scope"] in ("base", "exact"):
                        scope = ldap.SCOPE_BASE

                    filter = self.__replace_makro(ldap_cfg["filter"])
                                            
                    rid = con.search(ldap_cfg["base"],
                                     scope,
                                     filter,
                                     ldap_cfg["result_attrs"])
            
                    raw_res = (None, None)
                    raw_res = con.result(rid, True, 60)
                    if raw_res[0] == None:
                        con.abandon(rid)
                        raise Exception("LDAP server timeout reached")

                    # connection established, we have results
                    self.__vars = dict()
                    
                    # we did not receive data from LDAP
                    if raw_res[1] != []:
                        for entry in raw_res[1]:
                            for key, value in entry[1].items():
                                # result attributes might be multi values, but
                                # we only accept the first value.
                                self.__vars[key] = unicode(value[0], "utf-8")
                    else:
                        logging.warning("No LDAP result from server!")
                        raise DataNotFoundException

                    try:    
                        con.unbind()
                    except ldap.LDAPError, e:
                        pass

                if backend == "ldap":
                    self.__eval_options(section, backend="static")
                else:
                    self.__eval_options(section, backend="static_append")
Exemple #37
0
    def __init__(self,
                 ldap_config,
                 ldap_url,
                 bind_user=None,
                 bind_password=None,
                 cert_file=None):
        """
    Constructor initializes the LDAP connection
    """
        self.ldap_config = ldap_config
        self._ldap_url = ldap_url
        self._username = bind_user
        self._ldap_cert = cert_file

        # Certificate-related config settings
        if ldap_config.LDAP_CERT.get():
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
            ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,
                            ldap_config.LDAP_CERT.get())
        else:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

        if self.ldap_config.FOLLOW_REFERRALS.get():
            ldap.set_option(ldap.OPT_REFERRALS, 1)
        else:
            ldap.set_option(ldap.OPT_REFERRALS, 0)

        if ldap_config.DEBUG.get():
            ldap.set_option(ldap.OPT_DEBUG_LEVEL,
                            ldap_config.DEBUG_LEVEL.get())

        self.ldap_handle = ldap.initialize(
            uri=ldap_url, trace_level=ldap_config.TRACE_LEVEL.get())
        if self.ldap_config.USE_START_TLS.get(
        ) and not ldap_url.lower().startswith('ldaps'):
            self.ldap_handle.start_tls_s()

        if bind_user:
            try:
                self.ldap_handle.simple_bind_s(bind_user, bind_password)
            except Exception as e:
                self.handle_bind_exception(e, bind_user)
        else:
            try:
                # Do anonymous bind
                self.ldap_handle.simple_bind_s('', '')
            except Exception as e:
                self.handle_bind_exception(e)
Exemple #38
0
    def auth_user_ldap(self, username, password):
        """
            Method for authenticating user, auth LDAP style.
            depends on ldap module that is not mandatory requirement
            for F.A.B.

            :param username:
                The username
            :param password:
                The password
        """
        if username is None or username == "":
            return None
        user = self.find_user(username=username)
        if user is not None and (not user.is_active()):
            return None
        else:
            try:
                import ldap
            except:
                raise Exception("No ldap library for python.")
                return None
            try:
                if self.auth_ldap_allow_self_signed:
                    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,
                                    ldap.OPT_X_TLS_ALLOW)
                con = ldap.initialize(self.auth_ldap_server)
                con.set_option(ldap.OPT_REFERRALS, 0)
                if self.auth_ldap_use_tls:
                    try:
                        con.start_tls_s()
                    except Exception:
                        log.info(
                            LOGMSG_ERR_SEC_AUTH_LDAP_TLS.format(
                                self.auth_ldap_server))
                        return None
                # Authenticate user
                if not self._bind_ldap(ldap, con, username, password):
                    if user:
                        self.update_user_auth_stat(user, False)
                    log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username))
                    return None
                # If user does not exist on the DB and not self user registration, go away
                if not user and not self.auth_user_registration:
                    return None
                # User does not exist, create one if self registration.
                elif not user and self.auth_user_registration:
                    new_user = self._search_ldap(ldap, con, username)
                    if not new_user:
                        log.warning(LOGMSG_WAR_SEC_NOLDAP_OBJ.format(username))
                        return None
                    ldap_user_info = new_user[0][1]
                    if self.auth_user_registration and user is None:
                        user = self.add_user(
                            username=username,
                            first_name=ldap_user_info.get(
                                self.auth_ldap_firstname_field, [username])[0],
                            last_name=ldap_user_info.get(
                                self.auth_ldap_lastname_field, [username])[0],
                            email=ldap_user_info.get(
                                self.auth_ldap_email_field,
                                [username + '@email.notfound'])[0],
                            role=self.find_role(
                                self.auth_user_registration_role))

                self.update_user_auth_stat(user)
                return user

            except ldap.LDAPError as e:
                if type(e.message) == dict and 'desc' in e.message:
                    log.error(
                        LOGMSG_ERR_SEC_AUTH_LDAP.format(e.message['desc']))
                    return None
                else:
                    log.error(e)
                    return None
Exemple #39
0
def authenticate(api_handle, username, password):
    """
    Validate an LDAP bind, returning whether the authentication was successful or not.

    :param api_handle: The api instance to resolve settings.
    :param username: The username to authenticate.
    :param password: The password to authenticate.
    :return: True if the ldap server authentication was a success, otherwise false.
    """

    if not password:
        return False
    import ldap

    server = api_handle.settings().ldap_server
    basedn = api_handle.settings().ldap_base_dn
    port = str(api_handle.settings().ldap_port)
    tls = api_handle.settings().ldap_tls
    anon_bind = api_handle.settings().ldap_anonymous_bind
    prefix = api_handle.settings().ldap_search_prefix

    # Support for LDAP client certificates
    tls_cacertfile = api_handle.settings().ldap_tls_cacertfile
    tls_keyfile = api_handle.settings().ldap_tls_keyfile
    tls_certfile = api_handle.settings().ldap_tls_certfile

    # allow multiple servers split by a space
    if server.find(" "):
        servers = server.split()
    else:
        servers = [server]

    # to get ldap working with Active Directory
    ldap.set_option(ldap.OPT_REFERRALS, 0)

    if tls_cacertfile:
        ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile)
    if tls_keyfile:
        ldap.set_option(ldap.OPT_X_TLS_KEYFILE, tls_keyfile)
    if tls_certfile:
        ldap.set_option(ldap.OPT_X_TLS_CERTFILE, tls_certfile)

    uri = ""
    for server in servers:
        # form our ldap uri based on connection port
        if port == '389':
            uri += 'ldap://' + server
        elif port == '636':
            uri += 'ldaps://' + server
        else:
            uri += 'ldap://' + "%s:%s" % (server, port)
        uri += ' '

    uri = uri.strip()

    # connect to LDAP host
    dir = ldap.initialize(uri)

    # start_tls if tls is 'on', 'true' or 'yes' and we're not already using old-SSL
    tls = str(tls).lower()
    if port != '636':
        if tls in ["on", "true", "yes", "1"]:
            try:
                dir.start_tls_s()
            except:
                traceback.print_exc()
                return False

    # if we're not allowed to search anonymously, grok the search bind settings and attempt to bind
    anon_bind = str(anon_bind).lower()
    if anon_bind not in ["on", "true", "yes", "1"]:
        searchdn = api_handle.settings().ldap_search_bind_dn
        searchpw = api_handle.settings().ldap_search_passwd

        if searchdn == '' or searchpw == '':
            raise CX("Missing search bind settings")

        try:
            dir.simple_bind_s(searchdn, searchpw)
        except:
            traceback.print_exc()
            return False

    # perform a subtree search in basedn to find the full dn of the user
    # TODO: what if username is a CN?  maybe it goes into the config file as well?
    filter = prefix + username
    result = dir.search_s(basedn, ldap.SCOPE_SUBTREE, filter, [])
    if result:
        for dn, entry in result:
            # username _should_ be unique so we should only have one result ignore entry; we don't need it
            pass
    else:
        return False

    try:
        # attempt to bind as the user
        dir.simple_bind_s(dn, password)
        dir.unbind()
        return True
    except:
        # traceback.print_exc()
        return False
    # catch-all
    return False
Exemple #40
0
def _ldap_auth(kerb_user=None):
    """
    Performs LDAP Authentication and Group Membership Check

    If Keberos Authentication was successfull this function is used for the additional Group Membership Check.
    If Kerberos Authentication fails and a Basic Auth Header is preasent in the Request this function is called to
    to Authenticate using LDAP and additionally Check for Group Membership.
    Note: LDAP Groups are defined in the configuration file. (config.py)

    :param kerb_user: Will be None if doing complete Basic Auth will contain users principle if just checking Group
                      membership.
    :type user principle: str
    :returns None if auth failed and users principle if successfull
    :rtype: str or None
    """

    password = None
    username = None
    if kerb_user:
        if _cfg["GROUP_AUTH"]:
            username = kerb_user.split('@', 1)[0]
        else:
            return kerb_user.split('@', 1)[0]
    elif ("HTTP_AUTHORIZATION" in request.headers.environ and "Basic" in request.environ["HTTP_AUTHORIZATION"]) or \
            "BASIC_AUTH" in session:
        if "BASIC_AUTH" in session:
            auth = session["BASIC_AUTH"].split(' ', 1)
        else:
            auth = request.headers.environ["HTTP_AUTHORIZATION"].split(' ', 1)
        try:
            username, password = b64decode((auth[1])).split(":")
        except Exception as ex:
            _logger.warn("Bad Request: Basic Auth header decode error")
            _logger.warn(ex)
            return None
    else:
        return None

    # Set ldap host
    ldap_connection = ldap.initialize(_cfg['LDAP_HOST'])
    # Set up cert, only required by the bind
    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, _cfg['LDAP_CERT_PATH'])
    # set up query string. Used to verify user is in valid groups
    query = '(&(memberUid=' + username + ')(|' + _cfg[
        'VALID_LDAP_GROUPS'] + "))"
    # Set up search base
    base = _cfg['LDAP_SEARCH_BASE']
    # Set up search scope
    search_scope = ldap.SCOPE_SUBTREE
    # None causes all to be returned
    retrieve_attributes = None

    authorized_user = None
    try:

        if not kerb_user:
            _logger.warn(": Could not authorize using kerberos, trying ldap")
            user = "******" + username + "," + _cfg['LDAP_BIND_BASE']
            ldap_connection.start_tls_s()
            if not ldap_connection.simple_bind_s(user, password):
                return None
            authorized_user = username

        if _cfg['VALID_LDAP_GROUPS'] != "()" and _cfg["GROUP_AUTH"]:
            # Search ldap to verify that user is in one of the defined valid groups
            ldap_result_id = ldap_connection.search(base, search_scope, query,
                                                    retrieve_attributes)
            rtype, rdata = ldap_connection.result(ldap_result_id, 1)
            if rdata:
                authorized_user = username
            else:
                func = inspect.stack()[0][3]
                _logger.warn(
                    "{0} - Bad Request, could not verify users credentials - user not in group "
                    .format(func))
                authorized_user = None
        else:
            authorized_user = username
    except Exception as ex:
        func = inspect.stack()[0][3]
        _logger.warn(
            "{0} - Bad Request, could not verifying users credentials ".format(
                func))
        _logger.warn(ex.message)
        authorized_user = None
    if authorized_user:
        return authorized_user
    else:
        func = inspect.stack()[0][3]
        _logger.warn(
            "{0} - Bad Request, could not verifying users credentials ".format(
                func))
        return None
    sys.exit()

setup_init = os.path.join(setup_dir, '__init__.py')

if not os.path.exists(setup_init):
    print "setup was not initialized. Please first run Gluu Server upgrader script. Exiting..."
    sys.exit()

from setup.pylib.printVersion import get_war_info
from setup.setup import Setup

from setup.pylib.Properties import Properties

import ldap
import ldap.modlist as modlist
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)


def check_oxd_server(host, port):
    conn = httplib.HTTPSConnection(host,
                                   port,
                                   context=ssl._create_unverified_context())

    try:
        conn.request("GET", "/health-check")
        result = conn.getresponse()

        if result.status == 200:
            text = result.read()
            data = json.loads(text)
            if data['status'] == 'running':
Exemple #42
0
 def set_option(self, option, value):
     return ldap.set_option(option, value)
Exemple #43
0
def ldap_auth(
        server='ldap',
        port=None,
        base_dn='ou=users,dc=domain,dc=com',
        mode='uid',
        secure=False,
        self_signed_certificate=None,  # See NOTE below
        cert_path=None,
        cert_file=None,
        cacert_path=None,
        cacert_file=None,
        key_file=None,
        bind_dn=None,
        bind_pw=None,
        filterstr='objectClass=*',
        username_attrib='uid',
        custom_scope='subtree',
        allowed_groups=None,
        manage_user=False,
        user_firstname_attrib='cn:1',
        user_lastname_attrib='cn:2',
        user_mail_attrib='mail',
        manage_groups=False,
        db=None,
        group_dn=None,
        group_name_attrib='cn',
        group_member_attrib='memberUid',
        group_filterstr='objectClass=*',
        tls=False,
        logging_level='error'):
    """
    to use ldap login with MS Active Directory:

        from gluon.contrib.login_methods.ldap_auth import ldap_auth
        auth.settings.login_methods.append(ldap_auth(
            mode='ad', server='my.domain.controller',
            base_dn='ou=Users,dc=domain,dc=com'))

    to use ldap login with Notes Domino:

        auth.settings.login_methods.append(ldap_auth(
            mode='domino',server='my.domino.server'))

    to use ldap login with OpenLDAP:

        auth.settings.login_methods.append(ldap_auth(
            server='my.ldap.server', base_dn='ou=Users,dc=domain,dc=com'))

    to use ldap login with OpenLDAP and subtree search and (optionally)
    multiple DNs:

        auth.settings.login_methods.append(ldap_auth(
            mode='uid_r', server='my.ldap.server',
            base_dn=['ou=Users,dc=domain,dc=com','ou=Staff,dc=domain,dc=com']))

    or (if using CN):

        auth.settings.login_methods.append(ldap_auth(
            mode='cn', server='my.ldap.server',
            base_dn='ou=Users,dc=domain,dc=com'))

    or you can full customize the search for user:

        auth.settings.login_methods.append(ldap_auth(
            mode='custom', server='my.ldap.server',
            base_dn='ou=Users,dc=domain,dc=com',
            username_attrib='uid',
            custom_scope='subtree'))

    the custom_scope can be: base, onelevel, subtree.

    If using secure ldaps:// pass secure=True and cert_path="..."
    If ldap is using GnuTLS then you need cert_file="..." instead cert_path
    because cert_path isn't implemented in GnuTLS :(

    To enable TLS, set tls=True:

        auth.settings.login_methods.append(ldap_auth(
            server='my.ldap.server',
            base_dn='ou=Users,dc=domain,dc=com',
            tls=True))

    If you need to bind to the directory with an admin account in order to
    search it then specify bind_dn & bind_pw to use for this.
    - currently only implemented for Active Directory

    If you need to restrict the set of allowed users (e.g. to members of a
    department) then specify an rfc4515 search filter string.
    - currently only implemented for mode in ['ad', 'company', 'uid_r']

    You can manage user attributes first name, last name, email from ldap:
        auth.settings.login_methods.append(ldap_auth(...as usual...,
            manage_user=True,
            user_firstname_attrib='cn:1',
            user_lastname_attrib='cn:2',
            user_mail_attrib='mail'
           ))

    Where:
    manage_user - let web2py handle user data from ldap
    user_firstname_attrib - the attribute containing the user's first name
                            optionally you can specify parts.
                            Example: cn: "John Smith" - 'cn:1'='John'
    user_lastname_attrib - the attribute containing the user's last name
                            optionally you can specify parts.
                            Example: cn: "John Smith" - 'cn:2'='Smith'
    user_mail_attrib - the attribute containing the user's email address


    If you need group control from ldap to web2py app's database feel free
    to set:

        auth.settings.login_methods.append(ldap_auth(...as usual...,
            manage_groups=True,
            db=db,
            group_dn='ou=Groups,dc=domain,dc=com',
            group_name_attrib='cn',
            group_member_attrib='memberUid',
            group_filterstr='objectClass=*'
           ))

        Where:
        manage_group - let web2py handle the groups from ldap
        db - is the database object (need to have auth_user, auth_group,
            auth_membership)
        group_dn - the ldap branch of the groups
        group_name_attrib - the attribute where the group name is stored
        group_member_attrib - the attribute containing the group members name
        group_filterstr - as the filterstr but for group select

    You can restrict login access to specific groups if you specify:

        auth.settings.login_methods.append(ldap_auth(...as usual...,
            allowed_groups=[...],
            group_dn='ou=Groups,dc=domain,dc=com',
            group_name_attrib='cn',
            group_member_attrib='memberUid',#use 'member' for Active Directory
            group_filterstr='objectClass=*'
           ))

        Where:
        allowed_groups - a list with allowed ldap group names
        group_dn - the ldap branch of the groups
        group_name_attrib - the attribute where the group name is stored
        group_member_attrib - the attribute containing the group members name
        group_filterstr - as the filterstr but for group select

    If using Active Directory you must specify bind_dn and bind_pw for
    allowed_groups unless anonymous bind works.

    You can set the logging level with the "logging_level" parameter, default
    is "error" and can be set to error, warning, info, debug.
    """

    if self_signed_certificate:
        # NOTE : If you have a self-signed SSL Certificate pointing over "port=686" and "secure=True" alone
        #        will not work, you need also to set "self_signed_certificate=True".
        # Ref1: https://onemoretech.wordpress.com/2015/06/25/connecting-to-ldap-over-self-signed-tls-with-python/
        # Ref2: http://bneijt.nl/blog/post/connecting-to-ldaps-with-self-signed-cert-using-python/
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

    logger = logging.getLogger('web2py.auth.ldap_auth')
    if logging_level == 'error':
        logger.setLevel(logging.ERROR)
    elif logging_level == 'warning':
        logger.setLevel(logging.WARNING)
    elif logging_level == 'info':
        logger.setLevel(logging.INFO)
    elif logging_level == 'debug':
        logger.setLevel(logging.DEBUG)

    def ldap_auth_aux(username,
                      password,
                      ldap_server=server,
                      ldap_port=port,
                      ldap_basedn=base_dn,
                      ldap_mode=mode,
                      ldap_binddn=bind_dn,
                      ldap_bindpw=bind_pw,
                      secure=secure,
                      cert_path=cert_path,
                      cert_file=cert_file,
                      cacert_file=cacert_file,
                      key_file=key_file,
                      filterstr=filterstr,
                      username_attrib=username_attrib,
                      custom_scope=custom_scope,
                      manage_user=manage_user,
                      user_firstname_attrib=user_firstname_attrib,
                      user_lastname_attrib=user_lastname_attrib,
                      user_mail_attrib=user_mail_attrib,
                      manage_groups=manage_groups,
                      allowed_groups=allowed_groups,
                      db=db):
        if password == '':  # http://tools.ietf.org/html/rfc4513#section-5.1.2
            logger.warning('blank password not allowed')
            return False
        logger.debug('mode: [%s] manage_user: [%s] custom_scope: [%s]'
                     ' manage_groups: [%s]' %
                     (str(mode), str(manage_user), str(custom_scope),
                      str(manage_groups)))
        if manage_user:
            if user_firstname_attrib.count(':') > 0:
                (user_firstname_attrib,
                 user_firstname_part) = user_firstname_attrib.split(':', 1)
                user_firstname_part = (int(user_firstname_part) - 1)
            else:
                user_firstname_part = None
            if user_lastname_attrib.count(':') > 0:
                (user_lastname_attrib,
                 user_lastname_part) = user_lastname_attrib.split(':', 1)
                user_lastname_part = (int(user_lastname_part) - 1)
            else:
                user_lastname_part = None
            user_firstname_attrib = ldap.filter.escape_filter_chars(
                user_firstname_attrib)
            user_lastname_attrib = ldap.filter.escape_filter_chars(
                user_lastname_attrib)
            user_mail_attrib = ldap.filter.escape_filter_chars(
                user_mail_attrib)
        try:
            if allowed_groups:
                if not is_user_in_allowed_groups(username, password):
                    return False
            con = init_ldap()
            if ldap_mode == 'ad':
                # Microsoft Active Directory
                if '@' not in username:
                    domain = []
                    for x in ldap_basedn.split(','):
                        if "DC=" in x.upper():
                            domain.append(x.split('=')[-1])
                    username = "******" % (username, '.'.join(domain))
                username_bare = username.split("@")[0]
                con.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
                # In cases where ForestDnsZones and DomainDnsZones are found,
                # result will look like the following:
                # ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,
                #    DC=domain,DC=com']
                if ldap_binddn:
                    # need to search directory with an admin account 1st
                    con.simple_bind_s(ldap_binddn, ldap_bindpw)
                else:
                    # credentials should be in the form of [email protected]
                    con.simple_bind_s(username, password)
                # this will throw an index error if the account is not found
                # in the ldap_basedn
                requested_attrs = ['sAMAccountName']
                if manage_user:
                    requested_attrs.extend([
                        user_firstname_attrib, user_lastname_attrib,
                        user_mail_attrib
                    ])
                result = con.search_ext_s(
                    ldap_basedn, ldap.SCOPE_SUBTREE,
                    "(&(sAMAccountName=%s)(%s))" %
                    (ldap.filter.escape_filter_chars(username_bare),
                     filterstr), requested_attrs)[0][1]
                if not isinstance(result, dict):
                    # result should be a dict in the form
                    # {'sAMAccountName': [username_bare]}
                    logger.warning('User [%s] not found!' % username)
                    return False
                if ldap_binddn:
                    # We know the user exists & is in the correct OU
                    # so now we just check the password
                    con.simple_bind_s(username, password)
                username = username_bare

            if ldap_mode == 'domino':
                # Notes Domino
                if "@" in username:
                    username = username.split("@")[0]
                con.simple_bind_s(username, password)
                if manage_user:
                    # TODO: sorry I have no clue how to query attrs in domino
                    result = {
                        user_firstname_attrib: username,
                        user_lastname_attrib: None,
                        user_mail_attrib: None
                    }

            if ldap_mode == 'cn':
                # OpenLDAP (CN)
                if ldap_binddn and ldap_bindpw:
                    con.simple_bind_s(ldap_binddn, ldap_bindpw)
                dn = "cn=" + username + "," + ldap_basedn
                con.simple_bind_s(dn, password)
                if manage_user:
                    result = con.search_s(
                        dn, ldap.SCOPE_BASE, "(objectClass=*)", [
                            user_firstname_attrib, user_lastname_attrib,
                            user_mail_attrib
                        ])[0][1]

            if ldap_mode == 'uid':
                # OpenLDAP (UID)
                if ldap_binddn and ldap_bindpw:
                    con.simple_bind_s(ldap_binddn, ldap_bindpw)
                    dn = "uid=" + username + "," + ldap_basedn
                    dn = con.search_s(ldap_basedn, ldap.SCOPE_SUBTREE,
                                      "(uid=%s)" % username, [''])[0][0]
                else:
                    dn = "uid=" + username + "," + ldap_basedn
                con.simple_bind_s(dn, password)
                if manage_user:
                    result = con.search_s(
                        dn, ldap.SCOPE_BASE, "(objectClass=*)", [
                            user_firstname_attrib, user_lastname_attrib,
                            user_mail_attrib
                        ])[0][1]

            if ldap_mode == 'company':
                # no DNs or password needed to search directory
                dn = ""
                pw = ""
                # bind anonymously
                con.simple_bind_s(dn, pw)
                # search by e-mail address
                filter = '(&(mail=%s)(%s))' % (
                    ldap.filter.escape_filter_chars(username), filterstr)
                # find the uid
                attrs = ['uid']
                if manage_user:
                    attrs.extend([
                        user_firstname_attrib, user_lastname_attrib,
                        user_mail_attrib
                    ])
                # perform the actual search
                company_search_result = con.search_s(ldap_basedn,
                                                     ldap.SCOPE_SUBTREE,
                                                     filter, attrs)
                dn = company_search_result[0][0]
                result = company_search_result[0][1]
                # perform the real authentication test
                con.simple_bind_s(dn, password)

            if ldap_mode == 'uid_r':
                # OpenLDAP (UID) with subtree search and multiple DNs
                if isinstance(ldap_basedn, list):
                    basedns = ldap_basedn
                else:
                    basedns = [ldap_basedn]
                filter = '(&(uid=%s)(%s))' % (
                    ldap.filter.escape_filter_chars(username), filterstr)
                found = False
                for basedn in basedns:
                    try:
                        result = con.search_s(basedn, ldap.SCOPE_SUBTREE,
                                              filter)
                        if result:
                            user_dn = result[0][0]
                            # Check the password
                            con.simple_bind_s(user_dn, password)
                            found = True
                            break
                    except ldap.LDAPError, detail:
                        (exc_type, exc_value) = sys.exc_info()[:2]
                        logger.warning(
                            "ldap_auth: searching %s for %s resulted in %s: %s\n"
                            % (basedn, filter, exc_type, exc_value))
                if not found:
                    logger.warning('User [%s] not found!' % username)
                    return False
                result = result[0][1]
            if ldap_mode == 'custom':
                # OpenLDAP (username_attrs) with subtree search and
                # multiple DNs
                if isinstance(ldap_basedn, list):
                    basedns = ldap_basedn
                else:
                    basedns = [ldap_basedn]
                filter = '(&(%s=%s)(%s))' % (
                    username_attrib, ldap.filter.escape_filter_chars(username),
                    filterstr)
                if custom_scope == 'subtree':
                    ldap_scope = ldap.SCOPE_SUBTREE
                elif custom_scope == 'base':
                    ldap_scope = ldap.SCOPE_BASE
                elif custom_scope == 'onelevel':
                    ldap_scope = ldap.SCOPE_ONELEVEL
                found = False
                for basedn in basedns:
                    try:
                        result = con.search_s(basedn, ldap_scope, filter)
                        if result:
                            user_dn = result[0][0]
                            # Check the password
                            con.simple_bind_s(user_dn, password)
                            found = True
                            break
                    except ldap.LDAPError, detail:
                        (exc_type, exc_value) = sys.exc_info()[:2]
                        logger.warning(
                            "ldap_auth: searching %s for %s resulted in %s: %s\n"
                            % (basedn, filter, exc_type, exc_value))
                if not found:
                    logger.warning('User [%s] not found!' % username)
                    return False
                result = result[0][1]
            if manage_user:
                logger.info('[%s] Manage user data' % str(username))
                try:
                    if user_firstname_part is not None:
                        store_user_firstname = result[user_firstname_attrib][
                            0].split(' ', 1)[user_firstname_part]
                    else:
                        store_user_firstname = result[user_firstname_attrib][0]
                except KeyError, e:
                    store_user_firstname = None
                try:
                    if user_lastname_part is not None:
                        store_user_lastname = result[user_lastname_attrib][
                            0].split(' ', 1)[user_lastname_part]
                    else:
                        store_user_lastname = result[user_lastname_attrib][0]
                except KeyError, e:
                    store_user_lastname = None
Exemple #44
0
    def __init__(self,
                 url,
                 page_size,
                 alias_dereferencing=None,
                 use_tls=False,
                 tls_cacertfile=None,
                 tls_cacertdir=None,
                 tls_req_cert='demand'):
        LOG.debug(_("LDAP init: url=%s"), url)
        LOG.debug(
            _('LDAP init: use_tls=%(use_tls)s\n'
              'tls_cacertfile=%(tls_cacertfile)s\n'
              'tls_cacertdir=%(tls_cacertdir)s\n'
              'tls_req_cert=%(tls_req_cert)s\n'
              'tls_avail=%(tls_avail)s\n') % {
                  'use_tls': use_tls,
                  'tls_cacertfile': tls_cacertfile,
                  'tls_cacertdir': tls_cacertdir,
                  'tls_req_cert': tls_req_cert,
                  'tls_avail': ldap.TLS_AVAIL
              })

        #NOTE(topol)
        #for extra debugging uncomment the following line
        #ldap.set_option(ldap.OPT_DEBUG_LEVEL, 4095)

        using_ldaps = url.lower().startswith("ldaps")

        if use_tls and using_ldaps:
            raise AssertionError(_('Invalid TLS / LDAPS combination'))

        if use_tls:
            if not ldap.TLS_AVAIL:
                raise ValueError(
                    _('Invalid LDAP TLS_AVAIL option: %s. TLS'
                      'not available') % ldap.TLS_AVAIL)
            if tls_cacertfile:
                #NOTE(topol)
                #python ldap TLS does not verify CACERTFILE or CACERTDIR
                #so we add some extra simple sanity check verification
                #Also, setting these values globally (i.e. on the ldap object)
                #works but these values are ignored when setting them on the
                #connection
                if not os.path.isfile(tls_cacertfile):
                    raise IOError(
                        _("tls_cacertfile %s not found "
                          "or is not a file") % tls_cacertfile)
                ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, tls_cacertfile)
            elif tls_cacertdir:
                #NOTE(topol)
                #python ldap TLS does not verify CACERTFILE or CACERTDIR
                #so we add some extra simple sanity check verification
                #Also, setting these values globally (i.e. on the ldap object)
                #works but these values are ignored when setting them on the
                #connection
                if not os.path.isdir(tls_cacertdir):
                    raise IOError(
                        _("tls_cacertdir %s not found "
                          "or is not a directory") % tls_cacertdir)
                ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, tls_cacertdir)
            if tls_req_cert in LDAP_TLS_CERTS.values():
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_cert)
            else:
                LOG.debug(_("LDAP TLS: invalid TLS_REQUIRE_CERT Option=%s"),
                          tls_req_cert)

        self.conn = ldap.initialize(url)
        self.conn.protocol_version = ldap.VERSION3

        if alias_dereferencing is not None:
            self.conn.set_option(ldap.OPT_DEREF, alias_dereferencing)
        self.page_size = page_size

        if use_tls:
            self.conn.start_tls_s()
Exemple #45
0
    def authenticate(self):
        # ldap.set_option(ldap.OPT_DEBUG_LEVEL, 1)
        ldap.set_option(ldap.OPT_REFERRALS, 0)
        ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 30)

        # the default LDAP protocol version - if not recognized - is v3
        if self.settings['protocol_version'] == '2':
            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION2)
        else:
            if self.settings['protocol_version'] != '3':
                LOG.warning(
                    "Unrecognized Protocol Version '%s', setting to '3'.",
                    self.settings['protocol_version'])
                self.settings['protocol_version'] = '3'
            ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)

        try:
            parsed_url = ldapurl.LDAPUrl(self.settings['url'])
        except ValueError:
            raise AuthenticationError(
                "Invalid url to LDAP service. "
                "Check config examples at https://github.com/Oomnitza."
            )  # FixMe: get new url
        self.ldap_connection = ldap.initialize(parsed_url.unparse())

        cacert_file = self.settings.get('cacert_file', '')
        if cacert_file:
            cacert_file = os.path.abspath(cacert_file)
            if not os.path.isfile(cacert_file):
                raise ConfigError("%s is not a valid file!" % cacert_file)
            LOG.info("Setting CACert File to: %r.", cacert_file)
            ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, cacert_file)
        cacert_dir = self.settings.get('cacert_dir', '')
        if cacert_dir:
            cacert_dir = os.path.abspath(cacert_dir)
            if not os.path.isdir(cacert_dir):
                raise ConfigError("%s is not a valid directory!" % cacert_dir)
            LOG.info("Setting CACert Dir to: %r.", cacert_dir)
            ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, cacert_dir)

        # check for tls
        # if self.settings['enable_tls'] in self.TrueValues and self.settings['protocol_version'] == '3':
        if self.settings.get('verify_ssl', True) in TrueValues:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
        else:
            LOG.info(
                "ldap.verify_ssl = '%s' so SSL certificate validation has been disabled.",
                self.settings.get('verify_ssl', True))
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)

        try:
            if self.settings['username'].lower() == 'anonymous':
                self.ldap_connection.simple_bind_s()
            else:
                password = self.settings['password']
                if not password:
                    LOG.warning(
                        "No password set for LDAP. Connecting without password."
                    )
                    password = u""

                self.ldap_connection.simple_bind_s(self.settings['username'],
                                                   password)
        except ldap.INVALID_CREDENTIALS:
            LOG.exception("Error calling simple_bind_s()")
            raise AuthenticationError(
                "Cannot connect to the LDAP server with given credentials. "
                "Check the 'username', 'password' and 'dn' options "
                "in the config file in the '[ldap]' section.")
        except ldap.UNWILLING_TO_PERFORM as exp:
            LOG.exception("Error calling simple_bind_s()")
            raise AuthenticationError(
                "Cannot connect to the LDAP server with given credentials: " +
                exp.args[0]['info'])
Exemple #46
0
    def __init__(self, ldap_config, who=None, cred=None):
        """
        Initialize an ldap connection object and bind to the configured
        LDAP server.
        None if initialization failed.
        """

        ldap_server = ldap_config.get('connection_url')
        if ldap_server is None:
            LOG.error('Server address is missing from the configuration')
            self.connection = None
            return

        referrals = ldap_config.get('referrals', False)
        ldap.set_option(ldap.OPT_REFERRALS, 1 if referrals else 0)

        deref = ldap_config.get('deref', ldap.DEREF_ALWAYS)
        if deref == 'never':
            deref = ldap.DEREF_NEVER
        else:
            deref = ldap.DEREF_ALWAYS

        ldap.set_option(ldap.OPT_DEREF, deref)

        ldap.protocol_version = ldap.VERSION3

        # Verify certificate in LDAPS connections
        tls_require_cert = ldap_config.get('tls_require_cert', '')
        if tls_require_cert.lower() == 'never':
            LOG.debug("Insecure LDAPS connection because of "
                      "tls_require_cert=='never'")
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

        self.connection = ldap.initialize(ldap_server, bytes_mode=False)

        LOG.debug('Binding to LDAP server with user: %s', who if who else '')

        res = None
        with ldap_error_handler():
            if who is None or cred is None:
                LOG.debug("Anonymous bind with no credentials.")
                res = self.connection.simple_bind_s()
                LOG.debug(res)
            else:
                LOG.debug("Binding with credential: %s", who)
                res = self.connection.simple_bind_s(who, cred)
                whoami = self.connection.whoami_s()
                LOG.debug(res)
                LOG.debug(whoami)

                # mail.python.org/pipermail/python-ldap/2012q4/003180.html
                if whoami is None:
                    # If LDAP server allows anonymous binds, simple bind
                    # does not throw an exception when the password is
                    # empty and does the binding as anonymous.
                    # This is an expected behaviour as per LDAP RFC.

                    # However, if the bind is successful but no
                    # authentication has been done, it is still to be
                    # considered an error from the user's perspective.
                    LOG.debug("Anonymous bind succeeded but no valid "
                              "password was given.")
                    raise ldap.INVALID_CREDENTIALS()

        if not res:
            LOG.debug("Server bind failed.")
            if self.connection is not None:
                self.connection.unbind()
            self.connection = None
    def authenticate(self, username=None, password=None):

        # Check if ldap server is set
        if settings.AUTH_LDAP_SERVER_URI is None:
            self.logger.error('AUTH_LDAP_SERVER_URI not defined in settings!')
            raise Exception("AUTH_LDAP_SERVER_URI not defined in settings!")

        self.logger.info('Authenticate user %s in AD/LDAP %s' %
                         (username, settings.AUTH_LDAP_SERVER_URI))

        # Check if authentication should trust all AD certificates
        if settings.AUTH_LDAP_TRUST_ALL_CERTIFICATES:
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)

        ldap_connection = ldap.initialize(settings.AUTH_LDAP_SERVER_URI)
        # https://stackoverflow.com/questions/18793040/python-ldap-not-able-to-bind-successfully
        ldap_connection.set_option(ldap.OPT_REFERRALS, 0)

        # Check if domain is already at the end of the username
        try:
            if str(username).lower().endswith(
                    str(settings.AUTH_LDAP_USER_DOMAIN).lower()):
                username_ldap_bind = username
            else:
                username_ldap_bind = "%s@%s" % (username,
                                                settings.AUTH_LDAP_USER_DOMAIN)
                self.logger.debug(
                    'Domain %s is not part of the given username %s, add it to bind to ldap: %s'
                    % (settings.AUTH_LDAP_USER_DOMAIN, username,
                       username_ldap_bind))
        except Exception as ex:
            self.logger.warn(
                'AUTH_LDAP_USER_DOMAIN not defined in django settings. Do not append domain to username for ldap authentication'
            )
            username_ldap_bind = username

        # Bind to ldap
        ##############
        try:
            self.__ldap_bind(ldap_connection=ldap_connection,
                             username=username_ldap_bind,
                             password=password)
        except Exception as ex:
            self.logger.error(
                'Could not bind to ldap (%s) as user %s. User therefore not authenticated.'
                % (settings.AUTH_LDAP_SERVER_URI, username_ldap_bind))
            self.logger.info('Bind exception message: %s' % ex.message)
            self.logger.debug(ex)
            return None

        # Check if AUTH_LDAP_USER_SEARCH is a list
        if not isinstance(
                settings.AUTH_LDAP_USER_SEARCH,
            (list, tuple)):  # Check if it is a list, otherwise convert to list
            self.logger.debug(
                'Given setting for AUTH_LDAP_USER_SEARCH is not a list (%s), convert it to a list.'
                % type(settings.AUTH_LDAP_USER_SEARCH))
            settings.AUTH_LDAP_USER_SEARCH = (
                settings.AUTH_LDAP_USER_SEARCH,
            )  # trailing comma: https://wiki.python.org/moin/TupleSyntax

        # Get Ldap User Object from ldap_base
        ldap_user_fields = None
        base_dn = None
        for ldap_base in settings.AUTH_LDAP_USER_SEARCH:
            ldap_user_fields = self.__get_user_from_ldap(ldap_connection,
                                                         username,
                                                         ldap_base=ldap_base)
            if ldap_user_fields is None:
                self.logger.info(
                    'Could not get ldap user with username %s in base_dn %s.' %
                    (username, ldap_base))
            else:
                self.logger.debug('User %s from ldap in base_dn %s received.' %
                                  (username, ldap_base))
                base_dn = ldap_base
                break

        if ldap_user_fields is None:
            self.logger.error(
                'Could not get ldap user with username %s in any of the configured AUTH_LDAP_USER_SEARCH. User therefore not authorized!'
                % username)
            return None

        try:
            ldap_username = ldap_user_fields[
                settings.AUTH_LDAP_USER_ATTR_MAP['username']][0]
            self.logger.debug('Username of %s in ldap: %s' %
                              (username, ldap_username))
        except NameError as ne:
            self.logger.warn(
                'Could not get username from ldap fields for user %s: %s' %
                (username, ne.message))
            self.logger.debug(
                'Probably AUTH_LDAP_USER_ATTR_MAP["username"] in settings not defined, use normal username %s as ldap_username.'
                % username)
            ldap_username = username

        # Django username, may have a prefix (AUTH_LDAP_USER_PREFIX) compared to login
        try:
            username_django = '%s%s' % (settings.AUTH_LDAP_USER_PREFIX,
                                        ldap_username)
        except NameError:
            username_django = ldap_username
        self.logger.debug('Username of %s in django: %s' %
                          (ldap_username, username_django))

        # Get fields for django user from ldap
        ######################################
        # first_name
        try:
            first_name = ldap_user_fields[
                settings.AUTH_LDAP_USER_ATTR_MAP['first_name']][0]
        except Exception as ex:
            self.logger.warn(
                'Could not get first_name from ldap fields (several reasons: ldap field not set, AUTH_LDAP_USER_ATTR_MAP for first_name): %s'
                % ex.message)
            first_name = None
        #  last_name
        try:
            last_name = ldap_user_fields[
                settings.AUTH_LDAP_USER_ATTR_MAP['last_name']][0]
        except Exception as ex:
            self.logger.warn(
                'Could not get last_name from ldap fields (several reasons: ldap field not set, AUTH_LDAP_USER_ATTR_MAP for last_name): %s'
                % ex.message)
            last_name = None
        # Email
        try:
            email = ldap_user_fields[
                settings.AUTH_LDAP_USER_ATTR_MAP['email']][0]
        except Exception as ex:
            self.logger.warn(
                'Could not get last_name from ldap fields (several reasons: ldap field not set, AUTH_LDAP_USER_ATTR_MAP for email): %s'
                % ex.message)
            email = None

        # Get/Create django user
        ########################
        django_user = self.__get_or_create_django_user(username_django,
                                                       first_name=first_name,
                                                       last_name=last_name,
                                                       email=email)
        # Reset staff und superuser fields at login
        django_user.is_staff = False
        django_user.is_superuser = False

        # User Profile (level: GA/RW/RO/SO)
        ###################################
        user_profile = None
        # GA = Global Admin
        #------------------
        user_profile_groups = None
        try:  # Check if setting exist
            user_profile_groups = settings.AUTH_LDAP_USER_PROFILE['GA']
        except Exception as ex:
            self.logger.warn(
                'Could not get ldap group(s) of user profile GA in setting AUTH_LDAP_USER_PROFILE.'
            )

        if user_profile_groups is not None:
            if not isinstance(
                    user_profile_groups,
                (list,
                 tuple)):  # Check if it is a list, otherwise convert to list
                self.logger.debug(
                    'Given setting for user profile "GA" is not a list (%s), convert it to a list.'
                    % type(user_profile_groups))
                user_profile_groups = (
                    user_profile_groups,
                )  # trailing comma: https://wiki.python.org/moin/TupleSyntax

            for group in user_profile_groups:
                if self.__is_user_member_of_ldap_group(
                        ldap_connection=ldap_connection,
                        username=ldap_username,
                        group_dn=group,
                        ldap_base=base_dn):
                    self.logger.debug('User %s is member of GA group %s' %
                                      (ldap_username, group))
                    self.__set_userprofile(username_django, 'GA')
                    user_profile = 'GA'
                    self.logger.debug(
                        'Set django user %s field "is_staff" to True.')
                    django_user.is_staff = True
                    django_user.save()
                    self.logger.debug(
                        'User profile to "GA" = Global Admin set. Do not check for other profiles anymore.'
                    )
                    break
            if user_profile is None:
                self.logger.debug('User %s is not part of any GA group.' %
                                  ldap_username)
        else:
            self.logger.debug(
                'No ldap group for user profile "GA" defined in settings.')

        # RW = Read & Write
        #------------------
        user_profile_groups = None  # temporary variable with ldap groups
        try:  # Check if setting exist
            user_profile_groups = settings.AUTH_LDAP_USER_PROFILE['RW']
        except Exception as ex:
            self.logger.warn(
                'Could not get ldap group(s) of user profile RW in setting AUTH_LDAP_USER_PROFILE.'
            )

        if user_profile_groups is not None and user_profile is None:
            if not isinstance(
                    user_profile_groups,
                (list,
                 tuple)):  # Check if it is a list, otherwise convert to list
                self.logger.debug(
                    'Given setting for user profile "RW" is not a list (%s), convert it to a list.'
                    % type(user_profile_groups))
                user_profile_groups = (
                    user_profile_groups,
                )  # trailing comma: https://wiki.python.org/moin/TupleSyntax

            for group in user_profile_groups:
                if self.__is_user_member_of_ldap_group(
                        ldap_connection=ldap_connection,
                        username=ldap_username,
                        group_dn=group,
                        ldap_base=base_dn):
                    self.logger.debug('User %s is member of RW group %s' %
                                      (ldap_username, group))
                    self.__set_userprofile(username_django, 'RW')
                    user_profile = 'RW'
                    self.logger.debug(
                        'User profile to "RW" = "Read Write" set. Do not check for other profiles anymore.'
                    )
                    break
            if user_profile is None:
                self.logger.debug('User %s is not part of any RW group.' %
                                  ldap_username)
        else:
            self.logger.debug(
                'No ldap group for user profile "RW" defined in settings OR user profile already set to GA.'
            )

        # RO = Read Only
        #---------------
        user_profile_groups = None  # temporary variable with ldap groups
        try:  # Check if setting exist
            user_profile_groups = settings.AUTH_LDAP_USER_PROFILE['RO']
        except Exception as ex:
            self.logger.warn(
                'Could not get ldap group(s) of user profile RO in setting AUTH_LDAP_USER_PROFILE.'
            )

        if user_profile_groups is not None and user_profile is None:
            if not isinstance(
                    user_profile_groups,
                (list,
                 tuple)):  # Check if it is a list, otherwise convert to list
                self.logger.debug(
                    'Given setting for user profile "RO" is not a list (%s), convert it to a list.'
                    % type(user_profile_groups))
                user_profile_groups = (
                    user_profile_groups,
                )  # trailing comma: https://wiki.python.org/moin/TupleSyntax

            for group in user_profile_groups:
                if self.__is_user_member_of_ldap_group(
                        ldap_connection=ldap_connection,
                        username=ldap_username,
                        group_dn=group,
                        ldap_base=base_dn):
                    self.logger.debug('User %s is member of RO group %s' %
                                      (ldap_username, group))
                    self.__set_userprofile(username_django, 'RO')
                    user_profile = 'RO'
                    self.logger.debug(
                        'User profile to "RO" = "Read Only" set. Do not check for other profiles anymore.'
                    )
                    break
            if user_profile is None:
                self.logger.debug('User %s is not part of any RO group.' %
                                  ldap_username)
        else:
            self.logger.debug(
                'No ldap group for user profile "RO" defined in settings OR user profile already set to GA or RW.'
            )

        # SO = Stats Only (not implemented (yet?) in SAL)
        #------------------------------------------------
        user_profile_groups = None  # temporary variable with ldap groups
        try:  # Check if setting exist
            user_profile_groups = settings.AUTH_LDAP_USER_PROFILE['SO']
        except Exception as ex:
            self.logger.warn(
                'Could not get ldap group(s) of user profile SO in setting AUTH_LDAP_USER_PROFILE.'
            )

        if user_profile_groups is not None and user_profile is None:
            if not isinstance(
                    user_profile_groups,
                (list,
                 tuple)):  # Check if it is a list, otherwise convert to list
                self.logger.debug(
                    'Given setting for user profile "SO" is not a list (%s), convert it to a list.'
                    % type(user_profile_groups))
                user_profile_groups = (
                    user_profile_groups,
                )  # trailing comma: https://wiki.python.org/moin/TupleSyntax

            for group in user_profile_groups:
                if self.__is_user_member_of_ldap_group(
                        ldap_connection=ldap_connection,
                        username=ldap_username,
                        group_dn=group,
                        ldap_base=base_dn):
                    self.logger.debug('User %s is member of SO group %s' %
                                      (ldap_username, group))
                    self.__set_userprofile(username_django, 'SO')
                    user_profile = 'SO'
                    self.logger.debug(
                        'User profile to "SO" = "Stats Only" set. Do not check for other profiles anymore.'
                    )
                    break
            if user_profile is None:
                self.logger.debug('User %s is not part of any SO group.')
        else:
            self.logger.debug(
                'No ldap group for user profile "SO" defined in settings OR user profile already set to GA, RW or RO.'
            )

        # If the user does not exist in any of the given AUTH_LDAP_USER_PROFILE groups, set to default UserProfile level
        if user_profile is None:
            self.logger.warn(
                'User %s authenticated in AD/LDAP, but not part of any configured GA/RW/RO/SO group. Set to %s.'
                % (django_user,
                   UserProfile._meta.get_field('level').get_default()))
            self.__set_userprofile(
                username_django,
                '%s' % UserProfile._meta.get_field('level').get_default())
            user_profile = UserProfile._meta.get_field('level').get_default()

        # Business Units
        ################
        # remove from all existing Business units, before assigne to new business units.
        self.logger.debug(
            'Remove all business units of %s, assign the configured ones afterwards.'
            % username_django)
        for business_unit in self.__get_business_units(
                username=username_django):
            self.logger.debug('Remove business unit "%s" from user %s.' %
                              (business_unit, username_django))
            self.__remove_user_from_business_unit(username_django,
                                                  business_unit)

        # assign Business units
        self.logger.debug('Get all existing business units.')
        all_business_units = self.__get_business_units()
        user_business_units = []  # business units of user.
        business_units_settings = None  # Configured Business units in the settings
        try:
            business_units_settings = settings.AUTH_LDAP_USER_TO_BUSINESS_UNIT.keys(
            )
        except Exception as ex:
            self.logger.debug(
                'AUTH_LDAP_USER_TO_BUSINESS_UNIT not configured in settings as dictionary.'
            )

        if business_units_settings is not None and user_profile != 'GA':  # GA (Global Admin does not need assigned business units)
            for business_unit in business_units_settings:
                # Handle all business units for key #ALL_BU
                if business_unit == '#ALL_BU':  # Special case: users in the group #ALL_BU get access to all Business units.
                    self.logger.debug(
                        'Check if user %s has access to all business units ("%s").'
                        % (ldap_username, business_unit))
                    if not isinstance(
                            settings.
                            AUTH_LDAP_USER_TO_BUSINESS_UNIT[business_unit],
                        (list, tuple)
                    ):  # Check if it is a list, otherwise convert to list
                        self.logger.debug(
                            'Given setting for business unit "%s" is not a list, convert it to a list.'
                            % business_unit)
                        # trailing comma: https://wiki.python.org/moin/TupleSyntax
                        settings.AUTH_LDAP_USER_TO_BUSINESS_UNIT[
                            business_unit] = (
                                settings.
                                AUTH_LDAP_USER_TO_BUSINESS_UNIT[business_unit],
                            )
                    for group in settings.AUTH_LDAP_USER_TO_BUSINESS_UNIT[
                            business_unit]:  # Loop over groups
                        self.logger.debug(
                            'Check if user %s is in ldap group %s.' %
                            (ldap_username, group))
                        if self.__is_user_member_of_ldap_group(
                                ldap_connection=ldap_connection,
                                username=ldap_username,
                                group_dn=group,
                                ldap_base=base_dn):
                            self.logger.debug(
                                'User %s is member of group %s, assign user to all existing business units!'
                                % (ldap_username, group))
                            for one_of_all_business_units in all_business_units:
                                self.logger.debug(
                                    'Assign business unit %s to user %s with access to all existing business units.'
                                    % (one_of_all_business_units,
                                       username_django))
                                self.__add_user_to_business_unit(
                                    username_django, one_of_all_business_units
                                )  # Assign user to business unit
                                user_business_units.append(
                                    one_of_all_business_units)
                            break
                        else:
                            self.logger.debug(
                                'User %s is NOT member of group %s.' %
                                (ldap_username, group))
                # Check if business unit is an existing one
                elif business_unit in all_business_units:
                    if not isinstance(
                            settings.
                            AUTH_LDAP_USER_TO_BUSINESS_UNIT[business_unit],
                        (list, tuple)
                    ):  # Check if it is a list, otherwise convert to list
                        self.logger.debug(
                            'Given setting for business unit "%s" is not a list, convert it to a list.'
                            % business_unit)
                        # trailing comma: https://wiki.python.org/moin/TupleSyntax
                        settings.AUTH_LDAP_USER_TO_BUSINESS_UNIT[
                            business_unit] = (
                                settings.
                                AUTH_LDAP_USER_TO_BUSINESS_UNIT[business_unit],
                            )
                    for group in settings.AUTH_LDAP_USER_TO_BUSINESS_UNIT[
                            business_unit]:  # Loop over groups
                        self.logger.debug(
                            'Check if user %s is in ldap group %s.' %
                            (ldap_username, group))
                        if self.__is_user_member_of_ldap_group(
                                ldap_connection=ldap_connection,
                                username=ldap_username,
                                group_dn=group,
                                ldap_base=base_dn):
                            self.logger.debug(
                                'User %s is member of group %s, assign user to business unit %s'
                                % (ldap_username, group, business_unit))
                            self.__add_user_to_business_unit(
                                username_django,
                                business_unit)  # Assign user to business unit
                            user_business_units.append(business_unit)
                            break
                        else:
                            self.logger.debug(
                                'User %s is NOT member of group %s.' %
                                (ldap_username, group))
                else:
                    self.logger.warn(
                        'Business unit in settings (AUTH_LDAP_USER_TO_BUSINESS_UNIT) %s does not exist in existing SAL business units (%s)'
                        % (business_unit, ''.join(all_business_units)))
        elif user_profile == 'GA':
            self.logger.debug(
                'User %s has user profile GA (Global Admin), therefore not necessary to assign business units to the user.'
                % username_django)
        elif business_units_settings is None:
            self.logger.debug(
                'AUTH_LDAP_USER_TO_BUSINESS_UNIT not correct configured in settings, therefore not possible to assign business units to user %s.'
                % username_django)

        self.logger.info(
            'Everything fine! Found user with username "%s" in ldap. User has user profile "%s" and access to following business units: %s'
            % (username, user_profile, ', '.join(user_business_units)))
        django_user.save()
        return django_user
Exemple #48
0
    def ipacheckldap(self, thost, trealm, ca_cert_path=None):
        """
        Given a host and kerberos realm verify that it is an IPA LDAP
        server hosting the realm.

        Returns a list [errno, host, realm] or an empty list on error.
        Errno is an error number:
            0 means all ok
            1 means we could not check the info in LDAP (may happend when
                anonymous binds are disabled)
            2 means the server is certainly not an IPA server
        """

        lrealms = []

        i = 0

        #now verify the server is really an IPA server
        try:
            ldap_url = "ldap://" + format_netloc(thost, 389)
            root_logger.debug("Init LDAP connection with: %s", ldap_url)
            lh = ldap.initialize(ldap_url)
            if ca_cert_path:
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, True)
                ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, ca_cert_path)
                lh.set_option(ldap.OPT_X_TLS_DEMAND, True)
                lh.start_tls_s()
            lh.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
            lh.simple_bind_s("", "")

            # get IPA base DN
            root_logger.debug("Search LDAP server for IPA base DN")
            basedn = get_ipa_basedn(lh)

            if basedn is None:
                root_logger.debug("The server is not an IPA server")
                return [NOT_IPA_SERVER]

            self.basedn = basedn
            self.basedn_source = 'From IPA server %s' % ldap_url

            #search and return known realms
            root_logger.debug(
                "Search for (objectClass=krbRealmContainer) in %s (sub)",
                self.basedn)
            lret = lh.search_s(str(DN(('cn', 'kerberos'),
                                      self.basedn)), ldap.SCOPE_SUBTREE,
                               "(objectClass=krbRealmContainer)")
            if not lret:
                #something very wrong
                return [REALM_NOT_FOUND]

            for lres in lret:
                root_logger.debug("Found: %s", lres[0])
                for lattr in lres[1]:
                    if lattr.lower() == "cn":
                        lrealms.append(lres[1][lattr][0])

            if trealm:
                for r in lrealms:
                    if trealm == r:
                        return [0, thost, trealm]
                # must match or something is very wrong
                return [REALM_NOT_FOUND]
            else:
                if len(lrealms) != 1:
                    #which one? we can't attach to a multi-realm server without DNS working
                    return [REALM_NOT_FOUND]
                else:
                    return [0, thost, lrealms[0]]

            #we shouldn't get here
            return [UNKNOWN_ERROR]

        except LDAPError, err:
            if isinstance(err, ldap.TIMEOUT):
                root_logger.debug("LDAP Error: timeout")
                return [NO_LDAP_SERVER]

            if isinstance(err, ldap.SERVER_DOWN):
                root_logger.debug("LDAP Error: server down")
                return [NO_LDAP_SERVER]

            if isinstance(err, ldap.INAPPROPRIATE_AUTH):
                root_logger.debug("LDAP Error: Anonymous access not allowed")
                return [NO_ACCESS_TO_LDAP]

            # We should only get UNWILLING_TO_PERFORM if the remote LDAP server
            # has minssf > 0 and we have attempted a non-TLS connection.
            if ca_cert_path is None and isinstance(err,
                                                   ldap.UNWILLING_TO_PERFORM):
                root_logger.debug(
                    "LDAP server returned UNWILLING_TO_PERFORM. This likely means that minssf is enabled"
                )
                return [NO_TLS_LDAP]

            root_logger.error(
                "LDAP Error: %s: %s" %
                (err.args[0]['desc'], err.args[0].get('info', '')))
            return [UNKNOWN_ERROR]
        def authenticate(self,
                         name,
                         pw,
                         certlist,
                         certhash,
                         strong,
                         current=None):
            """
            This function is called to authenticate a user
            """

            # Search for the user in the database
            FALL_THROUGH = -2
            AUTH_REFUSED = -1

            # SuperUser is a special login.
            if name == "SuperUser":
                debug("Forced fall through for SuperUser")
                return (FALL_THROUGH, None, None)

            # Otherwise, let's check the LDAP server.
            uid = None

            if cfg.ldap.use_start_tls:
                # try StartTLS: global options
                debug(
                    "use_start_tls is set, setting global option TLS_REQCERT = never"
                )
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,
                                ldap.OPT_X_TLS_NEVER)

            ldap_trace = 0  # Change to 1 for more verbose trace
            ldap_conn = ldap.initialize(cfg.ldap.ldap_uri, ldap_trace)

            if cfg.ldap.use_start_tls:
                # try StartTLS: connection specific options
                debug(
                    "use_start_tls is set, setting connection options X_TLS_*")
                ldap_conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
                ldap_conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
                ldap_conn.set_option(ldap.OPT_X_TLS_DEMAND, True)
                try:
                    ldap_conn.start_tls_s()
                except Exception as e:
                    warning("could not initiate StartTLS, e = " + str(e))
                    return (AUTH_REFUSED, None, None)

            if cfg.ldap.bind_dn:
                # Bind the functional account to search the directory.
                bind_dn = cfg.ldap.bind_dn
                bind_pass = cfg.ldap.bind_pass
                try:
                    debug("try to connect to ldap (bind_dn will be used)")
                    ldap_conn.bind_s(bind_dn, bind_pass)
                except ldap.INVALID_CREDENTIALS:
                    ldap_conn.unbind()
                    warning("Invalid credentials for bind_dn=" + bind_dn)
                    return (AUTH_REFUSED, None, None)
            elif cfg.ldap.discover_dn:
                # Use anonymous bind to discover the DN
                try:
                    ldap_conn.bind_s()
                except ldap.INVALID_CREDENTIALS:
                    ldap_conn.unbind()
                    warning("Failed anomymous bind for discovering DN")
                    return (AUTH_REFUSED, None, None)

            else:
                # Prevent anonymous authentication.
                if not pw:
                    warning("No password supplied for user " + name)
                    return (AUTH_REFUSED, None, None)

                # Bind the user account to search the directory.
                bind_dn = "%s=%s,%s" % (cfg.ldap.username_attr, name,
                                        cfg.ldap.users_dn)
                bind_pass = pw
                try:
                    ldap_conn.bind_s(bind_dn, bind_pass)
                except ldap.INVALID_CREDENTIALS:
                    ldap_conn.unbind()
                    warning("User " + name +
                            " failed with invalid credentials")
                    return (AUTH_REFUSED, None, None)

            # Search for the user.
            res = ldap_conn.search_s(
                cfg.ldap.users_dn,
                ldap.SCOPE_SUBTREE,
                "(%s=%s)" % (cfg.ldap.username_attr, name),
                [cfg.ldap.number_attr, cfg.ldap.display_attr],
            )
            if len(res) == 0:
                warning("User " + name + " not found")
                if cfg.user.reject_on_miss:
                    return (AUTH_REFUSED, None, None)
                else:
                    return (FALL_THROUGH, None, None)
            match = res[
                0]  # Only interested in the first result, as there should only be one match

            # Parse the user information.
            uid = self.getMumbleID(match[1][cfg.ldap.number_attr][0])
            displayName = match[1][cfg.ldap.display_attr][0].decode("UTF-8")
            user_dn = match[0]
            debug("User match found, display '" + displayName + "' with UID " +
                  repr(uid))

            # Optionally check groups.
            if cfg.ldap.group_cn != "":
                debug("Checking group membership for " + name)

                # Search for user in group
                res = ldap_conn.search_s(
                    cfg.ldap.group_cn,
                    ldap.SCOPE_SUBTREE,
                    "(%s=%s)" % (cfg.ldap.group_attr, user_dn),
                    [cfg.ldap.number_attr, cfg.ldap.display_attr],
                )

                # Check if the user is a member of the group
                if len(res) < 1:
                    debug("User " + name + " failed with no group membership")
                    return (AUTH_REFUSED, None, None)

            # Second bind to test user credentials if using bind_dn or discover_dn.
            if cfg.ldap.bind_dn or cfg.ldap.discover_dn:
                # Prevent anonymous authentication.
                if not pw:
                    warning("No password supplied for user " + name)
                    return (AUTH_REFUSED, None, None)

                bind_dn = user_dn
                bind_pass = pw
                try:
                    ldap_conn.bind_s(bind_dn, bind_pass)
                except ldap.INVALID_CREDENTIALS:
                    ldap_conn.unbind()
                    warning("User " + name + " failed with wrong password")
                    return (AUTH_REFUSED, None, None)

            # Unbind and close connection.
            ldap_conn.unbind()

            # If we get here, the login is correct.
            # Add the user/id combo to cache, then accept:
            self.name_uid_cache[displayName] = uid
            debug("Login accepted for " + name)
            return (uid + cfg.user.id_offset, displayName, [])
 def _connect(self):
     """Initialize an ldap client"""
     ldap_client = ldap.initialize(self.uri)
     ldap.set_option(ldap.OPT_REFERRALS, 0)
     ldap.set_option(ldap.OPT_TIMEOUT, self.timeout)
     if self.starttls == 'on':
         ldap.set_option(ldap.OPT_X_TLS_DEMAND, True)
     else:
         ldap.set_option(ldap.OPT_X_TLS_DEMAND, False)
     # set the CA file if declared and if necessary
     if self.ca and self.checkcert == 'on':
         # check if the CA file actually exists
         if os.path.isfile(self.ca):
             ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.ca)
         else:
             raise CaFileDontExist(self.ca)
     if self.checkcert == 'off':
         # this is dark magic
         # remove any of these two lines and it doesn't work
         ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
         ldap_client.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,
                                ldap.OPT_X_TLS_NEVER)
     else:
         # this is even darker magic
         ldap_client.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,
                                ldap.OPT_X_TLS_DEMAND)
         # it doesn't make sense to set it to never
         # (== don't check certifate)
         # but it only works with this option...
         # ... and it checks the certificat
         # (I've lost my sanity over this)
         ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
     if self.starttls == 'on':
         try:
             ldap_client.start_tls_s()
         except Exception as e:
             self._exception_handler(e)
     return ldap_client
Exemple #51
0
def login():
    # Allow LDAP server to use a self signed certificate
    if current_app.config['LDAP_ALLOW_SELF_SIGNED_CERT']:
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)

    # Retrieve required fields from client request
    try:
        login = request.json.get('username', None) or request.json['email']
        password = request.json['password']
    except KeyError:
        raise ApiError("must supply 'username' and 'password'", 401)

    if '\\' in login:
        domain, username = login.split('\\')
        email = ''
        email_verified = False
    else:
        username, domain = login.split('@')
        email = login
        email_verified = True

    # Validate LDAP domain
    if domain not in current_app.config['LDAP_DOMAINS']:
        raise ApiError('unauthorized domain', 403)

    userdn = current_app.config['LDAP_DOMAINS'][domain] % username

    # Attempt LDAP AUTH
    try:
        trace_level = 2 if current_app.debug else 0
        ldap_connection = ldap.initialize(current_app.config['LDAP_URL'],
                                          trace_level=trace_level)
        ldap_connection.simple_bind_s(userdn, password)
    except ldap.INVALID_CREDENTIALS:
        raise ApiError('invalid username or password', 401)
    except Exception as e:
        raise ApiError(str(e), 500)

    # Get email address from LDAP
    if not email_verified:
        try:
            ldap_result = ldap_connection.search_s(userdn, ldap.SCOPE_SUBTREE,
                                                   '(objectClass=*)', ['mail'])
            email = ldap_result[0][1]['mail'][0].decode(sys.stdout.encoding)
            email_verified = True
        except:
            email = '{}@{}'.format(username, domain)

    # Create user if not yet there
    user = User.find_by_username(username=login)
    if not user:
        user = User(name=username,
                    login=login,
                    password='',
                    email=email,
                    roles=[],
                    text='LDAP user',
                    email_verified=email_verified)
        try:
            user = user.create()
        except Exception as e:
            ApiError(str(e), 500)

    # Assign customers & update last login time
    groups = list()
    try:
        groups_filters = current_app.config.get('LDAP_DOMAINS_GROUP', {})
        base_dns = current_app.config.get('LDAP_DOMAINS_BASEDN', {})
        if domain in groups_filters and domain in base_dns:
            resultID = ldap_connection.search(
                base_dns[domain], ldap.SCOPE_SUBTREE,
                groups_filters[domain].format(username=username,
                                              email=email,
                                              userdn=userdn), ['cn'])
            resultTypes, results = ldap_connection.result(resultID)
            for _dn, attributes in results:
                groups.append(attributes['cn'][0].decode('utf-8'))
    except ldap.LDAPError as e:
        raise ApiError(str(e), 500)

    # Check user is active
    if user.status != 'active':
        raise ApiError('User {} not active'.format(login), 403)
    user.update_last_login()

    scopes = Permission.lookup(login=login, roles=user.roles + groups)
    customers = get_customers(login=login, groups=[user.domain] + groups)

    auth_audit_trail.send(current_app._get_current_object(),
                          event='basic-ldap-login',
                          message='user login via LDAP',
                          user=login,
                          customers=customers,
                          scopes=scopes,
                          resource_id=user.id,
                          type='user',
                          request=request)

    # Generate token
    token = create_token(user_id=user.id,
                         name=user.name,
                         login=user.email,
                         provider='ldap',
                         customers=customers,
                         scopes=scopes,
                         roles=user.roles,
                         email=user.email,
                         email_verified=user.email_verified)
    return jsonify(token=token.tokenize)
LDAP_ENABLED = os.getenv('DBAAS_LDAP_ENABLED', '0')
if LDAP_ENABLED == "1":
    LDAP_ENABLED = True
else:
    LDAP_ENABLED = False

LDAP_CERTDIR = os.getenv('DBAAS_LDAP_CERTDIR', '')
LDAP_CACERTFILE = os.getenv('DBAAS_LDAP_CACERTFILE', '')
LDAP_CERTFILE = os.getenv('DBAAS_LDAP_CERTFILE', '')
LDAP_KEYFILE = os.getenv('DBAAS_LDAP_KEYFILE', '')

if LDAP_ENABLED:
    import ldap
    from django_auth_ldap.config import LDAPSearch, GroupOfNamesType

    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, LDAP_CERTDIR + LDAP_CACERTFILE)
    ldap.set_option(ldap.OPT_X_TLS_CERTFILE, LDAP_CERTDIR + LDAP_CERTFILE)
    ldap.set_option(ldap.OPT_X_TLS_KEYFILE, LDAP_CERTDIR + LDAP_KEYFILE)

    # Baseline configuration.
    AUTH_LDAP_SERVER_URI = os.getenv('AUTH_LDAP_SERVER_URI', '')

    AUTH_LDAP_BIND_DN = os.getenv('AUTH_LDAP_BIND_DN', '')
    AUTH_LDAP_BIND_PASSWORD = os.getenv('AUTH_LDAP_BIND_PASSWORD', '')
    AUTH_LDAP_USER_SEARCH_STR = os.getenv('AUTH_LDAP_USER_SEARCH', '')
    AUTH_LDAP_USER_SEARCH = LDAPSearch(
        AUTH_LDAP_USER_SEARCH_STR, ldap.SCOPE_SUBTREE,
        "(&(uid=%(user)s)(!(nsaccountlock=TRUE)))")
    AUTH_LDAP_GROUP_SEARCH_STR = os.getenv('AUTH_LDAP_GROUP_SEARCH', '')
    AUTH_LDAP_GROUP_SEARCH = LDAPSearch(AUTH_LDAP_GROUP_SEARCH_STR,
                                        ldap.SCOPE_SUBTREE,
Exemple #53
0
def login():

    try:
        login = request.json.get('username') or request.json['email']
        password = request.json['password']
    except KeyError:
        raise ApiError("must supply 'username' and 'password'", 401)

    if not password:
        raise ApiError('password not allowed to be empty', 401)

    try:
        if '\\' in login:
            domain, username = login.split('\\')
        else:
            username, domain = login.split('@')
    except ValueError:
        if current_app.config['LDAP_DEFAULT_DOMAIN']:
            username = login
            domain = current_app.config['LDAP_DEFAULT_DOMAIN']
        else:
            raise ApiError('expected username with domain', 401)

    # Validate LDAP domain
    if (domain not in current_app.config['ALLOWED_EMAIL_DOMAINS']
            and domain not in current_app.config['LDAP_DOMAINS']):
        raise ApiError('unauthorized domain', 403)

    # LDAP certificate settings
    if current_app.config['LDAP_CACERT']:
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
        ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,
                        current_app.config['LDAP_CACERT'])

    # Allow LDAP server to use a self-signed certificate
    if current_app.config['LDAP_ALLOW_SELF_SIGNED_CERT']:
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)

    # Set LDAP Timeout:
    if current_app.config['LDAP_QUERY_TIMEOUT_SECONDS']:
        ldap.set_option(ldap.OPT_NETWORK_TIMEOUT,
                        current_app.config['LDAP_QUERY_TIMEOUT_SECONDS'])

    # Initialise ldap connection
    try:
        trace_level = 2 if current_app.debug else 0  # XXX - do not set in production environments
        ldap_connection = ldap.initialize(current_app.config['LDAP_URL'],
                                          trace_level=trace_level)
    except Exception as e:
        raise ApiError(str(e), 500)

    # bind user credentials
    ldap_bind_username = current_app.config['LDAP_BIND_USERNAME']
    ldap_bind_password = current_app.config['LDAP_BIND_PASSWORD']
    if ldap_bind_username:
        try:
            ldap_connection.simple_bind_s(ldap_bind_username,
                                          ldap_bind_password)
        except ldap.INVALID_CREDENTIALS:
            raise ApiError('invalid ldap bind credentials', 500)

    # Set default base DN for user and group search
    base_dn = current_app.config['LDAP_BASEDN']

    # If user search filter exist
    #   Search the user using the provided User Search filter for the current domain
    #   If one user is found
    #       Set the DN as the one found
    #       Set email retreived from AD
    #   If more than one user is found
    #       Except: Search query is bad defined
    # Else
    #   Set the DN as the one found in LDAP_DOMAINS variable
    user_filter = current_app.config['LDAP_USER_FILTER']
    user_base_dn = current_app.config['LDAP_USER_BASEDN']
    user_attrs = [
        current_app.config['LDAP_USER_NAME_ATTR'],
        current_app.config['LDAP_USER_EMAIL_ATTR']
    ]
    if user_filter:
        result = [
            r for r in ldap_connection.search_s(base=user_base_dn or base_dn,
                                                scope=ldap.SCOPE_SUBTREE,
                                                filterstr=user_filter.format(
                                                    username=username),
                                                attrlist=user_attrs)
            if None not in r
        ]

        if len(result) > 1:
            raise ApiError(
                'invalid search query for domain "{}"'.format(domain), 500)
        elif len(result) == 0:
            raise ApiError('invalid username or password', 401)
        user_dn = result[0][0]
        name = result[0][1][
            current_app.config['LDAP_USER_NAME_ATTR']][0].decode(
                'utf-8', 'ignore')
        email = result[0][1][
            current_app.config['LDAP_USER_EMAIL_ATTR']][0].decode(
                'utf-8', 'ignore')
        email_verified = bool(email)
    else:
        if '%' in current_app.config['LDAP_DOMAINS'][domain]:
            user_dn = current_app.config['LDAP_DOMAINS'][domain] % username
        else:
            user_dn = current_app.config['LDAP_DOMAINS'][domain].format(
                username)
        name = username
        email = '{}@{}'.format(username, domain)
        email_verified = False

    # Authenticate user logging in
    try:
        ldap_connection.simple_bind_s(user_dn, password)
    except ldap.INVALID_CREDENTIALS:
        raise ApiError('invalid username or password', 401)

    login = email or username
    user = User.find_by_username(username=login)
    if not user:
        user = User(name=name,
                    login=login,
                    password='',
                    email=email,
                    roles=current_app.config['USER_ROLES'],
                    text='LDAP user',
                    email_verified=email_verified)
        user = user.create()
    else:
        user.update(login=login, email=email, email_verified=email_verified)

    if ldap_bind_username:
        try:
            ldap_connection.simple_bind_s(ldap_bind_username,
                                          ldap_bind_password)
        except ldap.INVALID_CREDENTIALS:
            raise ApiError('invalid ldap bind credentials', 500)

    # Assign customers & update last login time
    group_filter = current_app.config['LDAP_GROUP_FILTER']
    group_base_dn = current_app.config['LDAP_GROUP_BASEDN']
    groups = list()
    if group_filter:
        result = ldap_connection.search_s(
            base=group_base_dn or base_dn,
            scope=ldap.SCOPE_SUBTREE,
            filterstr=group_filter.format(username=username,
                                          email=email,
                                          userdn=user_dn),
            attrlist=[current_app.config['LDAP_GROUP_NAME_ATTR']])
        for group_dn, group_attrs in result:
            if current_app.config['LDAP_GROUP_NAME_ATTR'] in group_attrs.keys(
            ):
                groups.extend([
                    g.decode('utf-8', 'ignore') for g in group_attrs[
                        current_app.config['LDAP_GROUP_NAME_ATTR']]
                ])
            else:
                groups.append(group_dn)

    # Check user is active
    if user.status != 'active':
        raise ApiError('User {} not active'.format(login), 403)
    if not_authorized('ALLOWED_LDAP_GROUPS', groups):
        raise ApiError('User {} is not authorized'.format(login), 403)
    user.update_last_login()

    scopes = Permission.lookup(login=login, roles=user.roles + groups)
    customers = get_customers(login=login, groups=[user.domain] + groups)

    auth_audit_trail.send(current_app._get_current_object(),
                          event='basic-ldap-login',
                          message='user login via LDAP',
                          user=login,
                          customers=customers,
                          scopes=scopes,
                          roles=user.roles,
                          groups=groups,
                          resource_id=user.id,
                          type='user',
                          request=request)

    # Generate token
    token = create_token(user_id=user.id,
                         name=user.name,
                         login=user.email,
                         provider='ldap',
                         customers=customers,
                         scopes=scopes,
                         roles=user.roles,
                         groups=groups,
                         email=user.email,
                         email_verified=user.email_verified)
    return jsonify(token=token.tokenize)
Exemple #54
0
    def run(self, terms, variables=None, **kwargs):
        if not HAS_LDAP:
            msg = missing_required_lib(
                "python-ldap", url="https://pypi.org/project/python-ldap/")
            msg += ". Import Error: %s" % LDAP_IMP_ERR
            raise AnsibleLookupError(msg)

        # Load the variables and direct args into the lookup options
        self.set_options(var_options=variables, direct=kwargs)
        domain = self.get_option('domain')
        port = self.get_option('port')
        scheme = self.get_option('scheme')
        start_tls = self.get_option('start_tls')
        validate_certs = self.get_option('validate_certs')
        cacert_file = self.get_option('ca_cert')
        search_base = self.get_option('search_base')
        username = self.get_option('username')
        password = self.get_option('password')
        auth = self.get_option('auth')
        allow_plaintext = self.get_option('allow_plaintext')

        # Validate and set input values
        # https://www.openldap.org/lists/openldap-software/200202/msg00456.html
        validate_certs_map = {
            'never': ldap.OPT_X_TLS_NEVER,
            'allow': ldap.OPT_X_TLS_ALLOW,
            'try': ldap.OPT_X_TLS_TRY,
            'demand': ldap.OPT_X_TLS_DEMAND,  # Same as OPT_X_TLS_HARD
        }
        validate_certs_value = validate_certs_map.get(validate_certs, None)
        if validate_certs_value is None:
            valid_keys = list(validate_certs_map.keys())
            valid_keys.sort()
            raise AnsibleLookupError(
                "Invalid validate_certs value '%s': valid values are '%s'" %
                (validate_certs, "', '".join(valid_keys)))

        if auth not in ['gssapi', 'simple']:
            raise AnsibleLookupError(
                "Invalid auth value '%s': expecting either 'gssapi', or 'simple'"
                % auth)
        elif auth == 'gssapi':
            if not ldap.SASL_AVAIL:
                raise AnsibleLookupError(
                    "Cannot use auth=gssapi when SASL is not configured with the local LDAP "
                    "install")
            if username or password:
                raise AnsibleLookupError(
                    "Explicit credentials are not supported when auth='gssapi'. Call kinit "
                    "outside of Ansible")
        elif auth == 'simple' and not (username and password):
            raise AnsibleLookupError(
                "The username and password values are required when auth=simple"
            )

        if ldapurl.isLDAPUrl(domain):
            ldap_url = ldapurl.LDAPUrl(ldapUrl=domain)
        else:
            port = port if port else 389 if scheme == 'ldap' else 636
            ldap_url = ldapurl.LDAPUrl(hostport="%s:%d" % (domain, port),
                                       urlscheme=scheme)

        # We have encryption if using LDAPS, or StartTLS is used, or we auth with SASL/GSSAPI
        encrypted = ldap_url.urlscheme == 'ldaps' or start_tls or auth == 'gssapi'
        if not encrypted and not allow_plaintext:
            raise AnsibleLookupError(
                "Current configuration will result in plaintext traffic exposing credentials. "
                "Set auth=gssapi, scheme=ldaps, start_tls=True, or allow_plaintext=True to "
                "continue")

        if ldap_url.urlscheme == 'ldaps' or start_tls:
            # We cannot use conn.set_option as OPT_X_TLS_NEWCTX (required to use the new context) is not supported on
            # older distros like EL7. Setting it on the ldap object works instead
            if not ldap.TLS_AVAIL:
                raise AnsibleLookupError(
                    "Cannot use TLS as the local LDAP installed has not been configured to support it"
                )

            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, validate_certs_value)
            if cacert_file:
                cacert_path = os.path.expanduser(
                    os.path.expandvars(cacert_file))
                if not os.path.exists(to_bytes(cacert_path)):
                    raise AnsibleLookupError(
                        "The cacert_file specified '%s' does not exist" %
                        to_native(cacert_path))

                try:
                    # While this is a path, python-ldap expects a str/unicode and not bytes
                    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,
                                    to_text(cacert_path))
                except ValueError:
                    # https://keathmilligan.net/python-ldap-and-macos/
                    raise AnsibleLookupError(
                        "Failed to set path to cacert file, this is a known issue with older "
                        "OpenLDAP libraries on the host. Update OpenLDAP and reinstall "
                        "python-ldap to continue")

        conn_url = ldap_url.initializeUrl()
        conn = ldap.initialize(conn_url, bytes_mode=False)
        conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
        conn.set_option(ldap.OPT_REFERRALS,
                        0)  # Allow us to search from the base

        # Make sure we run StartTLS before doing the bind to protect the credentials
        if start_tls:
            try:
                conn.start_tls_s()
            except ldap.LDAPError as err:
                raise AnsibleLookupError(
                    "Failed to send StartTLS to LDAP host '%s': %s" %
                    (conn_url, to_native(err)))

        if auth == 'simple':
            try:
                conn.bind_s(to_text(username), to_text(password))
            except ldap.LDAPError as err:
                raise AnsibleLookupError(
                    "Failed to simple bind against LDAP host '%s': %s" %
                    (conn_url, to_native(err)))
        else:
            try:
                conn.sasl_gssapi_bind_s()
            except ldap.AUTH_UNKNOWN as err:
                # The SASL GSSAPI binding is not installed, e.g. cyrus-sasl-gssapi. Give a better error message than
                # what python-ldap provides
                raise AnsibleLookupError(
                    "Failed to do a sasl bind against LDAP host '%s', the GSSAPI mech is not "
                    "installed: %s" % (conn_url, to_native(err)))
            except ldap.LDAPError as err:
                raise AnsibleLookupError(
                    "Failed to do a sasl bind against LDAP host '%s': %s" %
                    (conn_url, to_native(err)))

        try:
            if not search_base:
                root_dse = conn.read_rootdse_s()
                search_base = root_dse['defaultNamingContext'][0]

            ret = []
            # TODO: change method to search for all servers in 1 request instead of multiple requests
            for server in terms:
                ret.append(get_laps_password(conn, server, search_base))
        finally:
            conn.unbind_s()

        return ret
Exemple #55
0
 def __init__(self, config):
     ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
     self._config = config
     self._conn = None
Exemple #56
0
    def POST(self):
        # Get username, password.
        i = web.input(_unicode=False)

        username = web.safestr(i.get('username', '').strip()).lower()
        password = i.get('password', '').strip()
        save_pass = web.safestr(i.get('save_pass', 'no').strip())

        if not iredutils.is_email(username):
            raise web.seeother('/login?msg=INVALID_USERNAME')

        if not password:
            raise web.seeother('/login?msg=EMPTY_PASSWORD')

        # Get LDAP URI.
        uri = settings.ldap_uri

        # Verify bind_dn & bind_pw.
        try:
            # Detect STARTTLS support.
            if uri.startswith('ldaps://'):
                starttls = True
            else:
                starttls = False

            # Set necessary option for STARTTLS.
            if starttls:
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,
                                ldap.OPT_X_TLS_NEVER)

            # Initialize connection.
            conn = ldap.initialize(uri)

            # Set LDAP protocol version: LDAP v3.
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)

            if starttls:
                conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)

            # synchronous bind.
            conn.bind_s(settings.ldap_bind_dn, settings.ldap_bind_password)
            conn.unbind_s()
        except (ldap.INVALID_CREDENTIALS):
            raise web.seeother('/login?msg=vmailadmin_INVALID_CREDENTIALS')
        except Exception as e:
            raise web.seeother('/login?msg=%s' % web.safestr(e))

        # Check whether it's a mail user
        dn_user = ldaputils.convert_keyword_to_dn(username, accountType='user')
        qr_user_auth = auth.Auth(uri=uri, dn=dn_user, password=password)

        qr_admin_auth = (False, 'INVALID_CREDENTIALS')
        if not qr_user_auth[0]:
            # Verify admin account under 'o=domainAdmins'.
            dn_admin = ldaputils.convert_keyword_to_dn(username,
                                                       accountType='admin')
            qr_admin_auth = auth.Auth(uri=uri, dn=dn_admin, password=password)

            if not qr_admin_auth[0]:
                session['failed_times'] += 1
                web.logger(msg="Login failed.",
                           admin=username,
                           event='login',
                           loglevel='error')
                raise web.seeother('/login?msg=INVALID_CREDENTIALS')

        if qr_admin_auth[0] or qr_user_auth[0]:
            session['username'] = username
            session['logged'] = True

            # Read preferred language from LDAP
            if qr_admin_auth[0] is True:
                adminLib = adminlib.Admin()
                adminProfile = adminLib.profile(
                    username, attributes=['preferredLanguage'])
                if adminProfile[0] is True:
                    dn, entry = adminProfile[1][0]
                    lang = entry.get('preferredLanguage',
                                     [settings.default_language])[0]
                    session['lang'] = lang

            if qr_user_auth[0] is True:
                session['isMailUser'] = True

            web.config.session_parameters['cookie_name'] = 'iRedAdmin-Pro'
            # Session expire when client ip was changed.
            web.config.session_parameters['ignore_change_ip'] = False
            # Don't ignore session expiration.
            web.config.session_parameters['ignore_expiry'] = False

            if save_pass == 'yes':
                # Session timeout (in seconds).
                web.config.session_parameters['timeout'] = 86400  # 24 hours
            else:
                # Expire session when browser closed.
                web.config.session_parameters['timeout'] = 600  # 10 minutes

            web.logger(
                msg="Login success",
                event='login',
            )

            # Save selected language
            selected_language = str(i.get('lang', '')).strip()
            if selected_language != web.ctx.lang and \
               selected_language in languages.get_language_maps():
                session['lang'] = selected_language

            raise web.seeother('/dashboard/checknew')
        else:
            session['failed_times'] += 1
            web.logger(
                msg="Login failed.",
                admin=username,
                event='login',
                loglevel='error',
            )
            raise web.seeother('/login?msg=%s' % qr_admin_auth[1])
Exemple #57
0
    def _open(self):
        """
        We can only intialize a single host. In this case,
        we iterate through a list of hosts until we get one that
        works and then use that to set our LDAP handle.

        SASL GSSAPI bind only succeeds when DNS reverse lookup zone
        is correctly populated. Fall through to simple bind if this
        fails.
        """
        res = None
        if self._isopen:
            return True

        if self.hosts:
            saved_simple_error = None
            saved_gssapi_error = None
            for server in self.hosts:
                try:
                    self._handle = pyldap.initialize(server)
                except Exception as e:
                    self.logger.debug(
                        f'Failed to initialize ldap connection to [{server}]: ({e}). Moving to next server.'
                    )
                    continue

                res = None
                pyldap.protocol_version = pyldap.VERSION3
                pyldap.set_option(pyldap.OPT_REFERRALS, 0)
                pyldap.set_option(pyldap.OPT_NETWORK_TIMEOUT,
                                  self.ldap['dns_timeout'])

                if SSL(self.ldap['ssl']) != SSL.NOSSL:
                    if self.ldap['certificate']:
                        pyldap.set_option(
                            pyldap.OPT_X_TLS_CERTFILE,
                            f"/etc/certificates/{self.ldap['cert_name']}.crt")
                        pyldap.set_option(
                            pyldap.OPT_X_TLS_KEYFILE,
                            f"/etc/certificates/{self.ldap['cert_name']}.key")

                    pyldap.set_option(pyldap.OPT_X_TLS_CACERTFILE,
                                      '/etc/ssl/truenas_cacerts.pem')
                    if self.ldap['validate_certificates']:
                        pyldap.set_option(pyldap.OPT_X_TLS_REQUIRE_CERT,
                                          pyldap.OPT_X_TLS_DEMAND)
                    else:
                        pyldap.set_option(pyldap.OPT_X_TLS_REQUIRE_CERT,
                                          pyldap.OPT_X_TLS_ALLOW)

                    try:
                        pyldap.set_option(pyldap.OPT_X_TLS_NEWCTX, 0)
                    except Exception:
                        self.logger.warning(
                            'Failed to initialize new TLS context.',
                            exc_info=True)

                if SSL(self.ldap['ssl']) == SSL.USESTARTTLS:
                    try:
                        self._handle.start_tls_s()

                    except pyldap.LDAPError as e:
                        self.logger.debug(
                            'Encountered error initializing start_tls: %s', e)
                        saved_simple_error = e
                        continue

                if self.ldap['anonbind']:
                    try:
                        res = self._handle.simple_bind_s()
                        break
                    except Exception as e:
                        saved_simple_error = e
                        self.logger.debug('Anonymous bind failed: %s' % e)
                        continue

                if self.ldap['certificate']:
                    try:
                        res = self._handle.sasl_non_interactive_bind_s(
                            'EXTERNAL')
                        if self.ad['verbose_logging']:
                            self.logger.debug(
                                'Successfully bound to [%s] using client certificate.',
                                server)
                        break
                    except Exception as e:
                        saved_simple_error = e
                        self.logger.debug('SASL EXTERNAL bind failed.',
                                          exc_info=True)
                        continue

                if self.ldap['kerberos_principal']:
                    try:
                        self._handle.set_option(pyldap.OPT_X_SASL_NOCANON, 1)
                        self._handle.sasl_gssapi_bind_s()
                        res = True
                        break
                    except Exception as e:
                        saved_gssapi_error = e
                        self.logger.debug(
                            f'SASL GSSAPI bind failed: {e}. Attempting simple bind'
                        )

                try:
                    res = self._handle.simple_bind_s(self.ldap['binddn'],
                                                     self.ldap['bindpw'])
                    break
                except Exception as e:
                    self.logger.debug(
                        f'Failed to bind to [{server}] using [{self.ldap["binddn"]}]: {e}'
                    )
                    saved_simple_error = e
                    continue

            if res:
                self._isopen = True

            elif saved_gssapi_error:
                self._convert_exception(saved_gssapi_error)

            elif saved_simple_error:
                self._convert_exception(saved_simple_error)

        return (self._isopen is True)
Exemple #58
0
    def get_user_info(self, username, password):
        """ get user info from ADS to a dictionary """
        try:
            userInfo = {
            'username' : username,
            'password' : password,
            }
            # prepare LDAP connection
            ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,settings.AD_CERT_FILE)
            ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER) #This required to avoid CN mismatches
            ldap.set_option(ldap.OPT_REFERRALS,0) # DO NOT TURN THIS OFF OR SEARCH WON'T WORK!

            # initialize
            self.debug_write('ldap.initialize...')
            l = ldap.initialize(settings.AD_LDAP_URL)
            l.set_option(ldap.OPT_PROTOCOL_VERSION, 3)

            # bind
            binddn = "%s@%s" % (username,settings.AD_NT4_DOMAIN)
            self.debug_write('ldap.bind %s' % binddn)
            l.bind_s(binddn,password)

            # search
            self.debug_write('search...')
            result = l.search_ext_s(settings.AD_SEARCH_DN,ldap.SCOPE_SUBTREE,"sAMAccountName=%s" % username,settings.AD_SEARCH_FIELDS)[0][1]
            self.debug_write("results in %s" % result)

            # Validate that they are a member of review board group
            if result.has_key('memberOf'):
                membership = result['memberOf']
            else:
                self.debug_write('AD user has no group memberships')
                return None

            # user ADS Groups
            isAdmin, isValid, idGroup = self.check_group(membership)

            if not isValid:
                return None

            userInfo['isAdmin'] = isAdmin
            userInfo['idGroup'] = idGroup
            self.debug_write(idGroup)

            # get user info from ADS
            # get email
            if result.has_key('mail'):
                mail = result['mail'][0]
            else:
                mail = ""

            userInfo['mail'] = mail
            self.debug_write("mail=%s" % mail)

            # get surname
            if result.has_key('sn'):
                last_name = result['sn'][0]
            else:
                last_name = None

            userInfo['last_name'] = last_name
            self.debug_write("last_name=%s" % last_name)

            # get display name
            if result.has_key('givenName'):
                first_name = result['givenName'][0]
            else:
                first_name = None

            userInfo['first_name'] = first_name
            self.debug_write("first_name=%s" % first_name)

            # LDAP unbind
            l.unbind_s()
            return userInfo

        except Exception, e:
            self.debug_write("exception caught!")
            self.debug_write(e)
            return None
Exemple #59
0
    query = Q_GET_BORRABLES + ' AND ' + Q_BETWEEN_DATES
    if DEBUG: print "get_list_by_date Query:", query
    cursor.execute(query)
    userList = cursor.fetchall()
    return userList


def testPyad():
    rows = getListByDate('2008-02-01')
    for usuario in rows:
        user = pyad.from_cn(usuario)
        print type(user)
        print user
        raw_input("Pulse para continuar ...")
    print len(rows)


try:
    ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, 0)
    lcon = ldap.initialize(LDAP_SERVER)
    lcon.simple_bind_s(BIND_DN, BIND_PASS)
except ldap.LDAPError, e:
    print e

user = lcon.search_s(USER_BASE, ldap.SCOPE_SUBTREE, "cn=i02s*")

for dn, entry in user:
    print 'Processing', repr(dn)
    print entry
    #handle_ldap_entry(entry)
Exemple #60
0
import time
import ldap
import ldap.modlist as modlist
import secrets
import base64

from flask import abort

HTTP_NOTFOUND = 404
#BASE_MEMBERS = 'OU=Test,OU=GroupsOU,DC=ps,DC=protospace,DC=ca' # testing
BASE_MEMBERS = 'OU=MembersOU,DC=ps,DC=protospace,DC=ca'  # prod

ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, './ProtospaceAD.cer')


def init_ldap():
    ldap_conn = ldap.initialize('ldaps://ldap.ps.protospace.ca:636')
    ldap_conn.set_option(ldap.OPT_REFERRALS, 0)
    ldap_conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
    ldap_conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
    ldap_conn.set_option(ldap.OPT_X_TLS_DEMAND, True)
    ldap_conn.set_option(ldap.OPT_DEBUG_LEVEL, 255)

    return ldap_conn


def find_user(username):
    '''
    Search for a user by sAMAccountname
    '''