summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_ads.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_ads.c')
-rw-r--r--source3/nsswitch/winbindd_ads.c66
1 files changed, 63 insertions, 3 deletions
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 */