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,  | 
