summaryrefslogtreecommitdiff
path: root/nslcd/group.c
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2014-01-05 22:11:20 +0100
committerArthur de Jong <arthur@arthurdejong.org>2014-01-05 22:11:20 +0100
commitc6c317ec9efb8190bdc1834091c4761b60637e7f (patch)
tree5525692071b163d3a464153aa77d39f8936820af /nslcd/group.c
parentbe94912a9d236bbe3d5b0e17b771727b0054906d (diff)
parent309b4bbbc040ce9f37ccf25399eacc5294bfc34f (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.c40
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)