diff options
-rw-r--r-- | source3/winbindd/winbindd_msrpc.c | 106 |
1 files changed, 51 insertions, 55 deletions
diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c index 586a018b26..c60e24967f 100644 --- a/source3/winbindd/winbindd_msrpc.c +++ b/source3/winbindd/winbindd_msrpc.c @@ -460,33 +460,36 @@ done: } /* Lookup groups a user is a member of. I wish Unix had a call like this! */ -static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - const struct dom_sid *user_sid, - uint32 *num_groups, struct dom_sid **user_grpsids) +static NTSTATUS msrpc_lookup_usergroups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + const struct dom_sid *user_sid, + uint32_t *pnum_groups, + struct dom_sid **puser_grpsids) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - struct policy_handle dom_pol, user_pol; - uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED; - struct samr_RidWithAttributeArray *rid_array = NULL; - unsigned int i; - uint32 user_rid; - struct rpc_pipe_client *cli; - - DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid))); + struct rpc_pipe_client *samr_pipe; + struct policy_handle dom_pol; + struct dom_sid *user_grpsids = NULL; + uint32_t num_groups = 0; + TALLOC_CTX *tmp_ctx; + NTSTATUS status; - if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) - return NT_STATUS_UNSUCCESSFUL; + DEBUG(3,("msrpc_lookup_usergroups sid=%s\n", sid_string_dbg(user_sid))); - *num_groups = 0; - *user_grpsids = NULL; + *pnum_groups = 0; - /* so lets see if we have a cached user_info_3 */ - result = lookup_usergroups_cached(domain, mem_ctx, user_sid, - num_groups, user_grpsids); + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } - if (NT_STATUS_IS_OK(result)) { - return NT_STATUS_OK; + /* Check if we have a cached user_info_3 */ + status = lookup_usergroups_cached(domain, + tmp_ctx, + user_sid, + &num_groups, + &user_grpsids); + if (NT_STATUS_IS_OK(status)) { + goto cached; } if ( !winbindd_can_contact_domain( domain ) ) { @@ -494,46 +497,39 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, domain->name)); /* Tell the cache manager not to remember this one */ - - return NT_STATUS_SYNCHRONIZATION_REQUIRED; + status = NT_STATUS_SYNCHRONIZATION_REQUIRED; + goto done; } /* no cache; hit the wire */ + status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } - result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); - if (!NT_STATUS_IS_OK(result)) - return result; - - /* Get user handle */ - result = rpccli_samr_OpenUser(cli, mem_ctx, - &dom_pol, - des_access, - user_rid, - &user_pol); - - if (!NT_STATUS_IS_OK(result)) - return result; - - /* Query user rids */ - result = rpccli_samr_GetGroupsForUser(cli, mem_ctx, - &user_pol, - &rid_array); - *num_groups = rid_array->count; - - rpccli_samr_Close(cli, mem_ctx, &user_pol); - - if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) - return result; + status = rpc_lookup_usergroups(tmp_ctx, + samr_pipe, + &dom_pol, + &domain->sid, + user_sid, + &num_groups, + &user_grpsids); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } - (*user_grpsids) = TALLOC_ARRAY(mem_ctx, struct dom_sid, *num_groups); - if (!(*user_grpsids)) - return NT_STATUS_NO_MEMORY; +cached: + if (pnum_groups) { + *pnum_groups = num_groups; + } - for (i=0;i<(*num_groups);i++) { - sid_compose(&((*user_grpsids)[i]), &domain->sid, - rid_array->rids[i].rid); + if (puser_grpsids) { + *puser_grpsids = talloc_move(mem_ctx, &user_grpsids); } +done: + TALLOC_FREE(tmp_ctx); + return status; return NT_STATUS_OK; } @@ -1236,7 +1232,7 @@ struct winbindd_methods msrpc_methods = { msrpc_sid_to_name, msrpc_rids_to_names, msrpc_query_user, - lookup_usergroups, + msrpc_lookup_usergroups, msrpc_lookup_useraliases, lookup_groupmem, sequence_number, |