diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd.h | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 66 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 2 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 4 |
4 files changed, 69 insertions, 8 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index e290796e67..a00bf54cad 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -117,10 +117,11 @@ struct winbindd_methods { const char *user_name, uint32 user_rid, WINBIND_USERINFO *user_info); + /* the backend can also choose for this function */ NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 user_rid, uint32 *num_groups, - uint32 **user_gids); + const char *user_name, 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 a1c34bee66..1c498d394d 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -344,10 +344,70 @@ error: /* 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) + const char *user_name, uint32 user_rid, + uint32 *num_groups, uint32 **user_gids) { - return NT_STATUS_NOT_IMPLEMENTED; + ADS_STRUCT *ads; + const char *attrs[] = {"distinguishedName", NULL}; + const char *attrs2[] = {"tokenGroups", "primaryGroupID", NULL}; + int rc, count; + void *msg; + char *exp; + char *user_dn; + DOM_SID *sids; + int i; + uint32 primary_group; + + DEBUG(3,("ads: lookup_usergroups\n")); + + (*num_groups) = 0; + + ads = ads_init(NULL, NULL, NULL); + if (!ads) { + DEBUG(1,("ads_init failed\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + rc = ads_connect(ads); + if (rc) { + DEBUG(1,("lookup_usergroups ads_connect: %s\n", ads_errstr(rc))); + return NT_STATUS_UNSUCCESSFUL; + } + + asprintf(&exp, "(sAMAccountName=%s)", user_name); + rc = ads_search(ads, &msg, exp, attrs); + free(exp); + if (rc) { + DEBUG(1,("lookup_usergroups(%s) ads_search: %s\n", user_name, ads_errstr(rc))); + return NT_STATUS_UNSUCCESSFUL; + } + + user_dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName"); + + rc = ads_search_dn(ads, &msg, user_dn, attrs2); + if (rc) { + DEBUG(1,("lookup_usergroups(%s) ads_search tokenGroups: %s\n", user_name, ads_errstr(rc))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group)) { + DEBUG(1,("No primary group for %s !?\n", user_name)); + return NT_STATUS_UNSUCCESSFUL; + } + + count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids) + 1; + (*user_gids) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * count); + (*user_gids)[(*num_groups)++] = primary_group; + + for (i=1;i<count;i++) { + uint32 rid; + if (!sid_peek_rid(&sids[i-1], &rid)) continue; + (*user_gids)[*num_groups] = rid; + (*num_groups)++; + } + + ads_destroy(&ads); + return NT_STATUS_OK; } /* the ADS backend methods are exposed via this structure */ diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 9d29fee67c..d800456d9d 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -968,7 +968,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state) sid_split_rid(&user_sid, &user_rid); - status = domain->methods->lookup_usergroups(domain, mem_ctx, user_rid, &num_groups, &user_gids); + status = domain->methods->lookup_usergroups(domain, mem_ctx, name_user, user_rid, &num_groups, &user_gids); if (!NT_STATUS_IS_OK(status)) goto done; /* Copy data back to client */ diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index f7d8253fd0..d783156815 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -243,8 +243,8 @@ static NTSTATUS query_user(struct winbindd_domain *domain, /* 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) + const char *user_name, uint32 user_rid, + uint32 *num_groups, uint32 **user_gids) { CLI_POLICY_HND *hnd; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; |