diff options
Diffstat (limited to 'source3/nsswitch/winbindd_group.c')
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 147 |
1 files changed, 144 insertions, 3 deletions
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 1b21352c86..e5cdc404a0 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -31,9 +31,150 @@ extern BOOL opt_nocache; #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -/*************************************************************** - Empty static struct for negative caching. -****************************************************************/ +static void add_member(const char *domain, const char *user, + char **pp_members, size_t *p_num_members) +{ + fstring name; + + fill_domain_username(name, domain, user, True); + safe_strcat(name, ",", sizeof(name)-1); + string_append(pp_members, name); + *p_num_members += 1; +} + +/********************************************************************** + Add member users resulting from sid. Expand if it is a domain group. +**********************************************************************/ + +static void add_expanded_sid(const DOM_SID *sid, char **pp_members, size_t *p_num_members) +{ + DOM_SID dom_sid; + uint32 rid; + struct winbindd_domain *domain; + size_t i; + + char *domain_name = NULL; + char *name = NULL; + enum lsa_SidType type; + + uint32 num_names; + DOM_SID *sid_mem; + char **names; + uint32 *types; + + NTSTATUS result; + + TALLOC_CTX *mem_ctx = talloc_init("add_expanded_sid"); + + if (mem_ctx == NULL) { + DEBUG(1, ("talloc_init failed\n")); + return; + } + + sid_copy(&dom_sid, sid); + sid_split_rid(&dom_sid, &rid); + + domain = find_lookup_domain_from_sid(sid); + + if (domain == NULL) { + DEBUG(3, ("Could not find domain for sid %s\n", + sid_string_static(sid))); + goto done; + } + + result = domain->methods->sid_to_name(domain, mem_ctx, sid, + &domain_name, &name, &type); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3, ("sid_to_name failed for sid %s\n", + sid_string_static(sid))); + goto done; + } + + DEBUG(10, ("Found name %s, type %d\n", name, type)); + + if (type == SID_NAME_USER) { + add_member(domain_name, name, pp_members, p_num_members); + goto done; + } + + if (type != SID_NAME_DOM_GRP) { + DEBUG(10, ("Alias member %s neither user nor group, ignore\n", + name)); + goto done; + } + + /* Expand the domain group, this must be done via the target domain */ + + domain = find_domain_from_sid(sid); + + if (domain == NULL) { + DEBUG(3, ("Could not find domain from SID %s\n", + sid_string_static(sid))); + goto done; + } + + result = domain->methods->lookup_groupmem(domain, mem_ctx, + sid, &num_names, + &sid_mem, &names, + &types); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10, ("Could not lookup group members for %s: %s\n", + name, nt_errstr(result))); + goto done; + } + + for (i=0; i<num_names; i++) { + DEBUG(10, ("Adding group member SID %s\n", + sid_string_static(&sid_mem[i]))); + + if (types[i] != SID_NAME_USER) { + DEBUG(1, ("Hmmm. Member %s of group %s is no user. " + "Ignoring.\n", names[i], name)); + continue; + } + + add_member(domain->name, names[i], pp_members, p_num_members); + } + + done: + talloc_destroy(mem_ctx); + return; +} + +static BOOL fill_passdb_alias_grmem(struct winbindd_domain *domain, + DOM_SID *group_sid, + size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len) +{ + DOM_SID *members; + size_t i, num_members; + + *num_gr_mem = 0; + *gr_mem = NULL; + *gr_mem_len = 0; + + if (!NT_STATUS_IS_OK(pdb_enum_aliasmem(group_sid, &members, + &num_members))) + return True; + + for (i=0; i<num_members; i++) { + add_expanded_sid(&members[i], gr_mem, num_gr_mem); + } + + SAFE_FREE(members); + + if (*gr_mem != NULL) { + size_t len; + + /* We have at least one member, strip off the last "," */ + len = strlen(*gr_mem); + (*gr_mem)[len-1] = '\0'; + *gr_mem_len = len; + } + + return True; +} /* Fill a grent structure from various other information */ |