svn commit: samba r23255 - in
branches/SAMBA_3_0_26/source/nsswitch: .
obnox at samba.org
obnox at samba.org
Wed May 30 22:57:47 GMT 2007
Author: obnox
Date: 2007-05-30 22:57:46 +0000 (Wed, 30 May 2007)
New Revision: 23255
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=23255
Log:
Merge the reworking of winbindd_ads lookup_groupmem function
from 3_0: Call lsa_lookup_sids on the list of sids that
can not be resolved from cache, instead of passing each
single sid to dn_lookup (which becomes obsoleten and is
removed). Weed out the sids that could not be resolved.
This merges r23072, r23078, r23252, r23253.
Michael
Modified:
branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c
Changeset:
Modified: branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c
===================================================================
--- branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c 2007-05-30 22:43:11 UTC (rev 23254)
+++ branches/SAMBA_3_0_26/source/nsswitch/winbindd_ads.c 2007-05-30 22:57:46 UTC (rev 23255)
@@ -402,50 +402,11 @@
return NT_STATUS_OK;
}
-/* convert a DN to a name, SID and name type
- this might become a major speed bottleneck if groups have
- lots of users, in which case we could cache the results
-*/
-static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- const char *dn,
- char **name, uint32 *name_type, DOM_SID *sid)
-{
- LDAPMessage *res = NULL;
- const char *attrs[] = {"userPrincipalName", "sAMAccountName",
- "objectSid", "sAMAccountType", NULL};
- ADS_STATUS rc;
- uint32 atype;
- DEBUG(3,("ads: dn_lookup\n"));
+/* If you are looking for "dn_lookup": Yes, it used to be here!
+ * It has gone now since it was a major speed bottleneck in
+ * lookup_groupmem (its only use). It has been replaced by
+ * an rpc lookup sids call... R.I.P. */
- rc = ads_search_retry_dn(ads, &res, dn, attrs);
-
- if (!ADS_ERR_OK(rc) || !res) {
- goto failed;
- }
-
- (*name) = ads_pull_username(ads, mem_ctx, res);
-
- if (!ads_pull_uint32(ads, res, "sAMAccountType", &atype)) {
- goto failed;
- }
- (*name_type) = ads_atype_map(atype);
-
- if (!ads_pull_sid(ads, res, "objectSid", sid)) {
- goto failed;
- }
-
- if (res)
- ads_msgfree(ads, res);
-
- return True;
-
-failed:
- if (res)
- ads_msgfree(ads, res);
-
- return False;
-}
-
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -942,12 +903,19 @@
char *ldap_exp;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char *sidstr;
- char **members;
+ char **members = NULL;
int i;
- size_t num_members;
- fstring sid_string;
+ size_t num_members = 0;
ads_control args;
+ struct rpc_pipe_client *cli;
+ POLICY_HND lsa_policy;
+ DOM_SID *sid_mem_nocache = NULL;
+ char **names_nocache = NULL;
+ uint32 *name_types_nocache = NULL;
+ char **domains_nocache = NULL; /* only needed for rpccli_lsa_lookup_sids */
+ uint32 num_nocache = 0;
+
DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
sid_string_static(group_sid)));
@@ -980,9 +948,6 @@
}
SAFE_FREE(sidstr);
- members = NULL;
- num_members = 0;
-
args.control = ADS_EXTENDED_DN_OID;
args.val = ADS_EXTENDED_DN_HEX_STRING;
args.critical = True;
@@ -996,74 +961,135 @@
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
- */
-
- if (num_members) {
+ DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", num_members));
+
+ /* Now that we have a list of sids, we need to get the
+ * lists of names and name_types belonging to these sids.
+ * even though conceptually not quite clean, we use the
+ * RPC call lsa_lookup_sids for this since it can handle a
+ * list of sids. ldap calls can just resolve one sid at a time.
+ *
+ * At this stage, the sids are still hidden in the exetended dn
+ * member output format. We actually do a little better than
+ * stated above: In extracting the sids from the member strings,
+ * we try to resolve as many sids as possible from the
+ * cache. Only the rest is passed to the lsa_lookup_sids call. */
+
+ if (num_names) {
(*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
+ (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
(*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);
- (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
+ (sid_mem_nocache) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
if ((members == NULL) || (*sid_mem == NULL) ||
- (*name_types == NULL) || (*names == NULL)) {
+ (*names == NULL) || (*name_types == NULL) ||
+ (sid_mem_nocache == NULL))
+ {
DEBUG(1, ("talloc failed\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- } else {
+ }
+ else {
(*sid_mem) = NULL;
+ (*names) = NULL;
(*name_types) = NULL;
- (*names) = NULL;
}
-
- for (i=0;i<num_members;i++) {
+
+ for (i=0; i<num_members; i++) {
uint32 name_type;
- char *name, *domain_name, *dn;
+ char *name, *domain_name;
DOM_SID sid;
- 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)))
- {
+ if (!ads_get_sid_from_extended_dn(mem_ctx, members[i], args.val, &sid)) {
status = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ 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)));
-
+ DEBUG(10,("ads: lookup_groupmem: got sid %s from cache\n",
+ sid_string_static(&sid)));
+ sid_copy(&(*sid_mem)[*num_names], &sid);
(*names)[*num_names] = CONST_DISCARD(char *,name);
(*name_types)[*num_names] = name_type;
- sid_copy(&(*sid_mem)[*num_names], &sid);
-
(*num_names)++;
-
- continue;
}
+ else {
+ DEBUG(10, ("ads: lookup_groupmem: sid %s not found in cache\n",
+ sid_string_static(&sid)));
+ sid_copy(&(sid_mem_nocache)[num_nocache], &sid);
+ num_nocache++;
+ }
+ }
- if (dn_lookup(ads, mem_ctx, dn, &name, &name_type, &sid)) {
+ DEBUG(10, ("ads: lookup_groupmem: %d sids found in cache, "
+ "%d left for lsa_lookupsids\n", *num_names, num_nocache));
- 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)++;
+ /* handle sids not resolved from cache by lsa_lookup_sids */
+ if (num_nocache > 0) {
+ status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
}
- }
+ status = rpccli_lsa_lookup_sids_all(cli, mem_ctx,
+ &lsa_policy,
+ num_nocache,
+ sid_mem_nocache,
+ &domains_nocache,
+ &names_nocache,
+ &name_types_nocache);
+
+ if (NT_STATUS_IS_OK(status) ||
+ NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
+ {
+ /* Copy the entries over from the "_nocache" arrays
+ * to the result arrays, skipping the gaps the
+ * lookup_sids call left. */
+ *num_names = 0;
+ for (i=0; i < num_nocache; i++) {
+ if (((names_nocache)[i] != NULL) &&
+ ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
+ {
+ sid_copy(&(*sid_mem)[*num_names],
+ &sid_mem_nocache[i]);
+ (*names)[*num_names] = names_nocache[i];
+ (*name_types)[*num_names] = name_types_nocache[i];
+ (*num_names)++;
+ }
+ }
+ }
+ else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+ DEBUG(10, ("lookup_groupmem: lsa_lookup_sids could "
+ "not map any SIDs at all.\n"));
+ /* Don't handle this as an error here.
+ * There is nothing left to do with respect to the
+ * overall result... */
+ }
+ else if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("lookup_groupmem: Error looking up %d "
+ "sids via rpc_lsa_lookup_sids: %s\n",
+ num_members, nt_errstr(status)));
+ goto done;
+ }
+ }
+
status = NT_STATUS_OK;
- DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n", sid_to_string(sid_string, group_sid)));
+ DEBUG(3,("ads lookup_groupmem for sid=%s succeeded\n",
+ sid_string_static(group_sid)));
+
done:
if (res)
ads_msgfree(ads, res);
+ /* free intermediate lists. - a temp talloc ctx might be better. */
+ TALLOC_FREE(sid_mem_nocache);
+ TALLOC_FREE(names_nocache);
+ TALLOC_FREE(name_types_nocache);
+ TALLOC_FREE(domains_nocache);
+
return status;
}
More information about the samba-cvs
mailing list