Index: source/nsswitch/winbindd_ads.c =================================================================== RCS file: /cvsroot/samba/source/nsswitch/winbindd_ads.c,v retrieving revision 1.43.2.26 diff -u -r1.43.2.26 winbindd_ads.c --- source/nsswitch/winbindd_ads.c 13 Oct 2003 14:03:06 -0000 1.43.2.26 +++ source/nsswitch/winbindd_ads.c 2 Nov 2003 17:51:59 -0000 @@ -688,11 +688,15 @@ ADS_STRUCT *ads = NULL; char *ldap_exp; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *sidstr; + char *sidstr = NULL; const char *attrs[] = {"member", NULL}; char **members; - int i, num_members; + int i, num_members, all_members = 0; fstring sid_string; + char *member_range; + char *attr = "member"; + int lorange = 0; + int hirange = 0; DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_static(group_sid))); @@ -709,9 +713,9 @@ /* search for all members of the group */ asprintf(&ldap_exp, "(objectSid=%s)",sidstr); + +query: rc = ads_search_retry(ads, &res, ldap_exp, attrs); - free(ldap_exp); - free(sidstr); if (!ADS_ERR_OK(rc) || !res) { DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); @@ -724,7 +728,7 @@ goto done; } - members = ads_pull_strings(ads, mem_ctx, res, "member"); + members = ads_pull_strings_range(ads, mem_ctx, res, attr, &hirange); if (!members) { /* no members? ok ... */ status = NT_STATUS_OK; @@ -732,14 +736,15 @@ } /* 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 + the problem is that the members are in the form of distinguished names */ for (i=0;members[i];i++) /* noop */ ; num_members = i; + all_members += i; - (*sid_mem) = talloc_zero(mem_ctx, sizeof(**sid_mem) * num_members); - (*name_types) = talloc_zero(mem_ctx, sizeof(**name_types) * num_members); - (*names) = talloc_zero(mem_ctx, sizeof(**names) * num_members); + (*sid_mem) = talloc_realloc(mem_ctx, *sid_mem, sizeof(**sid_mem) * all_members); + (*name_types) = talloc_realloc(mem_ctx, *name_types, sizeof(**name_types) * all_members); + (*names) = talloc_realloc(mem_ctx, *names, sizeof(**names) * all_members); for (i=0;ild, (LDAPMessage *)msg, &ptr); + if (!first_attr || first_attr == NULL) + return NULL; + second_attr = ldap_next_attribute(ads->ld, (LDAPMessage *)msg, ptr); + + DEBUG(10,("attr: [%s], first_attr: [%s], second_attr: [%s]\n", + attr, first_attr, second_attr)); + + /* retrieve values and set hirange pointer */ + if (!second_attr && !StrCaseCmp(first_attr,attr)) { + /* no range */ + values = ldap_get_values(ads->ld, msg, attr); + *hirange_ptr = 0; + } + + if (second_attr) { + /* first or subsequent range */ + values = ldap_get_values(ads->ld, msg, second_attr); + *hirange_ptr = *hirange_ptr + ldap_count_values_len(values); + } + + if (!second_attr && StrCaseCmp(first_attr,attr)) { + /* subsequent or last range */ + values = ldap_get_values(ads->ld, msg, first_attr); + + /* end-of-range character is: "*" */ + if ( *(first_attr + strlen(first_attr) - 1 ) == '*' ) { + *hirange_ptr = -1; + } else { + *hirange_ptr = *hirange_ptr + ldap_count_values_len(values); + } + } + + ber_free(ptr, 0); + free(first_attr); + if (second_attr) + free(second_attr); + + if (!values) + return NULL; + + for (i=0;values[i];i++) /* noop */ ; + n = i; + + ret = talloc(mem_ctx, sizeof(char *) * (n+1)); + if (!ret) { + ldap_value_free(values); + return NULL; + } + + for (i=0;i