Skip to content

Commit

Permalink
Merge pull request Ericsson#3006 from gyorb/ldap-dn
Browse files Browse the repository at this point in the history
[server][auth] user dn postfix preference
  • Loading branch information
csordasmarton authored Nov 10, 2020
2 parents 616f593 + 04d6f70 commit 39a2837
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
12 changes: 12 additions & 0 deletions docs/web/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,17 @@ servers as it can elongate the authentication process.

Example configuration: `(&(objectClass=person)(sAMAccountName=$USN$))`

* `user_dn_postfix_preference`

User DN postfix preference value can be used to select out one prefered
user DN if multiple DN entries are found by the LDAP search.
The configured value will be matched and the first matching will be used.
If only one DN was found this postfix matching will not be used.
If not set and multiple values are found the first value
in the search result list will be used.

Example configuration: `OU=people,DC=example,DC=com`

* `groupBase`

Root tree containing all the groups.
Expand Down Expand Up @@ -250,6 +261,7 @@ servers as it can elongate the authentication process.
"accountBase" : null,
"accountScope" : "subtree",
"accountPattern" : "(&(objectClass=person)(sAMAccountName=$USN$))",
"user_dn_postfix_preference": null,
"groupBase" : null,
"groupScope" : "subtree",
"groupPattern" : "(&(objectClass=group)(member=$USERDN$))",
Expand Down
42 changes: 34 additions & 8 deletions web/server/codechecker_server/auth/cc_ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,22 +139,41 @@ def ldap_error_handler():
def get_user_dn(con,
account_base_dn,
account_pattern,
scope=ldap.SCOPE_SUBTREE):
scope=ldap.SCOPE_SUBTREE,
user_dn_postfix_preference=None):
"""
Search for the user dn based on the account pattern.
Return the full user dn None if search failed.
Parameters:
user_dn_postfix_preference: User DN postfix preference value can
be used to select out one prefered
user DN if multiple DN entries are found by the LDAP search.
The configured value will be matched and the first matching will be used.
If only one DN was found this postfix matching will not be used.
If not set and multiple values are found the first value
in the search result list will be used.
"""

with ldap_error_handler():
# Attribute values MAY contain any type of data. Before you use a
# value, call 'bytes_to_str' helper function to convert it to text.
user_data = con.search_s(account_base_dn, scope, account_pattern)

user_dns = []
if user_data:
# User found use the user DN from the first result.
user_dn = bytes_to_str(user_data[0][0])
LOG.debug("Found user: %s", user_dn)
return user_dn
for user_info in user_data:
user_dns.append(bytes_to_str(user_info[0]))
LOG.debug("Found user dns: %s", ', '.join(user_dns))

if len(user_dns) > 1 and user_dn_postfix_preference:
for user_dn in user_dns:
if user_dn.endswith(user_dn_postfix_preference):
LOG.debug("Selected user dn: %s", user_dn)
return user_dn
elif len(user_dns) > 0:
LOG.debug("Selected user dn: %s", user_dns[0])
return user_dns[0]

LOG.debug("Searching for user failed with pattern: %s", account_pattern)
LOG.debug("Account base DN: %s", account_base_dn)
Expand Down Expand Up @@ -316,6 +335,9 @@ def auth_user(ldap_config, username=None, credentials=None):
service_cred = credentials

LOG.debug("Creating SERVICE connection...")

user_dn_postfix_preference = ldap_config.get('user_dn_postfix_preference')

with LDAPConnection(ldap_config, service_user, service_cred) as connection:
if connection is None:
LOG.error('Please check your LDAP server '
Expand All @@ -326,7 +348,8 @@ def auth_user(ldap_config, username=None, credentials=None):
user_dn = get_user_dn(connection,
account_base,
account_pattern,
account_scope)
account_scope,
user_dn_postfix_preference)

if user_dn is None:
LOG.warning("DN lookup failed for user name: '%s'!", username)
Expand Down Expand Up @@ -371,6 +394,8 @@ def get_groups(ldap_config, username, credentials):
service_user = username
service_cred = credentials

user_dn_postfix_preference = ldap_config.get('user_dn_postfix_preference')

LOG.debug("creating LDAP connection. service user %s", service_user)
with LDAPConnection(ldap_config, service_user, service_cred) as connection:
if connection is None:
Expand All @@ -381,15 +406,16 @@ def get_groups(ldap_config, username, credentials):
user_dn = get_user_dn(connection,
account_base,
account_pattern,
account_scope)
account_scope,
user_dn_postfix_preference)

group_pattern = ldap_config.get('groupPattern', '')
if user_dn and group_pattern == '':
# User found and there is no group membership pattern to check.
return []
group_pattern = group_pattern.replace('$USERDN$', user_dn)

LOG.debug('Checking for group membership.')
LOG.debug('Checking for group membership %s', user_dn)

group_scope = ldap_config.get('groupScope', '')
group_scope = get_ldap_query_scope(group_scope)
Expand Down
1 change: 1 addition & 0 deletions web/server/config/server_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"accountBase" : null,
"accountScope" : "subtree",
"accountPattern" : "(&(objectClass=person)(sAMAccountName=$USN$))",
"user_dn_postfix_preference": null,
"groupBase" : null,
"groupScope" : "subtree",
"groupPattern" : "(&(objectClass=group)(member=$USERDN$))",
Expand Down

0 comments on commit 39a2837

Please sign in to comment.