summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd.h8
-rw-r--r--source3/nsswitch/winbindd_ads.c1
-rw-r--r--source3/nsswitch/winbindd_cache.c86
-rw-r--r--source3/nsswitch/winbindd_group.c41
-rw-r--r--source3/nsswitch/winbindd_passdb.c8
-rw-r--r--source3/nsswitch/winbindd_rpc.c62
6 files changed, 206 insertions, 0 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index 22deaf82c6..cd1d16e344 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -183,6 +183,14 @@ struct winbindd_methods {
const DOM_SID *user_sid,
uint32 *num_groups, DOM_SID ***user_gids);
+ /* Lookup all aliases that the sids delivered are member of. This is
+ * to implement 'domain local groups' correctly */
+ NTSTATUS (*lookup_useraliases)(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases,
+ uint32 **alias_rids);
+
/* find all members of the group with the specified group_rid */
NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index f77b76cd9a..335e21adcb 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -966,6 +966,7 @@ struct winbindd_methods ads_methods = {
msrpc_sid_to_name,
query_user,
lookup_usergroups,
+ msrpc_lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index ba274ec8e7..460ce934cb 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -5,6 +5,7 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Gerald Carter 2003
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
@@ -1202,6 +1203,90 @@ skip_save:
return status;
}
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ struct winbind_cache *cache = get_cache(domain);
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
+ char *sidlist = talloc_strdup(mem_ctx, "");
+ int i;
+
+ if (!cache->tdb)
+ goto do_query;
+
+ if (num_sids == 0) {
+ *num_aliases = 0;
+ *alias_rids = NULL;
+ return NT_STATUS_OK;
+ }
+
+ /* We need to cache indexed by the whole list of SIDs, the aliases
+ * resulting might come from any of the SIDs. */
+
+ for (i=0; i<num_sids; i++) {
+ sidlist = talloc_asprintf(mem_ctx, "%s/%s", sidlist,
+ sid_string_static(sids[i]));
+ if (sidlist == NULL)
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ centry = wcache_fetch(cache, domain, "UA%s", sidlist);
+
+ if (!centry)
+ goto do_query;
+
+ *num_aliases = centry_uint32(centry);
+ *alias_rids = NULL;
+
+ (*alias_rids) = TALLOC_ARRAY(mem_ctx, uint32, *num_aliases);
+
+ if (!(*alias_rids))
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<(*num_aliases); i++)
+ (*alias_rids)[i] = centry_uint32(centry);
+
+ status = centry->status;
+
+ DEBUG(10,("lookup_useraliases: [Cached] - cached info for domain %s "
+ "status %s\n", domain->name,
+ get_friendly_nt_error_msg(status)));
+
+ centry_free(centry);
+ return status;
+
+ do_query:
+ (*num_aliases) = 0;
+ (*alias_rids) = NULL;
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
+
+ DEBUG(10,("lookup_usergroups: [Cached] - doing backend query for info "
+ "for domain %s\n", domain->name ));
+
+ status = domain->backend->lookup_useraliases(domain, mem_ctx,
+ num_sids, sids,
+ num_aliases, alias_rids);
+
+ /* and save it */
+ refresh_sequence_number(domain, False);
+ centry = centry_start(domain, status);
+ if (!centry)
+ goto skip_save;
+ centry_put_uint32(centry, *num_aliases);
+ for (i=0; i<(*num_aliases); i++)
+ centry_put_uint32(centry, (*alias_rids)[i]);
+ centry_end(centry, "UA%s", sidlist);
+ centry_free(centry);
+
+ skip_save:
+ return status;
+}
+
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -1387,6 +1472,7 @@ struct winbindd_methods cache_methods = {
sid_to_name,
query_user,
lookup_usergroups,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index d64c2e4a19..502a4b8584 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -6,6 +6,7 @@
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
Copyright (C) Gerald (Jerry) Carter 2003.
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1234,6 +1235,46 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state)
goto no_groups;
}
+ domain = find_our_domain();
+
+ if (domain == NULL) {
+ DEBUG(0, ("Could not find our domain\n"));
+ goto done;
+ }
+
+ /* Note that I do not check for AD or its mode. XP in a real NT4
+ * domain also asks for this info. -- vl */
+
+ if (!IS_DC) {
+ uint32_t *alias_rids = NULL;
+ int num_aliases;
+
+ /* We need to include the user SID to expand */
+ user_grpsids = TALLOC_REALLOC_ARRAY(mem_ctx, user_grpsids,
+ DOM_SID *, num_groups+1);
+ user_grpsids[num_groups] = &user_sid;
+
+ status = domain->methods->lookup_useraliases(domain, mem_ctx,
+ num_groups,
+ user_grpsids+1,
+ &num_aliases,
+ &alias_rids);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Could not expand alias sids: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ for (i=0; i<num_aliases; i++) {
+ DOM_SID sid;
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, alias_rids[i]);
+ add_sid_to_parray_unique(mem_ctx, &sid, &user_grpsids,
+ &num_groups);
+ }
+ }
+
if (lp_winbind_nested_groups()) {
int k;
/* num_groups is changed during the loop, that's why we have
diff --git a/source3/nsswitch/winbindd_passdb.c b/source3/nsswitch/winbindd_passdb.c
index a208186b5f..4dcc018c64 100644
--- a/source3/nsswitch/winbindd_passdb.c
+++ b/source3/nsswitch/winbindd_passdb.c
@@ -292,6 +292,13 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return NT_STATUS_NO_SUCH_USER;
}
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID **sids,
+ uint32 *num_aliases, DOM_SID ***aliases)
+{
+ return NT_STATUS_NO_SUCH_USER;
+}
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
@@ -384,6 +391,7 @@ struct winbindd_methods passdb_methods = {
sid_to_name,
query_user,
lookup_usergroups,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index e6edb70f07..10d6e4f4fa 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -5,6 +5,7 @@
Copyright (C) Tim Potter 2000-2001,2003
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -561,6 +562,66 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return result;
}
+NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ CLI_POLICY_HND *hnd;
+ BOOL got_dom_pol = False;
+ POLICY_HND dom_pol;
+ DOM_SID2 *sid2;
+ int i, retry;
+
+ *num_aliases = 0;
+ *alias_rids = NULL;
+
+ retry = 0;
+ do {
+ /* Get sam handle; if we fail here there is no hope */
+
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain,
+ &hnd)))
+ goto done;
+
+ /* Get domain handle */
+
+ result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sid, &dom_pol);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ got_dom_pol = True;
+
+ sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+
+ if (sid2 == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ for (i=0; i<num_sids; i++) {
+ sid_copy(&sid2[i].sid, sids[i]);
+ sid2[i].num_auths = sid2[i].sid.num_auths;
+ }
+
+ result = cli_samr_query_useraliases(hnd->cli, mem_ctx, &dom_pol,
+ num_sids, sid2,
+ num_aliases, alias_rids);
+
+ done:
+
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
+
+ return result;
+}
+
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
@@ -980,6 +1041,7 @@ struct winbindd_methods msrpc_methods = {
msrpc_sid_to_name,
query_user,
lookup_usergroups,
+ msrpc_lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,