diff options
-rw-r--r-- | source3/nsswitch/winbindd.h | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 12 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 16 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_proto.h | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 62 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 56 |
6 files changed, 83 insertions, 72 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 01d334d4eb..e290796e67 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -116,6 +116,11 @@ struct winbindd_methods { TALLOC_CTX *mem_ctx, const char *user_name, uint32 user_rid, WINBIND_USERINFO *user_info); + + NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 user_rid, uint32 *num_groups, + uint32 **user_gids); }; /* Structures to hold per domain information */ diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index d86c498cfe..a1c34bee66 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -341,6 +341,15 @@ error: return NT_STATUS_UNSUCCESSFUL; } +/* Lookup groups a user is a member of. */ +static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, + uint32 user_rid, uint32 *num_groups, + uint32 **user_gids) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + /* the ADS backend methods are exposed via this structure */ struct winbindd_methods ads_methods = { query_user_list, @@ -350,7 +359,8 @@ struct winbindd_methods ads_methods = { and MS servers always allow RPC for this (even in native mode) so just use RPC for sid_to_name. Maybe that's why they allow it? */ winbindd_rpc_sid_to_name, - query_user + query_user, + lookup_usergroups }; #endif diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 07f30f0acc..9d29fee67c 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -918,7 +918,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) DOM_SID user_sid; enum SID_NAME_USE name_type; uint32 user_rid, num_groups, num_gids; - DOM_GID *user_groups = NULL; + NTSTATUS status; + uint32 *user_gids; struct winbindd_domain *domain; enum winbindd_result result = WINBINDD_ERROR; gid_t *gid_list; @@ -967,9 +968,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) sid_split_rid(&user_sid, &user_rid); - if (!winbindd_lookup_usergroups(domain, mem_ctx, user_rid, - &num_groups, &user_groups)) - goto done; + status = domain->methods->lookup_usergroups(domain, mem_ctx, user_rid, &num_groups, &user_gids); + if (!NT_STATUS_IS_OK(status)) goto done; /* Copy data back to client */ @@ -980,12 +980,8 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) goto done; for (i = 0; i < num_groups; i++) { - if (!winbindd_idmap_get_gid_from_rid( - domain->name, user_groups[i].g_rid, - &gid_list[num_gids])) { - - DEBUG(1, ("unable to convert group rid %d to gid\n", - user_groups[i].g_rid)); + if (!winbindd_idmap_get_gid_from_rid(domain->name, user_gids[i], &gid_list[num_gids])) { + DEBUG(1, ("unable to convert group rid %d to gid\n", user_gids[i])); continue; } diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h index 1d553fdceb..503f8b4267 100644 --- a/source3/nsswitch/winbindd_proto.h +++ b/source3/nsswitch/winbindd_proto.h @@ -145,10 +145,6 @@ BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain, BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name, enum SID_NAME_USE *type); -BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 user_rid, uint32 *num_groups, - DOM_GID **user_groups); BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 group_rid, uint32 *num_names, diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index b92e456185..f7d8253fd0 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -240,6 +240,65 @@ static NTSTATUS query_user(struct winbindd_domain *domain, return result; } +/* 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, + uint32 user_rid, uint32 *num_groups, + uint32 **user_gids) +{ + CLI_POLICY_HND *hnd; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + POLICY_HND dom_pol, user_pol; + uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; + BOOL got_dom_pol = False, got_user_pol = False; + DOM_GID *user_groups; + int i; + + /* Get sam handle */ + if (!(hnd = cm_get_sam_handle(domain->name))) + goto done; + + /* Get domain handle */ + result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, + des_access, &domain->sid, &dom_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + got_dom_pol = True; + + /* Get user handle */ + result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, + des_access, user_rid, &user_pol); + + if (!NT_STATUS_IS_OK(result)) + goto done; + + got_user_pol = True; + + /* Query user rids */ + result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol, + num_groups, &user_groups); + + if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) + goto done; + + (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups)); + for (i=0;i<(*num_groups);i++) { + (*user_gids)[i] = user_groups[i].g_rid; + } + + done: + /* Clean up policy handles */ + if (got_user_pol) + cli_samr_close(hnd->cli, mem_ctx, &user_pol); + + if (got_dom_pol) + cli_samr_close(hnd->cli, mem_ctx, &dom_pol); + + return result; +} + /* the rpc backend methods are exposed via this structure */ struct winbindd_methods msrpc_methods = { @@ -247,6 +306,7 @@ struct winbindd_methods msrpc_methods = { enum_dom_groups, name_to_sid, winbindd_rpc_sid_to_name, - query_user + query_user, + lookup_usergroups }; diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index d6f4ca0bcf..d91b6cc95f 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -478,62 +478,6 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, return rv; } -/* Lookup groups a user is a member of. I wish Unix had a call like this! */ - -BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, - uint32 user_rid, uint32 *num_groups, - DOM_GID **user_groups) -{ - CLI_POLICY_HND *hnd; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - POLICY_HND dom_pol, user_pol; - uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; - BOOL got_dom_pol = False, got_user_pol = False; - - /* Get sam handle */ - - if (!(hnd = cm_get_sam_handle(domain->name))) - goto done; - - /* Get domain handle */ - - result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol, - des_access, &domain->sid, &dom_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_dom_pol = True; - - /* Get user handle */ - - result = cli_samr_open_user(hnd->cli, mem_ctx, &dom_pol, - des_access, user_rid, &user_pol); - - if (!NT_STATUS_IS_OK(result)) - goto done; - - got_user_pol = True; - - /* Query user rids */ - - result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &user_pol, - num_groups, user_groups); - - done: - - /* Clean up policy handles */ - - if (got_user_pol) - cli_samr_close(hnd->cli, mem_ctx, &user_pol); - - if (got_dom_pol) - cli_samr_close(hnd->cli, mem_ctx, &dom_pol); - - return NT_STATUS_IS_OK(result); -} - /* Lookup group membership given a rid. */ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain, |