summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2007-04-22 15:25:54 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:19:35 -0500
commitfa2756c944b0316b2fef33646d15d13670dcfb49 (patch)
treee233366e46d01e163bb2a8a8c6399685a934de89 /source3/nsswitch
parent56f6336fd4a8e929bf18f1c1c3b3f8f54ee341f5 (diff)
downloadsamba-fa2756c944b0316b2fef33646d15d13670dcfb49.tar.gz
samba-fa2756c944b0316b2fef33646d15d13670dcfb49.tar.bz2
samba-fa2756c944b0316b2fef33646d15d13670dcfb49.zip
r22461: Use ranged LDAP queries in lookup_usergroups_member() and start to optinmize
lookup_groupmem(). In the later, at least try to avoid those massive LDAP dn_lookups by looking in the cache before. Guenther (This used to be commit eb1566869c5493f2a1d1ff9fcaaa45c143ad12a0)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd_ads.c174
1 files changed, 75 insertions, 99 deletions
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 8391a985fc..f189123d7d 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -609,13 +609,15 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
{
ADS_STATUS rc;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- int count;
LDAPMessage *res = NULL;
ADS_STRUCT *ads;
const char *attrs[] = {"memberOf", NULL};
size_t num_groups = 0;
DOM_SID *group_sids = NULL;
int i;
+ char **strings;
+ size_t num_strings = 0;
+
DEBUG(3,("ads: lookup_usergroups_memberof\n"));
@@ -626,22 +628,16 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
goto done;
}
- rc = ads_search_retry_extended_dn(ads, &res, user_dn, attrs,
- ADS_EXTENDED_DN_HEX_STRING);
-
- if (!ADS_ERR_OK(rc) || !res) {
+ rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
+ ADS_EXTENDED_DN_HEX_STRING,
+ &strings, &num_strings);
+
+ if (!ADS_ERR_OK(rc)) {
DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n",
user_dn, ads_errstr(rc)));
return ads_ntstatus(rc);
}
- count = ads_count_replies(ads, res);
-
- if (count == 0) {
- status = NT_STATUS_NO_SUCH_USER;
- goto done;
- }
-
*user_sids = NULL;
num_groups = 0;
@@ -651,16 +647,32 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
goto done;
}
- count = ads_pull_sids_from_extendeddn(ads, mem_ctx, res, "memberOf",
- ADS_EXTENDED_DN_HEX_STRING,
- &group_sids);
- if (count == 0) {
+ group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);
+ if (!group_sids) {
+ TALLOC_FREE(strings);
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ for (i=0; i<num_strings; i++) {
+
+ if (!ads_get_sid_from_extended_dn(mem_ctx, strings[i],
+ ADS_EXTENDED_DN_HEX_STRING,
+ &(group_sids)[i])) {
+ TALLOC_FREE(group_sids);
+ TALLOC_FREE(strings);
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ }
+
+ if (i == 0) {
DEBUG(1,("No memberOf for this user?!?\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- for (i=0; i<count; i++) {
+ for (i=0; i<num_strings; i++) {
/* ignore Builtin groups from ADS - Guenther */
if (sid_check_is_in_builtin(&group_sids[i])) {
@@ -841,7 +853,6 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
uint32 **name_types)
{
ADS_STATUS rc;
- int count;
LDAPMessage *res=NULL;
ADS_STRUCT *ads = NULL;
char *ldap_exp;
@@ -851,11 +862,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
int i;
size_t num_members;
fstring sid_string;
- BOOL more_values;
- const char **attrs;
- uint32 first_usn;
- uint32 current_usn;
- int num_retries = 0;
+ ads_control args;
DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
sid_string_static(group_sid)));
@@ -886,77 +893,19 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
members = NULL;
num_members = 0;
- if ((attrs = TALLOC_ARRAY(mem_ctx, const char *, 3)) == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- attrs[1] = talloc_strdup(mem_ctx, "usnChanged");
- attrs[2] = NULL;
-
- do {
- if (num_members == 0)
- attrs[0] = talloc_strdup(mem_ctx, "member");
-
- DEBUG(10, ("Searching for attrs[0] = %s, attrs[1] = %s\n", attrs[0], attrs[1]));
-
- rc = ads_search_retry(ads, &res, ldap_exp, attrs);
-
- if (!ADS_ERR_OK(rc) || !res) {
- DEBUG(1,("ads: lookup_groupmem ads_search: %s\n",
- ads_errstr(rc)));
- status = ads_ntstatus(rc);
- goto done;
- }
+ args.control = ADS_EXTENDED_DN_OID;
+ args.val = ADS_EXTENDED_DN_HEX_STRING;
+ args.critical = True;
- count = ads_count_replies(ads, res);
- if (count == 0)
- break;
+ rc = ads_ranged_search(ads, mem_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
+ ldap_exp, &args, "member", &members, &num_members);
- if (num_members == 0) {
- if (!ads_pull_uint32(ads, res, "usnChanged", &first_usn)) {
- DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n"));
- goto done;
- }
- }
-
- if (!ads_pull_uint32(ads, res, "usnChanged", &current_usn)) {
- DEBUG(1, ("ads: lookup_groupmem could not pull usnChanged!\n"));
- goto done;
- }
-
- if (first_usn != current_usn) {
- DEBUG(5, ("ads: lookup_groupmem USN on this record changed"
- " - restarting search\n"));
- if (num_retries < 5) {
- num_retries++;
- num_members = 0;
- ads_msgfree(ads, res);
- res = NULL;
- continue;
- } else {
- DEBUG(5, ("ads: lookup_groupmem USN on this record changed"
- " - restarted search too many times, aborting!\n"));
- status = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
- }
-
- members = ads_pull_strings_range(ads, mem_ctx, res,
- "member",
- members,
- &attrs[0],
- &num_members,
- &more_values);
-
- ads_msgfree(ads, res);
- res = NULL;
-
- if ((members == NULL) || (num_members == 0))
- break;
-
- } while (more_values);
-
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(0,("ads_ranged_search failed with: %s\n", ads_errstr(rc)));
+ status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
/* now we need to turn a list of members into rids, names and name types
the problem is that the members are in the form of distinguised names
*/
@@ -975,19 +924,46 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
for (i=0;i<num_members;i++) {
uint32 name_type;
- char *name;
+ char *name, *domain_name, *dn;
DOM_SID sid;
- if (dn_lookup(ads, mem_ctx, members[i], &name, &name_type, &sid)) {
- (*names)[*num_names] = name;
- (*name_types)[*num_names] = name_type;
- sid_copy(&(*sid_mem)[*num_names], &sid);
- (*num_names)++;
+ if ((!ads_get_sid_from_extended_dn(mem_ctx, members[i], ADS_EXTENDED_DN_HEX_STRING, &sid)) ||
+ (!ads_get_dn_from_extended_dn(mem_ctx, members[i], &dn)))
+ {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
+
+ DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n",
+ sid_string_static(&sid)));
+
+ (*names)[*num_names] = CONST_DISCARD(char *,name);
+ (*name_types)[*num_names] = name_type;
+ sid_copy(&(*sid_mem)[*num_names], &sid);
+
+ (*num_names)++;
+
+ continue;
+ }
+
+ if (dn_lookup(ads, mem_ctx, dn, &name, &name_type, &sid)) {
+
+ DEBUG(10,("ads: lookup_groupmem: got sid %s from dn_lookup\n",
+ sid_string_static(&sid)));
+
+ (*names)[*num_names] = name;
+ (*name_types)[*num_names] = name_type;
+ sid_copy(&(*sid_mem)[*num_names], &sid);
+
+ (*num_names)++;
+
}
}
status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_groupmem for sid=%s\n", sid_to_string(sid_string, group_sid)));
+ DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n", sid_to_string(sid_string, group_sid)));
done:
if (res)