Ejemplo n.º 1
0
    def search_dn(self):
        """Searches for the user's Distinguished Name in the LDAP directory.

        :returns: A tuple of (dn, canonical_username)
        """
        uid_attr = escape_filter_chars(_config.get('ldap', 'uid_attr'))
        encoding = _config.get('ldap', 'encoding')
        manager = _config.get('ldap', 'manager').encode(encoding)
        manager_password = _config.get(
            'ldap', 'manager_password', raw=True).encode(encoding)
        if manager:
            _logger.debug("Attempting authenticated bind as manager to %s",
                          manager)
            self.ldap.simple_bind_s(manager, manager_password)
        filter_ = "(%s=%s)" % (uid_attr, escape_filter_chars(self.username))
        result = self.ldap.search_s(_config.get('ldap', 'basedn'),
                                    ldap.SCOPE_SUBTREE, filter_)
        if not result or not result[0] or not result[0][0]:
            raise UserNotFound(filter_)

        user_dn, attrs = result[0]
        if uid_attr in attrs:
            uid = attrs[uid_attr][0].decode(encoding)
        else:
            uid = self.username
        return user_dn.decode(encoding), uid
Ejemplo n.º 2
0
    def is_group_member(self, group_dn):
        """
        Verify that uid is a member in the group object identified by
        group_dn, using the pre-initialized ldap object l.

        The full user DN will be attempted matched against the member
        attribute of the group object.  If no match is found, the user uid
        will be attempted matched against the memberUid attribute.  The
        former should work well for groupOfNames and groupOfUniqueNames
        objects, the latter should work for posixGroup objects.
        """
        encoding = _config.get('ldap', 'encoding')
        user_dn = self.get_user_dn().encode(encoding)
        # Match groupOfNames/groupOfUniqueNames objects
        try:
            filterstr = '(member=%s)' % escape_filter_chars(user_dn)
            result = self.ldap.search_s(group_dn, ldap.SCOPE_BASE, filterstr)
            _logger.debug("groupOfNames results: %s", result)
            if len(result) < 1:
                # If no match, match posixGroup objects
                filterstr = (
                    '(memberUid=%s)' %
                    escape_filter_chars(self.username.encode(encoding)))
                result = self.ldap.search_s(group_dn, ldap.SCOPE_BASE,
                                            filterstr)
                _logger.debug("posixGroup results: %s", result)
            return len(result) > 0
        except ldap.TIMEOUT, error:
            _logger.error("Timed out while veryfing group memberships")
            raise TimeoutError(error)
Ejemplo n.º 3
0
 def mk_filter(self):
     # we still need a custom mk_filter because this is an | query
     if attmap['member'] and 'memberUid' in self.parameters:
         memberuid = self.parameters['memberUid']
         entry = passwd.uid2entry(self.conn, memberuid)
         if entry:
             return '(&%s(|(%s=%s)(%s=%s)))' % (
                     self.filter,
                     attmap['memberUid'], escape_filter_chars(memberuid),
                     attmap['member'], escape_filter_chars(entry[0])
                 )
     return super(Search, self).mk_filter()
Ejemplo n.º 4
0
def login(request):
    """
    Login page.

    This view is user as redirection target when an unconnected user queries a
    page that requires to be connected (@login_required decorator).
    """

    login_failed = False

    if request.method == 'POST':
        # LDAP DN special characters are escaped in this arbitrary input
        username = escape_filter_chars(request.POST['username'])
        password = request.POST['inputPassword']
        user = auth.authenticate(username=username, password=password)

        if user is not None and user.is_active:
            auth.login(request, user)

            if 'next' in request.GET:
                return HttpResponseRedirect(request.GET['next'])

            return HttpResponseRedirect("/")

        else:
            login_failed = True

    return render(
        request, "login.html",
        {
            'request': request,
            'login_failed': login_failed,
        })
Ejemplo n.º 5
0
    def enableOrDisableAccount(self, domain, account, dn, action, accountTypeInLogger=None):
        self.domain = web.safestr(domain).strip().lower()
        self.account = web.safestr(account).strip().lower()
        self.dn = escape_filter_chars(web.safestr(dn))

        # Validate operation action.
        if action in ["enable", "disable"]:
            self.action = action
        else:
            return (False, "INVALID_ACTION")

        # Set value of valid account status.
        if action == "enable":
            self.status = attrs.ACCOUNT_STATUS_ACTIVE
        else:
            self.status = attrs.ACCOUNT_STATUS_DISABLED

        try:
            self.updateAttrSingleValue(dn=self.dn, attr="accountStatus", value=self.status)

            if accountTypeInLogger is not None:
                web.logger(
                    msg="%s %s: %s." % (str(action).capitalize(), str(accountTypeInLogger), self.account),
                    domain=self.domain,
                    event=self.action,
                )

            return (True,)
        except ldap.LDAPError, e:
            return (False, ldaputils.getExceptionDesc(e))
Ejemplo n.º 6
0
 def get_by_email(self, email):
     query = "(%s=%s)" % (self.attribute_mapping["mail"], ldap_filter.escape_filter_chars(email))
     users = self.get_all(query)
     try:
         return users[0]
     except IndexError:
         return None
Ejemplo n.º 7
0
 def get_by_email(self, email):
     users = self.get_all('(mail=%s)' % \
                         (ldap_filter.escape_filter_chars(email),))
     try:
         return users[0]
     except IndexError:
         return None
Ejemplo n.º 8
0
 def get_by_name(self, name, filter=None):  # pylint: disable=W0221,W0613
     search_filter = "(%s=%s)" % (self.attribute_mapping["name"], ldap_filter.escape_filter_chars(name))
     tenants = self.get_all(search_filter)
     try:
         return tenants[0]
     except IndexError:
         raise exception.ProjectNotFound(project_id=name)
Ejemplo n.º 9
0
 def get_by_name(self, name, filter=None):
     query = "(%s=%s)" % (self.attribute_mapping["name"], ldap_filter.escape_filter_chars(name))
     groups = self.get_all(query)
     try:
         return groups[0]
     except IndexError:
         raise exception.GroupNotFound(group_id=name)
Ejemplo n.º 10
0
 def get_by_name(self, name, filter=None):
     query = "(%s=%s)" % (self.attribute_mapping["name"], ldap_filter.escape_filter_chars(name))
     res = self.get_all(query)
     try:
         return res[0]
     except IndexError:
         raise self._not_found(name)
 def search_group(self, id, conn=None):
     if not conn:
         conn = self.connect()
     filter = self.options['group_filter'] % {'group': escape_filter_chars(id)}
     rs = conn.search_s(self.options['group_dn'], ldap.SCOPE_SUBTREE, filter)
     if rs:
         return rs[0]
Ejemplo n.º 12
0
def ingroup(request, mail, cn):
    # first, figure out the uid
    mail_filter = make_search_filter(dict(mail=mail))
    alias_filter = make_search_filter(dict(emailAlias=mail))
    search_filter = '(|{}{})'.format(mail_filter, alias_filter)

    rs = connection().search_s(
        settings.LDAP_SEARCH_BASE,
        ldap.SCOPE_SUBTREE,
        search_filter,
        ['uid']
    )
    uid = None
    for dn, result in rs:
        uid = result['uid'][0]
        break

    if not uid:
        return False

    search_filter = u"""
    (|
       (&(objectClass=groupOfNames)(cn=%(groupname)s)(member=%(dn)s))
       (&(objectClass=posixGroup)(|(cn=scm_*)(cn=svn_*))(cn=%(groupname)s)(memberUid=%(mail)s))
       (&(objectClass=posixGroup)(!(|(cn=scm_*)(cn=svn_*)))(cn=%(groupname)s)(memberUid=%(uid)s))
    )
    """

    search_filter = search_filter % {
        'groupname': escape_filter_chars(cn),
        'dn': escape_filter_chars(dn),
        'uid': escape_filter_chars(uid),
        'mail': escape_filter_chars(mail),
    }
    search_filter = search_filter.strip()

    rs = connection().search_s(
        settings.GROUP_LDAP_SEARCH_BASE,
        ldap.SCOPE_SUBTREE,
        search_filter,
        ['cn']
    )

    for __ in rs:
        return True

    return False
Ejemplo n.º 13
0
 def get_by_name(self, name, filter=None):
     users = self.get_all('(%s=%s)' %
                          (self.attribute_mapping['name'],
                           ldap_filter.escape_filter_chars(name)))
     try:
         return users[0]
     except IndexError:
         raise exception.UserNotFound(user_id=name)
Ejemplo n.º 14
0
 def build_search_filter(self, term):
     # Note that this function might return an invalid filter if the config
     # use an incorrectly written custom filter.
     term_escaped = escape_filter_chars(term)
     if 'ldap_custom_filter' in self._config:
         return self._build_search_filter_from_custom_filter(term_escaped)
     else:
         return self._build_search_filter_from_searched_columns(term_escaped)
Ejemplo n.º 15
0
 def get_by_name(self, name, filter=None):
     roles = self.get_all('(%s=%s)' %
                          (self.attribute_mapping['name'],
                           ldap_filter.escape_filter_chars(name)))
     try:
         return roles[0]
     except IndexError:
         raise exception.RoleNotFound(role_id=name)
Ejemplo n.º 16
0
 def get_by_name(self, name, filter=None):
     users = self.get_all('(%s=%s)' %
                          (self.attribute_mapping['name'],
                           ldap_filter.escape_filter_chars(name)))
     try:
         return users[0]
     except IndexError:
         return None
Ejemplo n.º 17
0
def _gen_filter(attrtypes, values, extra=None):
    filt = ''
    for attr, value in zip(attrtypes, values):
        if attr is not None and value is not None:
            filt += '(%s=%s)' % (attr, ldap_filter.escape_filter_chars(value))
    if extra is not None:
        filt += '{FILT}'.format(FILT=extra)
    return filt
Ejemplo n.º 18
0
 def get_by_name(self, name, filter=None):
     query = ('(%s=%s)' % (self.attribute_mapping['name'],
                           ldap_filter.escape_filter_chars(name)))
     users = self.get_all(query)
     try:
         return users[0]
     except IndexError:
         raise exception.UserNotFound(user_id=name)
Ejemplo n.º 19
0
 def get_ldap_user_by_guid(self, guid):
     g = escape_filter_chars(guid, escape_mode=1)
     result = self.ldcon.search_s \
         ( self.cfg.LDAP_BASE_DN
         , ldap.SCOPE_SUBTREE
         , '(&(objectGUID=%s)(objectclass=%s))' % (g, self.objectclass)
         , None
         )
     return self._get_ldap_user(result)
Ejemplo n.º 20
0
    def search_for_users(self, user_string, base=None, search_attributes=None, return_attributes=None, credentials=None,
                         json_safe=False):
        """
        Returns matching user objects as a list of dictionaries

        Args:
            user_string: The substring to search for
            base: Optionally override the base object's DN
            search_attributes: The attributes to search through, with binary data removed
            easyad.EasyAD.user_attributes by default
            return_attributes: A list of attributes to return. easyad.EasyAD.user_attributes by default
            credentials: Optionally override the bind credentials
            json_safe: If true, convert binary data to base64 and datetimes to human-readable strings

        Returns:
            Results as a list of dictionaries

        Raises:
            ldap.LDAP_ERROR

        Notes:
            Setting a small number of search_attributes and return_attributes reduces server load and bandwidth
            respectively

        """
        if search_attributes is None:
            search_attributes = EasyAD.user_attributes.copy()
        if "memberOf" in search_attributes:
            search_attributes.remove("memberOf")
        if "thumbnailPhoto" in search_attributes:
            search_attributes.remove("thumbnailPhoto")

        if return_attributes is None:
            return_attributes = EasyAD.user_attributes.copy()

        generated_attributes = ["disabled", "passwordExpired", "passwordNeverExpires", "smartcardRequired"]
        for attribute in generated_attributes:
            if attribute in return_attributes:
                if "userAccountControl" not in return_attributes:
                    return_attributes.append("userAccountControl")
                break

        filter_string = ""
        for attribute in search_attributes:
            filter_string += "({0}=*{1}*)".format(attribute, escape_filter_chars(user_string))

        filter_string = "(&(objectClass=User)(|{0}))".format(filter_string)

        results = self.search(base=base,
                              filter_string=filter_string,
                              attributes=return_attributes,
                              credentials=credentials,
                              json_safe=json_safe)

        results = list(map(lambda user: enhance_user(user, json_safe=json_safe), results))

        return results
Ejemplo n.º 21
0
 def get_by_name(self, name, filter=None):  # pylint: disable=W0221,W0613
     search_filter = ('(%s=%s)'
                      % (self.attribute_mapping['name'],
                         ldap_filter.escape_filter_chars(name)))
     tenants = self.get_all(search_filter)
     try:
         return tenants[0]
     except IndexError:
         raise exception.TenantNotFound(tenant_id=name)
Ejemplo n.º 22
0
 def get_by_name(self, name, filter=None):  # pylint: disable=W0221,W0613
     search_filter = ('(%s=%s)'
                      % (self.attribute_mapping['name'],
                         ldap_filter.escape_filter_chars(name)))
     tenants = self.get_all(search_filter)
     try:
         return tenants[0]
     except IndexError:
         return None
Ejemplo n.º 23
0
 def get_by_service(self, service_id):
     roles = self.get_all("(service_id=%s)" % ldap_filter.escape_filter_chars(service_id))
     try:
         res = []
         for role in roles:
             res.append(role)
         return res
     except IndexError:
         return None
Ejemplo n.º 24
0
 def _perform_search_dn(self, xivo_ldap, username):
     username_esc = escape_filter_chars(username)
     filterstr = '{}={}'.format(self.user_login_attribute, username_esc)
     dn, _ = xivo_ldap.perform_search(self.user_base_dn, ldap.SCOPE_SUBTREE,
                                      filterstr=filterstr,
                                      attrlist=[''])
     if not dn:
         logger.debug('LDAP : No user DN for user_base dn: %s and filterstr: %s', self.user_base_dn, filterstr)
     return dn
Ejemplo n.º 25
0
def get_ldap_lists(l, search_strings, parent_list=None):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True, size=ldap_pagination_size, cookie='')

    if parent_list:
        filterstr = search_strings['get_all_sub_lists_filter'] % escape_filter_chars(parent_list)
    else:
        filterstr = search_strings['get_all_lists_filter']

    while True:
        msgid = l.search_ext(search_strings['list_search_string'],
                             ldap.SCOPE_SUBTREE,
                             serverctrls=[req_ctrl],
                             attrlist=(search_strings['list_cn_field'], search_strings['list_name_field']),
                             filterstr=filterstr)

        retries = 0
        rdata = None
        while retries < 5:
            try:
                rtype, rdata, rmsgid, serverctrls = l.result3(msgid, timeout=ldap_timeout, resp_ctrl_classes=known_ldap_resp_ctrls)
            except Exception:
                logger.exception('Error getting ldap list memberships')
                retries += 1
            else:
                break
        # ldap sometimees returns good but does not return rdata
        if rdata is None:
            break
        for (dn, data) in rdata:
            cn_field = data[search_strings['list_cn_field']][0]
            name_field = data[search_strings['list_name_field']][0]

            if isinstance(cn_field, bytes):
                cn_field = cn_field.decode('utf-8')
            if isinstance(name_field, bytes):
                name_field = name_field.decode('utf-8')

            results |= {(cn_field, name_field)}

        pctrls = [c for c in serverctrls
                  if c.controlType == SimplePagedResultsControl.controlType]

        if not pctrls:
            # Paging not supported
            logger.debug('LDAP pagination not supported')
            break
        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Ejemplo n.º 26
0
 def changePasswd(self, dn, cur_passwd, newpw):
     dn = escape_filter_chars(dn)
     try:
         # Reference: RFC3062 - LDAP Password Modify Extended Operation
         self.conn.passwd_s(dn, cur_passwd, newpw)
         return (True,)
     except ldap.UNWILLING_TO_PERFORM:
         return (False, "INCORRECT_OLDPW")
     except Exception, e:
         return (False, ldaputils.getExceptionDesc(e))
Ejemplo n.º 27
0
 def changePasswd(self, dn, cur_passwd, newpw):
     dn = escape_filter_chars(dn)
     try:
         # Reference: RFC3062 - LDAP Password Modify Extended Operation
         self.conn.passwd_s(dn, cur_passwd, newpw)
         return (True,)
     except ldap.UNWILLING_TO_PERFORM:
         return (False, 'INCORRECT_OLDPW')
     except Exception, e:
         return (False, ldaputils.getExceptionDesc(e))
Ejemplo n.º 28
0
def _gen_filter(attrtypes, values, extra=None):
    filt = ''
    if attrtypes is None:
        raise ValueError("Attempting to filter on type that doesn't support filtering!")
    for attr, value in zip(attrtypes, values):
        if attr is not None and value is not None:
            filt += '(%s=%s)' % (attr, ldap_filter.escape_filter_chars(value))
    if extra is not None:
        filt += '{FILT}'.format(FILT=extra)
    return filt
Ejemplo n.º 29
0
 def test_escape_filter_chars_mode0(self):
     """
     test function escape_filter_chars() with escape_mode=0
     """
     self.assertEquals(
         escape_filter_chars(r'foobar'),
         'foobar'
     )
     self.assertEquals(
         escape_filter_chars(r'foo\bar'),
         r'foo\5cbar'
     )
     self.assertEquals(
         escape_filter_chars(
             r'foo\bar',
             escape_mode=0
         ),
         r'foo\5cbar'
     )
Ejemplo n.º 30
0
def get_userdn_by_username(username):
	lo, po = get_machine_connection()
	if lo:
		# get the LDAP DN of the authorized user
		ldap_dn = lo.searchDn('(&(uid=%s)(objectClass=posixAccount))' % escape_filter_chars(username))
		if not ldap_dn:
			CORE.info('The LDAP DN for user %s could not be found' % (username))
			return
		CORE.info('The LDAP DN for user %s is %s' % (username, ldap_dn))
		return ldap_dn[0]
Ejemplo n.º 31
0
	def isValidPrinterObject(self):  # check printer on current spoolhost
		for member in self.info['groupMember']:
			spoolhosts = '(|'
			for host in self.info['spoolHost']:
				spoolhosts += filter_format("(univentionPrinterSpoolHost=%s)", [host])
			spoolhosts += ')'

			test = self.lo.searchDn(filter='(&(objectClass=univentionPrinter)(cn=%s)%s)' % (escape_filter_chars(member), spoolhosts))
			if len(test) < 1:
				raise univention.admin.uexceptions.notValidPrinter(_('%(name)s is not a valid printer on Spoolhost %(host)s.') % {'name': member, 'host': self.info['spoolHost']})
Ejemplo n.º 32
0
 def get_by_service(self, service_id):
     roles = self.get_all('(service_id=%s)' %
                          ldap_filter.escape_filter_chars(service_id))
     try:
         res = []
         for role in roles:
             res.append(role)
         return res
     except IndexError:
         return None
Ejemplo n.º 33
0
 def remove_udm_adconnection(cls, alias):
     lo, po, mod = cls.init_udm("office365/ad-connection")
     udm_objs = mod.lookup(None,
                           lo,
                           filter_s="cn=%s" % escape_filter_chars(alias))
     if len(udm_objs) == 1:
         udm_objs[0].remove()
         return udm_objs[0].dn
     else:
         return False
 def check_blacklist_attrs(self):
     for attr in self.add_blacklist_attrs:
         val = self.backup_data.get(attr, [None])[0]
         if val:
             l_filter = '({0}={1})'.format(attr, escape_filter_chars(val))
             res = self.lo.search(l_filter)
             if res:
                 return argparse.Namespace(value=val,
                                           attr=attr,
                                           dn=res[0][0])
     return None
Ejemplo n.º 35
0
 def validate(self, lo, validate_unlikely_changes=False):
     super(SchoolComputer, self).validate(lo, validate_unlikely_changes)
     if self.ip_address:
         name, ip_address = escape_filter_chars(
             self.name), escape_filter_chars(self.ip_address)
         if AnyComputer.get_first_udm_obj(
                 lo, '&(!(cn=%s))(ip=%s)' % (name, ip_address)):
             self.add_error(
                 'ip_address',
                 _('The ip address is already taken by another computer. Please change the ip address.'
                   ))
     if self.mac_address:
         name, mac_address = escape_filter_chars(
             self.name), escape_filter_chars(self.mac_address)
         if AnyComputer.get_first_udm_obj(
                 lo, '&(!(cn=%s))(mac=%s)' % (name, mac_address)):
             self.add_error(
                 'mac_address',
                 _('The mac address is already taken by another computer. Please change the mac address.'
                   ))
Ejemplo n.º 36
0
 def test_escape_filter_chars_mode1(self):
     """
     test function escape_filter_chars() with escape_mode=1
     """
     self.assertEquals(
         escape_filter_chars(
             '\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x84\xc3\x96\xc3\x9c\xc3\x9f',
             escape_mode=1
         ),
         r'\c3\a4\c3\b6\c3\bc\c3\84\c3\96\c3\9c\c3\9f'
     )
Ejemplo n.º 37
0
    def backend(self, backend):
        """
        @param backend - The backend DB name to show monitoring details for.

        Show monitoring status for the named backend.
        """

        backend_keys = [
            'readonly',
            'entrycachehits',
            'entrycachetries',
            'entrycachehitratio',
            'currententrycachesize',
            'maxentrycachesize',
            'currententrycachecount',
            'maxentrycachecount',
            'dncachehits',
            'dncachetries',
            'dncachehitratio',
            'currentdncachesize',
            'maxdncachesize',
            'currentdncachecount',
            'maxdncachecount',
            'normalizeddncachetries',
            'normalizeddncachehits',
            'normalizeddncachemisses',
            'normalizeddncachehitratio',
            'currentnormalizeddncachesize',
            'maxnormalizeddncachesize',
            'currentnormalizeddncachecount',
        ]

        backend = ldap_filter.escape_filter_chars(backend)
        dn = "cn=%s,%s" % (backend, DN_LDBM)

        # How do we handle errors?
        try:
            backend_status = self.conn.search_s(dn,
                                                ldap.SCOPE_SUBTREE,
                                                '(cn=monitor)',
                                                backend_keys)
        except ldap.LDAPError as e:
            return ('Unable to retrieve backend monitor information: ' +
                    'error %s' + str(e))

        status = {}
        if len(backend_status) == 1:
            status['dn'] = backend_status[0].dn
            for k in backend_keys:
                status[k] = backend_status[0].getValues(k)
        else:
            # Error case?
            pass
        return status
Ejemplo n.º 38
0
 def test_escape_filter_chars_mode2(self):
     """
     test function escape_filter_chars() with escape_mode=2
     """
     self.assertEquals(
         escape_filter_chars(
             'foobar',
             escape_mode=2
         ),
         r'\66\6f\6f\62\61\72'
     )
Ejemplo n.º 39
0
def authenticate(email, password):
    ldap_server = os.environ['INFRABOX_ACCOUNT_LDAP_URL']
    ldap_user = os.environ['INFRABOX_ACCOUNT_LDAP_DN']
    ldap_password = os.environ['INFRABOX_ACCOUNT_LDAP_PASSWORD']
    ldap_base_dn = os.environ['INFRABOX_ACCOUNT_LDAP_BASE']

    search_filter = "(mail=%s)" % escape_filter_chars(str(email))
    user_dn = None

    connect = ldap_conn(ldap_server)

    try:
        connect.bind_s(ldap_user, ldap_password)
        result = connect.search_s(ldap_base_dn,
                                  ldap.SCOPE_SUBTREE,
                                  search_filter,
                                  attrlist=['dn'])

        for r in result:
            if r[0]:
                user_dn = r[0]
                break

    except Exception as e:
        logger.warning("authentication error: %s", e)
        abort(400, 'Invalid email/password combination')
    finally:
        connect.unbind_s()

    if not user_dn:
        abort(400, 'Invalid email/password combination')

    connect = ldap_conn(ldap_server)
    try:
        connect.bind_s(user_dn, password)
        result = connect.search_s(ldap_base_dn,
                                  ldap.SCOPE_SUBTREE,
                                  search_filter,
                                  attrlist=['dn', 'cn', 'displayName'])

        user = result[0]
        if not user or not user[0]:
            abort(400, 'Invalid email/password combination')

        return {
            'cn': user[1]['cn'][0],
            'displayName': user[1]['displayName'][0]
        }

    except Exception as e:
        logger.exception(e)
        abort(400, 'Invalid email/password combination')
    finally:
        connect.unbind_s()
Ejemplo n.º 40
0
 def check_authz_search(self, parameters):
     if not cfg.pam_authz_searches:
         return
     # escape all parameters
     variables = dict((k, escape_filter_chars(v)) for k, v in parameters.items())
     variables.update(
         hostname=escape_filter_chars(socket.gethostname()),
         fqdn=escape_filter_chars(socket.getfqdn()),
         dn=variables['userdn'],
         uid=variables['username'])
     # go over all authz searches
     for x in cfg.pam_authz_searches:
         filter = x.value(variables)
         logging.debug('trying pam_authz_search "%s"', filter)
         srch = search.LDAPSearch(self.conn, filter=filter, attributes=('dn', ))
         try:
             dn, values = srch.items().next()
         except StopIteration:
             logging.error('pam_authz_search "%s" found no matches', filter)
             raise
         logging.debug('pam_authz_search found "%s"', dn)
Ejemplo n.º 41
0
            def linkUser(self, secondaryMatchVal: str, linkid: str):
                """
                Links the the target database user with the datasource on
                the provided value.  References the defined secondaryMatchAttribute
                (when this object was instantiated) for the name of the attribute that
                should be searched to find the user to link.

                secondaryMatchVal: the value of the AD secondary match field.

                linkid: the id that should link the datasource record to the target user.
                """
                searchattr = escape_filter_chars(self._secondaryMatchAttribute)
                searchval = escape_filter_chars(secondaryMatchVal)
                linkattr = escape_filter_chars(self._targetLinkAttribute)
                linkid = escape_filter_chars(linkid)
                dn = self.getUserInfo(searchattr,
                                      searchval)["distinguishedName"][0]
                modlist = [(ldap.MOD_REPLACE, linkattr,
                            [linkid.encode(self._targetEncoding)])]
                # TODO: Error Handling
                self._ld.modify_s(dn, modlist)
Ejemplo n.º 42
0
def search_objects(module, lo, pos, base='', **kwargs):
    module = _get_module(module, lo, pos)
    filter_str = ''
    for key, value in kwargs.iteritems():
        filter_str = '%s=%s' % (key, escape_filter_chars(value))
    try:
        objs = module.lookup(None, lo, filter_str, base=base)
    except udm_errors.noObject:
        objs = []
    for obj in objs:
        udm_objects.open(obj)
    return objs
Ejemplo n.º 43
0
def get_ldap_list_membership(l, search_strings, list_name):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True,
                                         size=ldap_pagination_size,
                                         cookie='')
    while True:
        msgid = l.search_ext(
            search_strings['user_search_string'],
            ldap.SCOPE_SUBTREE,
            serverctrls=[req_ctrl],
            attrlist=[search_strings['user_mail_field']],
            filterstr=search_strings['user_membership_filter'] %
            escape_filter_chars(list_name))
        retries = 0
        rdata = None
        while retries < 5:
            try:
                rtype, rdata, rmsgid, serverctrls = l.result3(
                    msgid,
                    timeout=ldap_timeout,
                    resp_ctrl_classes=known_ldap_resp_ctrls)
            except Exception:
                logger.exception('Error getting ldap list memberships')
                retries += 1
            else:
                break
        # ldap sometimees returns good but does not return rdata
        if rdata is None:
            break
        for data in rdata:
            member = data[1].get(search_strings['user_mail_field'], [None])[0]
            if isinstance(member, bytes):
                member = member.decode('utf-8')
            results |= {member}

        pctrls = [
            c for c in serverctrls
            if c.controlType == SimplePagedResultsControl.controlType
        ]

        if not pctrls:
            # Paging not supported
            logger.debug('LDAP pagination not supported')
            break
        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Ejemplo n.º 44
0
def get_ldap_lists(l, search_strings, parent_list=None):
    results = set()
    known_ldap_resp_ctrls = {
        SimplePagedResultsControl.controlType: SimplePagedResultsControl,
    }
    req_ctrl = SimplePagedResultsControl(True,
                                         size=ldap_pagination_size,
                                         cookie='')

    if parent_list:
        filterstr = search_strings[
            'get_all_sub_lists_filter'] % escape_filter_chars(parent_list)
    else:
        filterstr = search_strings['get_all_lists_filter']

    while True:
        msgid = l.search_ext(search_strings['list_search_string'],
                             ldap.SCOPE_SUBTREE,
                             serverctrls=[req_ctrl],
                             attrlist=(search_strings['list_cn_field'],
                                       search_strings['list_name_field']),
                             filterstr=filterstr)
        rtype, rdata, rmsgid, serverctrls = l.result3(
            msgid,
            timeout=ldap_timeout,
            resp_ctrl_classes=known_ldap_resp_ctrls)

        for (dn, data) in rdata:
            cn_field = data[search_strings['list_cn_field']][0]
            name_field = data[search_strings['list_name_field']][0]

            if isinstance(cn_field, bytes):
                cn_field = cn_field.decode('utf-8')
            if isinstance(name_field, bytes):
                name_field = name_field.decode('utf-8')

            results |= {(cn_field, name_field)}

        pctrls = [
            c for c in serverctrls
            if c.controlType == SimplePagedResultsControl.controlType
        ]

        if not pctrls:
            # Paging not supported
            break
        cookie = pctrls[0].cookie
        if not cookie:
            break
        req_ctrl.cookie = cookie

    return results
Ejemplo n.º 45
0
def get_user(username: str) -> User:
    found = False
    ambiguous = False
    matricolized = matricolize(username)
    username = escape_filter_chars(username)
    if matricolized is None:
        filters = (
            f"(&(objectClass=weeeOpenPerson)(uid={username})(!(nsaccountlock=true)))",
            f"(&(objectClass=weeeOpenPerson)(weeelabnickname={username})(!(nsaccountlock=true)))"
        )
    else:
        filters = (
            f"(&(objectClass=weeeOpenPerson)(schacpersonaluniquecode={matricolized})(!(nsaccountlock=true)))",
        )
    del matricolized

    try:
        print(f"Asking {LDAP_SERVER} for info...")
        conn = ldap.initialize(f"ldap://{LDAP_SERVER}:389")
        conn.protocol_version = ldap.VERSION3
        conn.start_tls_s()
        conn.simple_bind_s(LDAP_BIND_DN, LDAP_PASSWORD)
    except ldap.SERVER_DOWN:
        print(f"Cannot connect to LDAP server {LDAP_SERVER}")
        secure_exit(38)
        # noinspection PyTypeChecker
        return None  # Stops complaints from the IDE
    if conn is None:
        print(f"{PROGRAM_NAME}: Error connecting to LDAP server :(")
        secure_exit(38)

    for the_filter in filters:
        result = conn.search_s(LDAP_TREE, ldap.SCOPE_SUBTREE, the_filter,
                               ('uid', 'cn', 'givenname'))
        if len(result) > 1:
            ambiguous = True
        if len(result) == 1:
            attr = result[0][1]
            return User(attr['uid'][0].decode(), attr['cn'][0].decode(),
                        attr['givenname'][0].decode())
    conn.unbind_s()

    if ambiguous:
        print(
            f"{PROGRAM_NAME}: Multiple accounts found for that username/matricola/nickname, try with another one."
        )
        secure_exit(2)
    if not found:
        print(
            f"{PROGRAM_NAME}: Username not recognized. Maybe you misspelled it or you're an intruder."
        )
        secure_exit(2)
Ejemplo n.º 46
0
 def check_authzsearch(self, parameters):
     if not cfg.pam_authz_searches:
         return
     # escape all parameters
     variables = dict((k, escape_filter_chars(v)) for k, v in parameters.items())
     variables.update(
             hostname=escape_filter_chars(socket.gethostname()),
             fqdn=escape_filter_chars(socket.getfqdn()),
             dn=variables['userdn'],
             uid=variables['username'],
         )
     # go over all authz searches
     for x in cfg.pam_authz_searches:
         filter = x.value(variables)
         logging.debug('trying pam_authz_search "%s"', filter)
         srch = search.LDAPSearch(self.conn, filter=filter, attributes=('dn', ))
         try:
             dn, values = srch.items().next()
         except StopIteration:
             logging.error('pam_authz_search "%s" found no matches', filter)
             raise
         logging.debug('pam_authz_search found "%s"', dn)
Ejemplo n.º 47
0
def check_group_membership(username, group=None):
    with initialize_connection() as connection:
        connection.simple_bind_s(config.LDAP_BIND_DN, config.LDAP_BIND_PASSWORD)
        if group is None:
            query = config.LDAP_GROUP_ALL
        else:
            query = config.LDAP_GROUP_OBJECT_FILTER % {'group': ldap_filter.escape_filter_chars(group)}
        results = connection.search_s(config.LDAP_GROUP_BASE_DN, ldap.SCOPE_SUBTREE, query)
        members = itertools.chain.from_iterable([result[1]['memberUid']for result in results])
        encoding = config.LDAP_ENCODING
        members = [member.decode(encoding) for member in members]
        is_member = username in members
        return is_member
Ejemplo n.º 48
0
def ingroup(request, mail, cn):
    # first, figure out the uid
    mail_filter = make_search_filter(dict(mail=mail))
    alias_filter = make_search_filter(dict(emailAlias=mail))
    search_filter = '(|{}{})'.format(mail_filter, alias_filter)

    rs = connection().search_s(settings.LDAP_SEARCH_BASE, ldap.SCOPE_SUBTREE,
                               search_filter, ['uid'])
    uid = None
    for dn, result in rs:
        uid = result['uid'][0]
        break

    if not uid:
        return False

    search_filter = u"""
    (|
       (&(objectClass=groupOfNames)(cn=%(groupname)s)(member=%(dn)s))
       (&(objectClass=posixGroup)(|(cn=scm_*)(cn=svn_*))(cn=%(groupname)s)(memberUid=%(mail)s))
       (&(objectClass=posixGroup)(!(|(cn=scm_*)(cn=svn_*)))(cn=%(groupname)s)(memberUid=%(uid)s))
    )
    """

    search_filter = search_filter % {
        'groupname': escape_filter_chars(cn),
        'dn': escape_filter_chars(dn),
        'uid': escape_filter_chars(uid),
        'mail': escape_filter_chars(mail),
    }
    search_filter = search_filter.strip()

    rs = connection().search_s(settings.GROUP_LDAP_SEARCH_BASE,
                               ldap.SCOPE_SUBTREE, search_filter, ['cn'])

    for __ in rs:
        return True

    return False
Ejemplo n.º 49
0
    def get_group(self,
                  group_string,
                  base=None,
                  credentials=None,
                  attributes=None,
                  json_safe=False):
        """
        Searches for a unique group object and returns its attributes

        Args:
            group_string: A group name, cn, or dn
            base: Optionally override the base object dn
            credentials: A optional dictionary of the username and password to use.
            If credentials are not passed, the credentials from the initial EasyAD configuration are used.
            attributes: An optional list of attributes to return. Otherwise uses self.group_attributes.
            To return all attributes, pass an empty list.
            json_safe: If true, convert binary data to base64 and datetimes to human-readable strings

        Returns:
            A dictionary of group attributes

        Raises:
            ValueError: Query returned no or multiple results
            ldap.LDAP_ERROR: An LDAP error occurred
        """
        if base is None:
            base = self.config["AD_BASE_DN"]

        if attributes is None:
            attributes = self.group_attributes.copy()

        group_filter = "(&(objectClass=Group)(|(cn={0})(distinguishedName={0})))".format(
            escape_filter_chars(group_string))

        results = self.search(base=base,
                              filter_string=group_filter,
                              credentials=credentials,
                              attributes=attributes,
                              json_safe=json_safe)

        if len(results) == 0:
            raise ValueError("No such group")
        elif len(results) > 1:
            raise ValueError("The query returned more than one result")

        group = results[0]
        if "member" in group.keys():
            group["member"] = sorted(group["member"],
                                     key=lambda dn: dn.lower())

        return group
Ejemplo n.º 50
0
    def search_for_groups(self,
                          group_string,
                          base=None,
                          search_attributes=None,
                          return_attributes=None,
                          credentials=None,
                          json_safe=False):
        """
        Returns matching group objects as a list of dictionaries
        Args:
            group_string: The substring to search for
            base: Optionally override the base object's DN
            search_attributes: The attributes to search through, with binary data removed
            easyad.EasyAD.group_attributes by default
            return_attributes: A list of attributes to return. easyad.EasyAD.group_attributes by default
            credentials: Optionally override the bind credentials
            json_safe: If true, convert binary data to base64 and datetimes to human-readable strings

        Returns:
            Results as a list of dictionaries

        Raises:
            ldap.LDAP_ERROR

        Notes:
            Setting a small number of search_attributes and return_attributes reduces server load and bandwidth
            respectively

        """
        if search_attributes is None:
            search_attributes = EasyAD.group_attributes.copy()
        if "member" in search_attributes:
            search_attributes.remove("member")

        if return_attributes is None:
            return_attributes = EasyAD.group_attributes.copy()

        filter_string = ""
        for attribute in search_attributes:
            filter_string += "({0}=*{1}*)".format(
                attribute, escape_filter_chars(group_string))

        filter_string = "(&(objectClass=Group)(|{0}))".format(filter_string)

        results = self.search(base=base,
                              filter_string=filter_string,
                              attributes=return_attributes,
                              credentials=credentials,
                              json_safe=json_safe)

        return results
Ejemplo n.º 51
0
    def user_to_dn(self, username, ldap_config):
        user_dn = None
        user_id = None
        user_mail = None
        try:
            conn = self.get_connection(ldap_config)
            LOG.debug("Connection obtained to try and map user %s to dn" %
                      username)
            if ldap_config.user is not None:
                LOG.debug("Binding being requested for user: %s" %
                          ldap_config.user)
                conn.simple_bind_s(ldap_config.user, ldap_config.password)
                LOG.debug("Binding obtained")

            query = ('(&(%(name_attr)s=%(name)s)'
                     '%(filter)s'
                     '(objectClass=%(object_class)s))' % {
                         'name_attr': ldap_config.user_name_attribute,
                         'name': ldap_filter.escape_filter_chars(username),
                         'filter': (ldap_config.user_filter or ''),
                         'object_class': ldap_config.user_objectclass
                     })
            # Build the attribute list...we always want the dn...
            attrlist = ['dn']
            # ...plus additionally a specific attribute for the user_id and email
            if ldap_config.user_id_attribute != 'dn':
                attrlist.append(ldap_config.user_id_attribute)
            if ldap_config.user_mail_attribute is not None:
                attrlist.append(ldap_config.user_mail_attribute)

            users = conn.search_s(ldap_config.user_tree_dn, ldap.SCOPE_SUBTREE,
                                  query, attrlist)

            for dn, attrs in users:
                user_dn = dn
                if ldap_config.user_id_attribute == 'dn':
                    user_id = dn
                else:
                    value = attrs[ldap_config.user_id_attribute]
                    if (isinstance(value, list)):
                        user_id = value[0]
                    else:
                        user_id = value
                value = attrs.get(ldap_config.user_mail_attribute, None)
                if (isinstance(value, list)):
                    user_mail = value[0]
                else:
                    user_mail = value
                break
        except Exception, e:
            LOG.debug("Ldap user to dn failed due to: " + str(e))
Ejemplo n.º 52
0
def search_objects(_module, _lo, _pos, _base='', **kwargs):
    module = _get_module(_module, _lo, _pos)
    expressions = []
    conj = udm_filter.conjunction('&', expressions)
    for key, value in kwargs.iteritems():
        expressions.append(
            udm_filter.expression(key, escape_filter_chars(value), '='))
    try:
        objs = module.lookup(None, _lo, str(conj), base=_base)
    except udm_errors.noObject:
        objs = []
    for obj in objs:
        udm_objects.open(obj)
    return objs
Ejemplo n.º 53
0
 def get_user(self, username):
     username = ldap_filter.escape_filter_chars(username)
     dn = f"uid={username},cn=users,cn=accounts,{self.basedn}"
     filters = "(objectClass=person)"
     scope = ldap.SCOPE_BASE
     # attrlist = ["*", "+"]
     attrlist = list(c.attrname for c in USER_ATTR)
     result = self.conn.search_s(dn, scope, filters, attrlist)
     if not result:
         return None
     attrs = result[0][1]
     result = {c.destname: c(attrs) for c in USER_ATTR}
     # result['raw'] = repr(attrs)
     return result
Ejemplo n.º 54
0
 def is_valid_printer_object(self):  # check printer on current spoolhost
     spoolhosts = '(|%s)' % ''.join(
         filter_format('(univentionPrinterSpoolHost=%s)', [host])
         for host in self.info['spoolHost'])
     for member in self.info['groupMember']:
         if not self.lo.searchDn(
                 filter='(&(objectClass=univentionPrinter)(cn=%s)%s)' %
             (escape_filter_chars(member), spoolhosts)):
             raise univention.admin.uexceptions.notValidPrinter(
                 _('%(name)s is not a valid printer on Spoolhost %(host)s.')
                 % {
                     'name': member,
                     'host': self.info['spoolHost']
                 })
Ejemplo n.º 55
0
	def wait_for_drs_replication_of_membership(self, group_dn, member_uid, is_member=True, try_resync=True, **kwargs):
		"""
		wait_for_drs_replication() of a user to become a member of a group.
		:param group: str: DN of a group
		:param member_uid: str: username
		:param is_member: bool: whether the user should be a member or not
		:param try_resync: bool: if waiting for drs replication didn't succeed, run
		"/usr/share/univention-s4-connector/resync_object_from_ucs.py <group_dn>" and wait again
		:param kwargs: dict: will be passed to wait_for_drs_replication() with a modified 'ldap_filter'
		:return: None | <ldb result>
		"""
		try:
			user_filter = kwargs['ldap_filter']
			if user_filter and not user_filter.startswith('('):
				user_filter = '({})'.format(user_filter)
		except KeyError:
			user_filter = ''
		if is_member:
			member_filter = '(memberOf={})'.format(escape_filter_chars(group_dn))
		else:
			member_filter = '(!(memberOf={}))'.format(escape_filter_chars(group_dn))
		kwargs['ldap_filter'] = '(&(cn={}){}{})'.format(
			escape_filter_chars(member_uid),
			member_filter,
			user_filter
		)
		res = wait_for_drs_replication(**kwargs)
		if not res:
			self.log.warn('No result from wait_for_drs_replication().')
			if try_resync:
				cmd = ['/usr/share/univention-s4-connector/resync_object_from_ucs.py', group_dn]
				self.log.info('Running subprocess.call(%r)...', cmd)
				subprocess.call(cmd)
				self.log.info('Waiting again. Executing: wait_for_drs_replication_of_membership(group_dn=%r, member_uid=%r, is_member=%r, try_resync=False, **kwargs=%r)...', group_dn, member_uid, is_member, kwargs)
				# recursion once with try_resync=False
				res = self.wait_for_drs_replication_of_membership(group_dn=group_dn, member_uid=member_uid, is_member=is_member, try_resync=False, **kwargs)
		return res
Ejemplo n.º 56
0
	def get_share_fileserver_dn(self, set_by_self, lo):
		if set_by_self:
			set_by_self = self.get_name_from_dn(set_by_self) or set_by_self
		hostname = set_by_self or self.get_dc_name()
		if hostname == self.get_dc_name_fallback():
			# does not matter if exists or not - dc object will be created later
			host = SchoolDC(name=hostname, school=self.name)
			return host.dn

		host = AnyComputer.get_first_udm_obj(lo, 'cn=%s' % escape_filter_chars(hostname))
		if host:
			return host.dn
		else:
			logger.warning('Could not find %s. Using this host as ShareFileServer ("%s").', hostname, ucr.get('hostname'))
			return ucr.get('ldap/hostdn')
Ejemplo n.º 57
0
    def user_to_dn(self, username, ldap_config):
        user_dn = None
        user_id = None
        user_mail = None
        try:
            conn = self.get_connection(ldap_config)
            LOG.debug("Connection obtained to try and map user %s to dn" % username)
            if ldap_config.user is not None:
                LOG.debug("Binding being requested for user: %s" % ldap_config.user)
                conn.simple_bind_s(ldap_config.user, ldap_config.password)
                LOG.debug("Binding obtained")

            query = ('(&(%(name_attr)s=%(name)s)'
                     '%(filter)s'
					 '(objectClass=%(object_class)s))'
                     % {'name_attr': ldap_config.user_name_attribute,
                        'name': ldap_filter.escape_filter_chars(username),
						'filter': (ldap_config.user_filter or ''),
                        'object_class': ldap_config.user_objectclass})
            # Build the attribute list...we always want the dn...
            attrlist = ['dn']
            # ...plus additionally a specific attribute for the user_id and email
            if ldap_config.user_id_attribute != 'dn':
                attrlist.append(ldap_config.user_id_attribute)
            if ldap_config.user_mail_attribute is not None:
                attrlist.append(ldap_config.user_mail_attribute)

            users = conn.search_s(ldap_config.user_tree_dn, ldap.SCOPE_SUBTREE, query, attrlist)
                        
            for dn, attrs in users:
                user_dn = dn
                if ldap_config.user_id_attribute == 'dn':
                    user_id = dn
                else:
                    value = attrs[ldap_config.user_id_attribute]
                    if (isinstance(value, list)):
                        user_id = value[0]
                    else:
                        user_id = value
                value = attrs.get(ldap_config.user_mail_attribute, None)
                if (isinstance(value, list)):
                    user_mail = value[0]
                else:
                    user_mail = value
                break
        except Exception, e:
            LOG.debug("Ldap user to dn failed due to: " + str(e))
Ejemplo n.º 58
0
    def deleteObjWithDN(self, domain, dn, account, accountType):
        self.domain = web.safestr(domain)
        if not iredutils.is_domain(self.domain):
            return (False, "INVALID_DOMAIN_NAME")

        self.dn = escape_filter_chars(dn)

        # Used for logger.
        self.account = web.safestr(account)

        try:
            deltree.DelTree(self.conn, self.dn, ldap.SCOPE_SUBTREE)
            web.logger(msg="Delete %s: %s." % (str(accountType), self.account), domain=self.domain, event="delete")

            return (True,)
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Ejemplo n.º 59
0
    def __init__(self, uri, auth_user, auth_password, base_dn, group=None):
        """
        Constructs and binds an LDAPKeyProvider instance to the server
        identified by the uri using auth_user and auth_password for
        authentication.

        When users are looked up, it is verified that they belong to the
        provided group.
        """
        self.group = None
        if group:
            self.group = filter.escape_filter_chars(group)
        self.base_dn = base_dn

        # I know, this is not functionality the ldap module straightforwardly
        # exposes, but it seems to work.
        self.conn = ldap.ldapobject.ReconnectLDAPObject(uri)
        self.conn.simple_bind(auth_user, auth_password)
Ejemplo n.º 60
0
	def _make_ldap_query(self, query_args, unique=True):
		"""
		Execute an LDAP query for a user who matches the filter parameters
		provided in the `query_args` dict, where each key is the name of a valid
		LDAP field, and each value is the value requested for that field.

		The results of this query will be returned as dict whose keys will match
		those defined in the `desired_attributes` class attribute.

		If the `unique` keyword argument is True and more than one record is
		returned, an error will be raised.
		"""

		#  Build our filter string
		filters = "".join([ "(%s=%s)" % (key, escape_filter_chars(val)) for key, val in query_args.iteritems() ])
		if len(query_args) > 1:
			filters = "(&%s)" % filters

		#  The LDAP results object is of the form [0 => user DN, 1 => user info]
		results = self._ldap_conn.search_st(ldap_settings['LDAP_SEARCH_BASE'], ldap_settings['LDAP_SCOPE'], filters)
		if results:
			if unique and len(results) > 1:
				raise ValueError(_("expected a unique record, but %(record_count)d records were found!") % {
					'record_count': len(user_info)
				})

			#  Map the LDAP values to our requested attributes
			info_list = []
			for result in [result[1] for result in results]:
				user_info = {}
				for dict_key, ldap_val in self.desired_attributes.iteritems():
					user_val = result.get(ldap_val)
					try:
						user_val = user_val.pop()
					except AttributeError:
						pass
					user_info[dict_key] = user_val
				user_info['professor'] = user_info.get('professor', [""]) == "Faculty"
				info_list.append(user_info)

			return info_list.pop() if unique else info_list

		return None