[SSSD] [sssd PR#5784][synchronized] proxy: allow removing group members

2021-10-21 Thread ikerexxe
   URL: https://github.com/SSSD/sssd/pull/5784
Author: ikerexxe
 Title: #5784: proxy: allow removing group members
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5784/head:pr5784
git checkout pr5784
From 2fc3e52dcff272b90bab31a8ff4acbeb1fd2f0f4 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa 
Date: Tue, 14 Sep 2021 12:35:09 +0200
Subject: [PATCH] proxy: allow removing group members

The proxy provider doesn't allow to remove group members once they have
been added. This patch allows to do it by looping the member list from
the cache and comparing it with the actual membership list. If a member
is missing then it's removed from the cache.

Resolves: https://github.com/SSSD/sssd/issues/5783

Signed-off-by: Iker Pedrosa 
---
 src/providers/proxy/proxy_id.c | 159 -
 1 file changed, 157 insertions(+), 2 deletions(-)

diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 25daea585d..db6bbb2f0f 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -908,6 +908,10 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 struct sss_domain_info *dom,
 bool *delete_group)
 {
+if (delete_group) {
+*delete_group = false;
+}
+
 switch (status) {
 case NSS_STATUS_TRYAGAIN:
 DEBUG(SSSDBG_MINOR_FAILURE, "Buffer too small\n");
@@ -915,7 +919,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 
 case NSS_STATUS_NOTFOUND:
 DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 
 case NSS_STATUS_SUCCESS:
@@ -927,7 +933,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) {
 DEBUG(SSSDBG_MINOR_FAILURE,
   "Group filtered out! (id out of range)\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 }
 break;
@@ -1488,6 +1496,141 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
 return ret;
 }
 
+static int remove_group_members(struct proxy_id_ctx *ctx,
+struct sss_domain_info *dom,
+const struct passwd *pwd,
+long int num_gids,
+const gid_t *gids,
+long int num_cached_gids,
+const gid_t *cached_gids)
+{
+TALLOC_CTX *tmp_ctx = NULL;
+int i = 0, j = 0;
+int ret = EOK;
+const char *groupname = NULL;
+const char *username = NULL;
+bool group_found = false;
+struct ldb_result *res = NULL;
+
+tmp_ctx = talloc_new(NULL);
+if (!tmp_ctx) {
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+return ENOMEM;
+}
+
+username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name);
+if (username == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name);
+ret = ENOMEM;
+goto done;
+}
+
+for (i = 0; i < num_cached_gids; i++) {
+group_found = false;
+/* group 0 is the primary group so it can be skipped */
+for (j = 1; j < num_gids; j++) {
+if (cached_gids[i] == gids[j]) {
+group_found = true;
+break;
+}
+}
+
+if (!group_found) {
+ret = sysdb_getgrgid(tmp_ctx, dom, cached_gids[i], &res);
+if (ret != EOK || res->count != 1) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "sysdb_getgrgid failed for GID [%d].\n", cached_gids[i]);
+continue;
+}
+
+groupname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
+if (groupname == NULL) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "Attribute is missing but this should never happen!\n");
+continue;
+}
+
+ret = sysdb_remove_group_member(dom, groupname,
+username,
+SYSDB_MEMBER_USER, false);
+if (ret != EOK) {
+DEBUG(SSSDBG_CRIT_FAILURE,
+  "Could not remove member [%s] from group [%s]\n",
+  username, groupname);
+continue;
+}
+}
+}
+
+ret = EOK;
+
+done:
+talloc_free(tmp_ctx);
+return ret;
+}
+
+static int get_cached_user_groups(struct sysdb_ctx *sysdb,
+  struct sss_domain_info *dom,
+  const struct passwd *pwd,
+  unsigned 

[SSSD] [sssd PR#5784][synchronized] proxy: allow removing group members

2021-10-21 Thread ikerexxe
   URL: https://github.com/SSSD/sssd/pull/5784
Author: ikerexxe
 Title: #5784: proxy: allow removing group members
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5784/head:pr5784
git checkout pr5784
From 035de7e2b1efd72ba91c40295518bd30ea16b94d Mon Sep 17 00:00:00 2001
From: Iker Pedrosa 
Date: Tue, 14 Sep 2021 12:35:09 +0200
Subject: [PATCH] proxy: allow removing group members

The proxy provider doesn't allow to remove group members once they have
been added. This patch allows to do it by looping the member list from
the cache and comparing it with the actual membership list. If a member
is missing then it's removed from the cache.

Resolves: https://github.com/SSSD/sssd/issues/5783

Signed-off-by: Iker Pedrosa 
---
 src/providers/proxy/proxy_id.c | 154 -
 1 file changed, 152 insertions(+), 2 deletions(-)

diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 25daea585d..ae810442ce 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -908,6 +908,10 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 struct sss_domain_info *dom,
 bool *delete_group)
 {
+if (delete_group) {
+*delete_group = false;
+}
+
 switch (status) {
 case NSS_STATUS_TRYAGAIN:
 DEBUG(SSSDBG_MINOR_FAILURE, "Buffer too small\n");
@@ -915,7 +919,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 
 case NSS_STATUS_NOTFOUND:
 DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 
 case NSS_STATUS_SUCCESS:
@@ -927,7 +933,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) {
 DEBUG(SSSDBG_MINOR_FAILURE,
   "Group filtered out! (id out of range)\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 }
 break;
@@ -1488,6 +1496,136 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
 return ret;
 }
 
+static int remove_group_members(struct proxy_id_ctx *ctx,
+struct sss_domain_info *dom,
+const struct passwd *pwd,
+long int num_gids,
+const gid_t *gids,
+long int num_cached_gids,
+const gid_t *cached_gids)
+{
+TALLOC_CTX *tmp_ctx = NULL;
+int i = 0, j = 0;
+int ret = EOK;
+const char *groupname = NULL;
+const char *username = NULL;
+bool group_found = false;
+struct ldb_result *res = NULL;
+
+tmp_ctx = talloc_new(NULL);
+if (!tmp_ctx) {
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+return ENOMEM;
+}
+
+username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name);
+if (username == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name);
+ret = ENOMEM;
+goto done;
+}
+
+for (i = 0; i < num_cached_gids; i++) {
+group_found = false;
+/* group 0 is the primary group so it can be skipped */
+for (j = 1; j < num_gids; j++) {
+if (cached_gids[i] == gids[j]) {
+group_found = true;
+break;
+}
+}
+
+if (!group_found) {
+ret = sysdb_getgrgid(tmp_ctx, dom, cached_gids[i], &res);
+if (ret != EOK || res->count != 1) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "sysdb_getgrgid failed for GID [%d].\n", cached_gids[i]);
+continue;
+}
+
+groupname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
+if (groupname == NULL) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "Attribute is missing but this should never happen!\n");
+continue;
+}
+
+ret = sysdb_remove_group_member(dom, groupname,
+username,
+SYSDB_MEMBER_USER, false);
+if (ret != EOK) {
+DEBUG(SSSDBG_CRIT_FAILURE,
+  "Could not remove member [%s] from group [%s]\n",
+  username, groupname);
+continue;
+}
+}
+}
+
+ret = EOK;
+
+done:
+talloc_free(tmp_ctx);
+return ret;
+}
+
+static int get_cached_user_groups(struct sysdb_ctx *sysdb,
+  struct sss_domain_info *dom,
+  const struct passwd *pwd,
+  unsigned 

[SSSD] [sssd PR#5784][synchronized] proxy: allow removing group members

2021-10-18 Thread ikerexxe
   URL: https://github.com/SSSD/sssd/pull/5784
Author: ikerexxe
 Title: #5784: proxy: allow removing group members
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5784/head:pr5784
git checkout pr5784
From be0584db2c5ff898b9833116cfcda0a57a79415b Mon Sep 17 00:00:00 2001
From: Iker Pedrosa 
Date: Tue, 14 Sep 2021 12:35:09 +0200
Subject: [PATCH] proxy: allow removing group members

The proxy provider doesn't allow to remove group members once they have
been added. This patch allows to do it by looping the member list from
the cache and comparing it with the actual membership list. If a member
is missing then it's removed from the cache.

Resolves: https://github.com/SSSD/sssd/issues/5783

Signed-off-by: Iker Pedrosa 
---
 src/providers/proxy/proxy_id.c | 154 -
 1 file changed, 152 insertions(+), 2 deletions(-)

diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 25daea585d..6196c75020 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -908,6 +908,10 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 struct sss_domain_info *dom,
 bool *delete_group)
 {
+if (delete_group) {
+*delete_group = false;
+}
+
 switch (status) {
 case NSS_STATUS_TRYAGAIN:
 DEBUG(SSSDBG_MINOR_FAILURE, "Buffer too small\n");
@@ -915,7 +919,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 
 case NSS_STATUS_NOTFOUND:
 DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 
 case NSS_STATUS_SUCCESS:
@@ -927,7 +933,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) {
 DEBUG(SSSDBG_MINOR_FAILURE,
   "Group filtered out! (id out of range)\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 }
 break;
@@ -1488,6 +1496,136 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
 return ret;
 }
 
+static int remove_group_members(struct proxy_id_ctx *ctx,
+struct sss_domain_info *dom,
+const struct passwd *pwd,
+long int num_gids,
+const gid_t *gids,
+long int num_cached_gids,
+const gid_t *cached_gids)
+{
+TALLOC_CTX *tmp_ctx = NULL;
+int i = 0, j = 0;
+int ret = EOK;
+const char *groupname = NULL;
+const char *username = NULL;
+bool group_found = false;
+struct ldb_result *res = NULL;
+
+tmp_ctx = talloc_new(NULL);
+if (!tmp_ctx) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+goto done;
+}
+
+username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name);
+if (username == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name);
+ret = ENOMEM;
+goto done;
+}
+
+for (i = 0; i < num_cached_gids; i++) {
+group_found = false;
+/* group 0 is the primary group so it can be skipped */
+for (j = 1; j < num_gids; j++) {
+if (cached_gids[i] == gids[j]) {
+group_found = true;
+break;
+}
+}
+
+if (!group_found) {
+ret = sysdb_getgrgid(tmp_ctx, dom, cached_gids[i], &res);
+if (ret != EOK || res->count != 1) {
+DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrgid failed.\n");
+continue;
+}
+
+groupname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
+if (groupname == NULL) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "Attribute is missing but this should never happen!\n");
+ret = EFAULT;
+continue;
+}
+
+ret = sysdb_remove_group_member(dom, groupname,
+username,
+SYSDB_MEMBER_USER, false);
+
+if (ret != EOK) {
+DEBUG(SSSDBG_CRIT_FAILURE,
+  "Could not remove member [%s] from group [%s]\n",
+  username, groupname);
+continue;
+}
+}
+}
+
+done:
+return ret;
+}
+
+static int get_cached_user_groups(struct sysdb_ctx *sysdb,
+  struct sss_domain_info *dom,
+  const struct passwd *pwd,
+  unsigned int *_num_cached_gids,
+ 

[SSSD] [sssd PR#5784][synchronized] proxy: allow removing group members

2021-10-06 Thread ikerexxe
   URL: https://github.com/SSSD/sssd/pull/5784
Author: ikerexxe
 Title: #5784: proxy: allow removing group members
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5784/head:pr5784
git checkout pr5784
From 9f2cf6abddc352ca894e63c6ebe66687d3dd6abb Mon Sep 17 00:00:00 2001
From: Iker Pedrosa 
Date: Tue, 14 Sep 2021 12:35:09 +0200
Subject: [PATCH] proxy: allow removing group members

The proxy provider doesn't allow to remove group members once they have
been added. This patch allows to do it by looping the member list from
the cache and comparing it with the actual membership list. If a member
is missing then it's removed from the cache.

Resolves: https://github.com/SSSD/sssd/issues/5783

Signed-off-by: Iker Pedrosa 
---
 src/providers/proxy/proxy_id.c | 166 -
 1 file changed, 164 insertions(+), 2 deletions(-)

diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 25daea585d..f7cfe5cf65 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -915,7 +915,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 
 case NSS_STATUS_NOTFOUND:
 DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 
 case NSS_STATUS_SUCCESS:
@@ -927,7 +929,9 @@ handle_getgr_result(enum nss_status status, struct group *grp,
 if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) {
 DEBUG(SSSDBG_MINOR_FAILURE,
   "Group filtered out! (id out of range)\n");
-*delete_group = true;
+if (delete_group) {
+*delete_group = true;
+}
 break;
 }
 break;
@@ -1488,6 +1492,153 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
 return ret;
 }
 
+static int remove_group_members(struct proxy_id_ctx *ctx,
+struct sss_domain_info *dom,
+const struct passwd *pwd,
+long int num_gids,
+const gid_t *gids,
+long int num_cached_gids,
+const gid_t *cached_gids)
+{
+TALLOC_CTX *tmp_ctx = NULL;
+int i = 0, j = 0;
+int ret = EOK;
+size_t buflen = 0;
+char *buffer = NULL;
+char *groupname = NULL;
+const char *username = NULL;
+enum nss_status status;
+struct group *grp = NULL;
+bool group_found = false;
+
+tmp_ctx = talloc_new(NULL);
+if (!tmp_ctx) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+goto done;
+}
+
+username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name);
+if (username == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name);
+ret = ENOMEM;
+goto done;
+}
+
+grp = talloc(tmp_ctx, struct group);
+if (!grp) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc() failed\n");
+goto done;
+}
+
+for (i = 0; i < num_cached_gids; i++) {
+group_found = false;
+// group 0 is the primary group so it can be skipped
+for (j = 1; j < num_gids; j++) {
+if (cached_gids[i] == gids[j]) {
+group_found = true;
+break;
+}
+}
+
+if (!group_found) {
+do {
+/* always zero out the grp structure */
+memset(grp, 0, sizeof(struct group));
+buffer = grow_group_buffer(tmp_ctx, &buffer, &buflen);
+if (!buffer) {
+ret = ENOMEM;
+break;
+}
+
+status = ctx->ops.getgrgid_r(cached_gids[i], grp, buffer, buflen, &ret);
+
+ret = handle_getgr_result(status, grp, dom, NULL);
+} while (ret == EAGAIN);
+
+if (ret != EOK) {
+DEBUG(SSSDBG_OP_FAILURE,
+  "getgrgid failed [%d]: %s\n", ret, strerror(ret));
+continue;
+}
+
+groupname = sss_create_internal_fqname(tmp_ctx, grp->gr_name, dom->name);
+if (groupname == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n",
+  grp->gr_name);
+ret = ENOMEM;
+continue;
+}
+
+ret = sysdb_remove_group_member(dom, groupname,
+username,
+SYSDB_MEMBER_USER, false);
+
+if (ret != EOK) {
+DEBUG(SSSDBG_CRIT_FAILURE,
+  "Could not remove member [%s] from group [%s]\n",
+  username, groupname);
+continue

[SSSD] [sssd PR#5784][synchronized] proxy: allow removing group members

2021-09-16 Thread ikerexxe
   URL: https://github.com/SSSD/sssd/pull/5784
Author: ikerexxe
 Title: #5784: proxy: allow removing group members
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5784/head:pr5784
git checkout pr5784
From 6ef5ac2ef5e06bde5276a2e5be220ed9a3e28890 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa 
Date: Tue, 14 Sep 2021 12:35:09 +0200
Subject: [PATCH] proxy: allow removing group members

The proxy provider doesn't allow to remove group members once they have
been added. This patch allows to do it by looping the member list from
the cache and comparing it with the actual membership list. If a member
is missing then it's removed from the cache.

Resolves: https://github.com/SSSD/sssd/issues/5783

Signed-off-by: Iker Pedrosa 
---
 src/providers/proxy/proxy_id.c | 151 +
 1 file changed, 151 insertions(+)

diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 25daea585d..2c463f3f83 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -1488,6 +1488,152 @@ static int get_initgr(TALLOC_CTX *mem_ctx,
 return ret;
 }
 
+static int compare_group_members(struct proxy_id_ctx *ctx,
+   TALLOC_CTX *tmp_ctx,
+   struct sss_domain_info *dom,
+   long int num_gids,
+   gid_t *gids,
+   char *db_groupname,
+   bool *group_found)
+{
+int j = 0;
+int ret = EOK;
+size_t buflen = 0;
+char *buffer = NULL;
+char *network_groupname = NULL;
+enum nss_status status;
+struct group *grp = NULL;
+bool delete_group = false;
+
+grp = talloc(tmp_ctx, struct group);
+if (!grp) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc() failed\n");
+goto done;
+}
+
+// group 0 is the primary group so it can be skipped
+for (j = 1; j < num_gids; j++) {
+do {
+/* always zero out the grp structure */
+memset(grp, 0, sizeof(struct group));
+buffer = grow_group_buffer(tmp_ctx, &buffer, &buflen);
+if (!buffer) {
+ret = ENOMEM;
+goto done;
+}
+
+status = ctx->ops.getgrgid_r(gids[j], grp, buffer, buflen, &ret);
+
+ret = handle_getgr_result(status, grp, dom, &delete_group);
+} while (ret == EAGAIN);
+
+if (ret != EOK) {
+DEBUG(SSSDBG_OP_FAILURE,
+"getgrgid failed [%d]: %s\n", ret, strerror(ret));
+goto done;
+}
+
+network_groupname = sss_create_internal_fqname(tmp_ctx, grp->gr_name, dom->name);
+if (network_groupname == NULL) {
+DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n",
+  grp->gr_name);
+ret = ENOMEM;
+goto done;
+}
+
+if (strstr(db_groupname, network_groupname) != NULL) {
+*group_found = true;
+ret = EOK;
+goto done;
+}
+}
+
+done:
+return ret;
+}
+
+static int remove_group_members(struct proxy_id_ctx *ctx,
+struct sysdb_ctx *sysdb,
+struct sss_domain_info *dom,
+struct passwd *pwd,
+long int num_gids,
+gid_t *gids)
+{
+TALLOC_CTX *tmp_ctx;
+int ret = EOK;
+int i = 0;
+int num_values = 0;
+char *groupname = NULL;
+const char *username = NULL;
+const char *attr = SYSDB_MEMBEROF;
+const char *attrs[] = {attr, NULL};
+struct ldb_result *res = NULL;
+struct ldb_message_element *el = NULL;
+bool group_found = false;
+
+tmp_ctx = talloc_new(NULL);
+if (!tmp_ctx) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+goto done;
+}
+
+username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name);
+if (username == NULL) {
+ret = ENOMEM;
+goto done;
+}
+
+ret = sysdb_get_user_attr(tmp_ctx, dom, username, attrs, &res);
+if (res->count > 0) {
+el = ldb_msg_find_element(res->msgs[0], attr);
+if (el) {
+num_values = el->num_values;
+}
+}
+
+for (i = 0; i < num_values; i++) {
+group_found = false;
+
+ret = sysdb_get_rdn(sysdb, tmp_ctx, (const char *) el->values[i].data, NULL, &groupname);
+if (ret != EOK) {
+DEBUG(SSSDBG_CRIT_FAILURE, "Could not get rdn from [%s]\n",
+  (const char *) el->values[i].data);
+goto done;
+}
+
+if (!groupname) {
+ret = ENOMEM;
+DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup() failed\n");
+goto done;
+}
+
+ret = compare_group_members(ctx, tmp_ctx, dom, num_gids, gids,
+