summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/winbindd.h5
-rw-r--r--source3/nsswitch/winbindd_ads.c12
-rw-r--r--source3/nsswitch/winbindd_group.c16
-rw-r--r--source3/nsswitch/winbindd_proto.h4
-rw-r--r--source3/nsswitch/winbindd_rpc.c62
-rw-r--r--source3/nsswitch/winbindd_util.c56
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,