]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r4760: Make wbinfo --user-sids expand domain local groups. Andrew B., my testing
authorVolker Lendecke <vlendec@samba.org>
Sat, 15 Jan 2005 19:00:18 +0000 (19:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:54 +0000 (10:53 -0500)
shows that this info is correctly returned to us in to info3 struct, so
check_info3_in_group does not need to be adapted.

Volker

source/nsswitch/winbindd.h
source/nsswitch/winbindd_ads.c
source/nsswitch/winbindd_cache.c
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_passdb.c
source/nsswitch/winbindd_rpc.c

index 22deaf82c6ec6ea6e8bc32eb32f86de2224fbf6c..cd1d16e34411349ac7aa6a26518fb0b38ea575ac 100644 (file)
@@ -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,
index f77b76cd9abdc8fc74e5c535b5ef01a92cd673d0..335e21adcbe231cd253f2a3e8dc5c2406fe04f0e 100644 (file)
@@ -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,
index ba274ec8e7060f1bec04086fbc38881b333e4dec..460ce934cb7e2c80b149f73ea50057769bbf02de 100644 (file)
@@ -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,
index d64c2e4a19c6b18c19342354a0931d69e0b66692..502a4b85841b0f13025c92b53c1b57515136fd65 100644 (file)
@@ -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
index a208186b5f5205f0828ea1f96ff50dcae7ff47b5..4dcc018c64b8a32da2cbfabc86518199bb1fb227 100644 (file)
@@ -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,
index e6edb70f0796fbbcae79cbaed044d68c3e3eb288..10d6e4f4fa914244f52ecef95024e463912932ac 100644 (file)
@@ -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,