diff options
| author | Arthur de Jong <arthur@arthurdejong.org> | 2014-01-05 22:11:20 +0100 |
|---|---|---|
| committer | Arthur de Jong <arthur@arthurdejong.org> | 2014-01-05 22:11:20 +0100 |
| commit | c6c317ec9efb8190bdc1834091c4761b60637e7f (patch) | |
| tree | 5525692071b163d3a464153aa77d39f8936820af /nslcd/group.c | |
| parent | be94912a9d236bbe3d5b0e17b771727b0054906d (diff) | |
| parent | 309b4bbbc040ce9f37ccf25399eacc5294bfc34f (diff) | |
Implement deref control handling
This uses the LDAP_CONTROL_X_DEREF control as described in
draft-masarati-ldap-deref-00 to request the LDAP server to dereference
group member attribute values to uid attribute values.
This should reduce the number of searches that are required for
expanding group members that use the member attribute.
This mechanism could also be used to extract information on nested
groups but the gains are less clear there.
Not all LDAP servers support this control. In OpenLDAP, load the
(currently undocumented) deref overlay and enable it for the database to
take advantage of this improvement.
There is a functional difference when using this control. Any returned
deferred uid value returned by the LDAP server is accepted as a member.
No checks are performed to see if the user matches the search base and
search filters set for passwd entries.
Diffstat (limited to 'nslcd/group.c')
| -rw-r--r-- | nslcd/group.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/nslcd/group.c b/nslcd/group.c index 1455930..ffaeb80 100644 --- a/nslcd/group.c +++ b/nslcd/group.c @@ -78,6 +78,9 @@ static const char *default_group_userPassword = "*"; /* unmatchable */ /* the attribute list to request with searches */ static const char **group_attrs = NULL; +/* the attribute list for bymember searches (without member attributes) */ +static const char **group_bymember_attrs = NULL; + /* create a search filter for searching a group entry by name, return -1 on errors */ static int mkfilter_group_byname(const char *name, @@ -181,6 +184,18 @@ void group_init(void) exit(EXIT_FAILURE); } set_free(set); + /* set up bymember attribute list */ + set = set_new(); + attmap_add_attributes(set, attmap_group_cn); + attmap_add_attributes(set, attmap_group_userPassword); + attmap_add_attributes(set, attmap_group_gidNumber); + group_bymember_attrs = set_tolist(set); + if (group_bymember_attrs == NULL) + { + log_log(LOG_CRIT, "malloc() failed to allocate memory"); + exit(EXIT_FAILURE); + } + set_free(set); } static int do_write_group(TFILE *fp, MYLDAP_ENTRY *entry, @@ -219,6 +234,7 @@ static void getmembers(MYLDAP_ENTRY *entry, MYLDAP_SESSION *session, char buf[BUFLEN_NAME]; int i; const char **values; + const char ***derefs; /* add the memberUid values */ values = myldap_get_values(entry, attmap_group_memberUid); if (values != NULL) @@ -231,6 +247,26 @@ static void getmembers(MYLDAP_ENTRY *entry, MYLDAP_SESSION *session, /* skip rest if attmap_group_member is blank */ if (strcasecmp(attmap_group_member, "\"\"") == 0) return; + /* add deref'd entries if we have them*/ + derefs = myldap_get_deref_values(entry, attmap_group_member, attmap_passwd_uid); + if (derefs != NULL) + { + /* add deref'd uid attributes */ + for (i = 0; derefs[0][i] != NULL; i++) + set_add(members, derefs[0][i]); + /* add non-deref'd attribute values as subgroups */ + for (i = 0; derefs[1][i] != NULL; i++) + { + if ((seen == NULL) || (!set_contains(seen, derefs[1][i]))) + { + if (seen != NULL) + set_add(seen, derefs[1][i]); + if (subgroups != NULL) + set_add(subgroups, derefs[1][i]); + } + } + return; /* no need to parse the member attribute ourselves */ + } /* add the member values */ values = myldap_get_values(entry, attmap_group_member); if (values != NULL) @@ -447,7 +483,7 @@ int nslcd_group_bymember(TFILE *fp, MYLDAP_SESSION *session) { /* do the LDAP search */ search = myldap_search(session, base, group_scope, filter, - group_attrs, NULL); + group_bymember_attrs, NULL); if (search == NULL) { if (seen != NULL) @@ -497,7 +533,7 @@ int nslcd_group_bymember(TFILE *fp, MYLDAP_SESSION *session) /* do the LDAP searches */ for (i = 0; (base = group_bases[i]) != NULL; i++) { - search = myldap_search(session, base, group_scope, filter, group_attrs, NULL); + search = myldap_search(session, base, group_scope, filter, group_bymember_attrs, NULL); if (search != NULL) { while ((entry = myldap_get_entry(search, NULL)) != NULL) |
