/* * Generic modify groups member */ static int mod_groups_member(struct sss_domain_info *dom, char **grouplist, struct ldb_dn *member_dn, int optype) { TALLOC_CTX *tmpctx; struct ldb_dn *parent_dn; int ret; int i; char *grp_sysdb_fqname = NULL; tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } /* FIXME: add transaction around loop */ for (i = 0; grouplist[i]; i++) { grp_sysdb_fqname = sss_create_internal_fqname(tmpctx, grouplist[i], dom->name); if (grp_sysdb_fqname == NULL) { ret = ENOMEM; goto done; } parent_dn = sysdb_group_dn(tmpctx, dom, grp_sysdb_fqname); if (!parent_dn) { ret = ENOMEM; goto done; } talloc_free(grp_sysdb_fqname); ret = sysdb_mod_group_member(dom, member_dn, parent_dn, optype); if (ret) { goto done; } } ret = EOK; done: talloc_zfree(tmpctx); return ret; }
/* * Generic modify groups member */ static int mod_groups_member(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, char **grouplist, struct ldb_dn *member_dn, int optype) { TALLOC_CTX *tmpctx; struct ldb_dn *parent_dn; int ret; int i; struct sss_domain_info *domain = sysdb_ctx_get_domain(sysdb); tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } /* FIXME: add transaction around loop */ for (i = 0; grouplist[i]; i++) { parent_dn = sysdb_group_dn(sysdb, tmpctx, domain->name, grouplist[i]); if (!parent_dn) { ret = ENOMEM; goto done; } ret = sysdb_mod_group_member(sysdb, member_dn, parent_dn, optype); if (ret) { goto done; } } ret = EOK; done: talloc_zfree(tmpctx); return ret; }
static errno_t add_ad_user_to_cached_groups(struct ldb_dn *user_dn, struct sss_domain_info *user_dom, struct sss_domain_info *group_dom, char **groups, bool *missing_groups) { size_t c; struct sysdb_attrs *user_attrs; size_t msgs_count; struct ldb_message **msgs; char *subfilter; TALLOC_CTX *tmp_ctx; int ret; *missing_groups = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } for (c = 0; groups[c] != NULL; c++) { if (groups[c][0] == '\0') { continue; } subfilter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, groups[c]); if (subfilter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_groups(tmp_ctx, group_dom, subfilter, NULL, &msgs_count, &msgs); if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "Group [%s] not in the cache.\n", groups[c]); *missing_groups = true; continue; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n"); goto done; } } /* TODO? Do we have to remove members as well? I think not because the AD * query before removes all memberships. */ ret = sysdb_mod_group_member(group_dom, user_dn, msgs[0]->dn, LDB_FLAG_MOD_ADD); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_mod_group_member failed.\n"); goto done; } user_attrs = sysdb_new_attrs(tmp_ctx); if (user_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, groups[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_set_entry_attr(user_dom->sysdb, user_dn, user_attrs, LDB_FLAG_MOD_ADD); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); goto done; } /* mark group as already processed */ groups[c][0] = '\0'; } ret = EOK; done: talloc_free(tmp_ctx); return ret; }