diff options
Diffstat (limited to 'source4/nsswitch/winbindd_group.c')
-rw-r--r-- | source4/nsswitch/winbindd_group.c | 896 |
1 files changed, 0 insertions, 896 deletions
diff --git a/source4/nsswitch/winbindd_group.c b/source4/nsswitch/winbindd_group.c deleted file mode 100644 index d06db5943c..0000000000 --- a/source4/nsswitch/winbindd_group.c +++ /dev/null @@ -1,896 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind daemon for ntdom nss module - - Copyright (C) Tim Potter 2000 - Copyright (C) Jeremy Allison 2001. - - 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 - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "winbindd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_WINBIND - -/*************************************************************** - Empty static struct for negative caching. -****************************************************************/ - -/* Fill a grent structure from various other information */ - -static BOOL fill_grent(struct winbindd_gr *gr, const char *dom_name, - const char *gr_name, gid_t unix_gid) -{ - fstring full_group_name; - /* Fill in uid/gid */ - fill_domain_username(full_group_name, dom_name, gr_name); - - gr->gr_gid = unix_gid; - - /* Group name and password */ - - safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1); - safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1); - - return True; -} - -/* Fill in the group membership field of a NT group given by group_sid */ - -static BOOL fill_grent_mem(struct winbindd_domain *domain, - DOM_SID *group_sid, - enum SID_NAME_USE group_name_type, - int *num_gr_mem, char **gr_mem, int *gr_mem_len) -{ - DOM_SID **sid_mem = NULL; - uint32 num_names = 0; - uint32 *name_types = NULL; - unsigned int buf_len, buf_ndx, i; - char **names = NULL, *buf; - BOOL result = False; - TALLOC_CTX *mem_ctx; - NTSTATUS status; - fstring sid_string; - - if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name))) - return False; - - /* Initialise group membership information */ - - DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid))); - - *num_gr_mem = 0; - - if (group_name_type != SID_NAME_DOM_GRP) { - DEBUG(1, ("SID %s in domain %s isn't a domain group\n", - sid_to_string(sid_string, group_sid), domain->name)); - goto done; - } - - /* Lookup group members */ - status = domain->methods->lookup_groupmem(domain, mem_ctx, group_sid, &num_names, - &sid_mem, &names, &name_types); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("could not lookup membership for group rid %s in domain %s (error: %s)\n", - sid_to_string(sid_string, group_sid), domain->name, nt_errstr(status))); - - goto done; - } - - DEBUG(10, ("looked up %d names\n", num_names)); - - if (DEBUGLEVEL >= 10) { - for (i = 0; i < num_names; i++) - DEBUG(10, ("\t%20s %s %d\n", names[i], sid_to_string(sid_string, sid_mem[i]), - name_types[i])); - } - - /* Add members to list */ - - buf = NULL; - buf_len = buf_ndx = 0; - - again: - - for (i = 0; i < num_names; i++) { - char *the_name; - fstring name; - int len; - - the_name = names[i]; - - DEBUG(10, ("processing name %s\n", the_name)); - - /* FIXME: need to cope with groups within groups. These - occur in Universal groups on a Windows 2000 native mode - server. */ - - if (name_types[i] != SID_NAME_USER) { - DEBUG(3, ("name %s isn't a domain user\n", the_name)); - continue; - } - - /* Don't bother with machine accounts */ - - if (the_name[strlen(the_name) - 1] == '$') { - DEBUG(10, ("%s is machine account\n", the_name)); - continue; - } - - /* Append domain name */ - - fill_domain_username(name, domain->name, the_name); - - len = strlen(name); - - /* Add to list or calculate buffer length */ - - if (!buf) { - buf_len += len + 1; /* List is comma separated */ - (*num_gr_mem)++; - DEBUG(10, ("buf_len + %d = %d\n", len + 1, buf_len)); - } else { - DEBUG(10, ("appending %s at ndx %d\n", name, len)); - safe_strcpy(&buf[buf_ndx], name, len); - buf_ndx += len; - buf[buf_ndx] = ','; - buf_ndx++; - } - } - - /* Allocate buffer */ - - if (!buf && buf_len != 0) { - if (!(buf = malloc(buf_len))) { - DEBUG(1, ("out of memory\n")); - result = False; - goto done; - } - memset(buf, 0, buf_len); - goto again; - } - - if (buf && buf_ndx > 0) { - buf[buf_ndx - 1] = '\0'; - } - - *gr_mem = buf; - *gr_mem_len = buf_len; - - DEBUG(10, ("num_mem = %d, len = %d, mem = %s\n", *num_gr_mem, - buf_len, *num_gr_mem ? buf : "NULL")); - result = True; - -done: - - talloc_destroy(mem_ctx); - - DEBUG(10, ("fill_grent_mem returning %d\n", result)); - - return result; -} - -/* Return a group structure from a group name */ - -enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) -{ - DOM_SID group_sid; - struct winbindd_domain *domain; - enum SID_NAME_USE name_type; - fstring name_domain, name_group; - char *tmp, *gr_mem; - gid_t gid; - int gr_mem_len; - - /* Ensure null termination */ - state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0'; - - DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid, - state->request.data.groupname)); - - /* Parse domain and groupname */ - - memset(name_group, 0, sizeof(fstring)); - - tmp = state->request.data.groupname; - if (!parse_domain_user(tmp, name_domain, name_group)) - return WINBINDD_ERROR; - - /* Get info for the domain */ - - if ((domain = find_domain_from_name(name_domain)) == NULL) { - DEBUG(0, ("could not get domain sid for domain %s\n", - name_domain)); - return WINBINDD_ERROR; - } - - /* Get rid and name type from name */ - - if (!winbindd_lookup_sid_by_name(domain, name_group, &group_sid, - &name_type)) { - DEBUG(1, ("group %s in domain %s does not exist\n", - name_group, name_domain)); - return WINBINDD_ERROR; - } - - if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) { - DEBUG(1, ("name '%s' is not a local or domain group: %d\n", - name_group, name_type)); - return WINBINDD_ERROR; - } - - if (!winbindd_idmap_get_gid_from_sid(&group_sid, &gid)) { - DEBUG(1, ("error converting unix gid to sid\n")); - return WINBINDD_ERROR; - } - - if (!fill_grent(&state->response.data.gr, name_domain, - name_group, gid) || - !fill_grent_mem(domain, &group_sid, name_type, - &state->response.data.gr.num_gr_mem, - &gr_mem, &gr_mem_len)) { - return WINBINDD_ERROR; - } - - /* Group membership lives at start of extra data */ - - state->response.data.gr.gr_mem_ofs = 0; - - state->response.length += gr_mem_len; - state->response.extra_data = gr_mem; - - return WINBINDD_OK; -} - -/* Return a group structure from a gid number */ - -enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state) -{ - struct winbindd_domain *domain; - DOM_SID group_sid; - enum SID_NAME_USE name_type; - fstring dom_name; - fstring group_name; - int gr_mem_len; - char *gr_mem; - - DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid, - state->request.data.gid)); - - /* Bug out if the gid isn't in the winbind range */ - - if ((state->request.data.gid < server_state.gid_low) || - (state->request.data.gid > server_state.gid_high)) - return WINBINDD_ERROR; - - /* Get rid from gid */ - - if (!winbindd_idmap_get_sid_from_gid(state->request.data.gid, &group_sid)) { - DEBUG(1, ("could not convert gid %d to rid\n", - state->request.data.gid)); - return WINBINDD_ERROR; - } - - /* Get name from sid */ - - if (!winbindd_lookup_name_by_sid(&group_sid, dom_name, group_name, &name_type)) { - DEBUG(1, ("could not lookup sid\n")); - return WINBINDD_ERROR; - } - - if (!((name_type == SID_NAME_ALIAS) || - (name_type == SID_NAME_DOM_GRP))) { - DEBUG(1, ("name '%s' is not a local or domain group: %d\n", - group_name, name_type)); - return WINBINDD_ERROR; - } - - /* Fill in group structure */ - - domain = find_domain_from_sid(&group_sid); - - if (!domain) { - DEBUG(1,("Can't find domain from sid\n")); - return WINBINDD_ERROR; - } - - if (!fill_grent(&state->response.data.gr, dom_name, group_name, - state->request.data.gid) || - !fill_grent_mem(domain, &group_sid, name_type, - &state->response.data.gr.num_gr_mem, - &gr_mem, &gr_mem_len)) - return WINBINDD_ERROR; - - /* Group membership lives at start of extra data */ - - state->response.data.gr.gr_mem_ofs = 0; - - state->response.length += gr_mem_len; - state->response.extra_data = gr_mem; - - return WINBINDD_OK; -} - -/* - * set/get/endgrent functions - */ - -/* "Rewind" file pointer for group database enumeration */ - -enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state) -{ - struct winbindd_domain *domain; - - DEBUG(3, ("[%5d]: setgrent\n", state->pid)); - - /* Check user has enabled this */ - - if (!lp_winbind_enum_groups()) - return WINBINDD_ERROR; - - /* Free old static data if it exists */ - - if (state->getgrent_state != NULL) { - free_getent_state(state->getgrent_state); - state->getgrent_state = NULL; - } - - /* Create sam pipes for each domain we know about */ - - for (domain = domain_list(); domain != NULL; domain = domain->next) { - struct getent_state *domain_state; - - /* Create a state record for this domain */ - - if ((domain_state = (struct getent_state *) - malloc(sizeof(struct getent_state))) == NULL) { - DEBUG(1, ("winbindd_setgrent: malloc failed for domain_state!\n")); - return WINBINDD_ERROR; - } - - ZERO_STRUCTP(domain_state); - - fstrcpy(domain_state->domain_name, domain->name); - - /* Add to list of open domains */ - - DLIST_ADD(state->getgrent_state, domain_state); - } - - return WINBINDD_OK; -} - -/* Close file pointer to ntdom group database */ - -enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) -{ - DEBUG(3, ("[%5d]: endgrent\n", state->pid)); - - free_getent_state(state->getgrent_state); - state->getgrent_state = NULL; - - return WINBINDD_OK; -} - -/* Get the list of domain groups and domain aliases for a domain. We fill in - the sam_entries and num_sam_entries fields with domain group information. - The dispinfo_ndx field is incremented to the index of the next group to - fetch. Return True if some groups were returned, False otherwise. */ - -#define MAX_FETCH_SAM_ENTRIES 100 - -static BOOL get_sam_group_entries(struct getent_state *ent) -{ - NTSTATUS status; - uint32 num_entries; - struct acct_info *name_list = NULL, *tmp_name_list = NULL; - TALLOC_CTX *mem_ctx; - BOOL result = False; - struct acct_info *sam_grp_entries = NULL; - struct winbindd_domain *domain; - - if (ent->got_sam_entries) - return False; - - if (!(mem_ctx = talloc_init("get_sam_group_entries(%s)", - ent->domain_name))) { - DEBUG(1, ("get_sam_group_entries: could not create talloc context!\n")); - return False; - } - - /* Free any existing group info */ - - SAFE_FREE(ent->sam_entries); - ent->num_sam_entries = 0; - ent->got_sam_entries = True; - - /* Enumerate domain groups */ - - num_entries = 0; - - if (!(domain = find_domain_from_name(ent->domain_name))) { - DEBUG(3, ("no such domain %s in get_sam_group_entries\n", ent->domain_name)); - goto done; - } - - /* always get the domain global groups */ - - status = domain->methods->enum_dom_groups(domain, mem_ctx, &num_entries, &sam_grp_entries); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("get_sam_group_entries: could not enumerate domain groups! Error: %s\n", nt_errstr(status))); - result = False; - goto done; - } - - /* Copy entries into return buffer */ - - if (num_entries) { - if ( !(name_list = malloc(sizeof(struct acct_info) * num_entries)) ) { - DEBUG(0,("get_sam_group_entries: Failed to malloc memory for %d domain groups!\n", - num_entries)); - result = False; - goto done; - } - memcpy( name_list, sam_grp_entries, num_entries * sizeof(struct acct_info) ); - } - - ent->num_sam_entries = num_entries; - - /* get the domain local groups if we are a member of - a native win2k domain */ - - if ( domain->native_mode && domain->methods->enum_local_groups ) - { - DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n")); - - status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries); - - if ( !NT_STATUS_IS_OK(status) ) { - DEBUG(3,("get_sam_group_entries: Failed to enumerate domain local groups!\n")); - num_entries = 0; - } - else - DEBUG(4,("get_sam_group_entries: Returned %d local groups\n", num_entries)); - - /* Copy entries into return buffer */ - - if ( num_entries ) { - if ( !(tmp_name_list = Realloc( name_list, sizeof(struct acct_info) * (ent->num_sam_entries+num_entries))) ) - { - DEBUG(0,("get_sam_group_entries: Failed to realloc more memory for %d local groups!\n", - num_entries)); - result = False; - SAFE_FREE( name_list ); - goto done; - } - - name_list = tmp_name_list; - - memcpy( &name_list[ent->num_sam_entries], sam_grp_entries, - num_entries * sizeof(struct acct_info) ); - } - - ent->num_sam_entries += num_entries; - } - - - /* Fill in remaining fields */ - - ent->sam_entries = name_list; - ent->sam_entry_index = 0; - - result = (ent->num_sam_entries > 0); - - done: - talloc_destroy(mem_ctx); - - return result; -} - -/* Fetch next group entry from ntdom database */ - -#define MAX_GETGRENT_GROUPS 500 - -enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) -{ - struct getent_state *ent; - struct winbindd_gr *group_list = NULL; - int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0; - char *new_extra_data, *gr_mem_list = NULL; - - DEBUG(3, ("[%5d]: getgrent\n", state->pid)); - - /* Check user has enabled this */ - - if (!lp_winbind_enum_groups()) - return WINBINDD_ERROR; - - num_groups = MIN(MAX_GETGRENT_GROUPS, state->request.data.num_entries); - - if ((state->response.extra_data = - malloc(num_groups * sizeof(struct winbindd_gr))) == NULL) - return WINBINDD_ERROR; - - state->response.data.num_entries = 0; - - group_list = (struct winbindd_gr *)state->response.extra_data; - - if (!(ent = state->getgrent_state)) - return WINBINDD_ERROR; - - /* Start sending back groups */ - - for (i = 0; i < num_groups; i++) { - struct acct_info *name_list = NULL; - fstring domain_group_name; - uint32 result; - gid_t group_gid; - int gr_mem_len; - char *gr_mem, *new_gr_mem_list; - DOM_SID group_sid; - struct winbindd_domain *domain; - - /* Do we need to fetch another chunk of groups? */ - - tryagain: - - DEBUG(10, ("entry_index = %d, num_entries = %d\n", - ent->sam_entry_index, ent->num_sam_entries)); - - if (ent->num_sam_entries == ent->sam_entry_index) { - - while(ent && !get_sam_group_entries(ent)) { - struct getent_state *next_ent; - - DEBUG(10, ("freeing state info for domain %s\n", ent->domain_name)); - - /* Free state information for this domain */ - - SAFE_FREE(ent->sam_entries); - - next_ent = ent->next; - DLIST_REMOVE(state->getgrent_state, ent); - - SAFE_FREE(ent); - ent = next_ent; - } - - /* No more domains */ - - if (!ent) - break; - } - - name_list = ent->sam_entries; - - if (!(domain = - find_domain_from_name(ent->domain_name))) { - DEBUG(3, ("No such domain %s in winbindd_getgrent\n", ent->domain_name)); - result = False; - goto done; - } - - /* Lookup group info */ - - sid_copy(&group_sid, &domain->sid); - sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid); - - if (!winbindd_idmap_get_gid_from_sid( - &group_sid, - &group_gid)) { - - DEBUG(1, ("could not look up gid for group %s\n", - name_list[ent->sam_entry_index].acct_name)); - - ent->sam_entry_index++; - goto tryagain; - } - - DEBUG(10, ("got gid %d for group %x\n", group_gid, - name_list[ent->sam_entry_index].rid)); - - /* Fill in group entry */ - - fill_domain_username(domain_group_name, ent->domain_name, - name_list[ent->sam_entry_index].acct_name); - - result = fill_grent(&group_list[group_list_ndx], - ent->domain_name, - name_list[ent->sam_entry_index].acct_name, - group_gid); - - /* Fill in group membership entry */ - - if (result) { - DOM_SID member_sid; - group_list[group_list_ndx].num_gr_mem = 0; - gr_mem = NULL; - gr_mem_len = 0; - - /* Get group membership */ - if (state->request.cmd == WINBINDD_GETGRLST) { - result = True; - } else { - sid_copy(&member_sid, &domain->sid); - sid_append_rid(&member_sid, name_list[ent->sam_entry_index].rid); - result = fill_grent_mem( - domain, - &member_sid, - SID_NAME_DOM_GRP, - &group_list[group_list_ndx].num_gr_mem, - &gr_mem, &gr_mem_len); - } - } - - if (result) { - /* Append to group membership list */ - new_gr_mem_list = Realloc( - gr_mem_list, - gr_mem_list_len + gr_mem_len); - - if (!new_gr_mem_list && (group_list[group_list_ndx].num_gr_mem != 0)) { - DEBUG(0, ("out of memory\n")); - SAFE_FREE(gr_mem_list); - gr_mem_list_len = 0; - break; - } - - DEBUG(10, ("list_len = %d, mem_len = %d\n", - gr_mem_list_len, gr_mem_len)); - - gr_mem_list = new_gr_mem_list; - - memcpy(&gr_mem_list[gr_mem_list_len], gr_mem, - gr_mem_len); - - SAFE_FREE(gr_mem); - - group_list[group_list_ndx].gr_mem_ofs = - gr_mem_list_len; - - gr_mem_list_len += gr_mem_len; - } - - ent->sam_entry_index++; - - /* Add group to return list */ - - if (result) { - - DEBUG(10, ("adding group num_entries = %d\n", - state->response.data.num_entries)); - - group_list_ndx++; - state->response.data.num_entries++; - - state->response.length += - sizeof(struct winbindd_gr); - - } else { - DEBUG(0, ("could not lookup domain group %s\n", - domain_group_name)); - } - } - - /* Copy the list of group memberships to the end of the extra data */ - - if (group_list_ndx == 0) - goto done; - - new_extra_data = Realloc( - state->response.extra_data, - group_list_ndx * sizeof(struct winbindd_gr) + gr_mem_list_len); - - if (!new_extra_data) { - DEBUG(0, ("out of memory\n")); - group_list_ndx = 0; - SAFE_FREE(state->response.extra_data); - SAFE_FREE(gr_mem_list); - - return WINBINDD_ERROR; - } - - state->response.extra_data = new_extra_data; - - memcpy(&((char *)state->response.extra_data) - [group_list_ndx * sizeof(struct winbindd_gr)], - gr_mem_list, gr_mem_list_len); - - SAFE_FREE(gr_mem_list); - - state->response.length += gr_mem_list_len; - - DEBUG(10, ("returning %d groups, length = %d\n", - group_list_ndx, gr_mem_list_len)); - - /* Out of domains */ - - done: - - return (group_list_ndx > 0) ? WINBINDD_OK : WINBINDD_ERROR; -} - -/* List domain groups without mapping to unix ids */ - -enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) -{ - uint32 total_entries = 0; - struct winbindd_domain *domain; - char *extra_data = NULL; - char *ted = NULL; - unsigned int extra_data_len = 0, i; - - DEBUG(3, ("[%5d]: list groups\n", state->pid)); - - /* Enumerate over trusted domains */ - - for (domain = domain_list(); domain; domain = domain->next) { - struct getent_state groups; - - ZERO_STRUCT(groups); - - /* Get list of sam groups */ - ZERO_STRUCT(groups); - fstrcpy(groups.domain_name, domain->name); - - get_sam_group_entries(&groups); - - if (groups.num_sam_entries == 0) { - /* this domain is empty or in an error state */ - continue; - } - - /* keep track the of the total number of groups seen so - far over all domains */ - total_entries += groups.num_sam_entries; - - /* Allocate some memory for extra data. Note that we limit - account names to sizeof(fstring) = 128 characters. */ - ted = Realloc(extra_data, sizeof(fstring) * total_entries); - - if (!ted) { - DEBUG(0,("failed to enlarge buffer!\n")); - SAFE_FREE(extra_data); - return WINBINDD_ERROR; - } else - extra_data = ted; - - /* Pack group list into extra data fields */ - for (i = 0; i < groups.num_sam_entries; i++) { - char *group_name = ((struct acct_info *) - groups.sam_entries)[i].acct_name; - fstring name; - - fill_domain_username(name, domain->name, group_name); - /* Append to extra data */ - memcpy(&extra_data[extra_data_len], name, - strlen(name)); - extra_data_len += strlen(name); - extra_data[extra_data_len++] = ','; - } - - free(groups.sam_entries); - } - - /* Assign extra_data fields in response structure */ - if (extra_data) { - extra_data[extra_data_len - 1] = '\0'; - state->response.extra_data = extra_data; - state->response.length += extra_data_len; - } - - /* No domains may have responded but that's still OK so don't - return an error. */ - - return WINBINDD_OK; -} - -/* Get user supplementary groups. This is much quicker than trying to - invert the groups database. */ - -enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) -{ - fstring name_domain, name_user; - DOM_SID user_sid; - enum SID_NAME_USE name_type; - uint32 num_groups, num_gids; - NTSTATUS status; - DOM_SID **user_gids; - struct winbindd_domain *domain; - enum winbindd_result result = WINBINDD_ERROR; - gid_t *gid_list; - unsigned int i; - TALLOC_CTX *mem_ctx; - - /* Ensure null termination */ - state->request.data.username[sizeof(state->request.data.username)-1]='\0'; - - DEBUG(3, ("[%5d]: getgroups %s\n", state->pid, - state->request.data.username)); - - if (!(mem_ctx = talloc_init("winbindd_getgroups(%s)", - state->request.data.username))) - return WINBINDD_ERROR; - - /* Parse domain and username */ - - if (!parse_domain_user(state->request.data.username, name_domain, - name_user)) - goto done; - - /* Get info for the domain */ - - if ((domain = find_domain_from_name(name_domain)) == NULL) { - DEBUG(0, ("could not find domain entry for domain %s\n", - name_domain)); - goto done; - } - - /* Get rid and name type from name. The following costs 1 packet */ - - if (!winbindd_lookup_sid_by_name(domain, name_user, &user_sid, - &name_type)) { - DEBUG(1, ("user '%s' does not exist\n", name_user)); - goto done; - } - - if (name_type != SID_NAME_USER) { - DEBUG(1, ("name '%s' is not a user name: %d\n", - name_user, name_type)); - goto done; - } - - status = domain->methods->lookup_usergroups(domain, mem_ctx, - &user_sid, &num_groups, - &user_gids); - if (!NT_STATUS_IS_OK(status)) goto done; - - /* Copy data back to client */ - - num_gids = 0; - gid_list = malloc(sizeof(gid_t) * num_groups); - - if (state->response.extra_data) - goto done; - - for (i = 0; i < num_groups; i++) { - if (!winbindd_idmap_get_gid_from_sid( - user_gids[i], - &gid_list[num_gids])) { - fstring sid_string; - - DEBUG(1, ("unable to convert group sid %s to gid\n", - sid_to_string(sid_string, user_gids[i]))); - continue; - } - - num_gids++; - } - - state->response.data.num_entries = num_gids; - state->response.extra_data = gid_list; - state->response.length += num_gids * sizeof(gid_t); - - result = WINBINDD_OK; - - done: - - talloc_destroy(mem_ctx); - - return result; -} |