summaryrefslogtreecommitdiffstats
path: root/server/db
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-11-30 21:51:41 -0500
committerStephen Gallagher <sgallagh@redhat.com>2009-12-07 10:19:03 -0500
commit9a9f6858e488b6aaf1df7f484a7caea5346f5a3e (patch)
tree8beaf990f32b778eabdb4f30ba2338ae2f447d2a /server/db
parenteffa7cd25f32c88aeb1478f5305bb185434867be (diff)
downloadsssd-9a9f6858e488b6aaf1df7f484a7caea5346f5a3e.tar.gz
sssd-9a9f6858e488b6aaf1df7f484a7caea5346f5a3e.tar.xz
sssd-9a9f6858e488b6aaf1df7f484a7caea5346f5a3e.zip
Fix nested group memberships
Search the local db to find the local DN using the original DN as search key. This way we do not have to rely on weak and faulty heuristicts based on DN names. Add a few helper functions in the process and change the way we pass members to sysdb_store_group_send(), instead of passing users and groups list, just add member DNs to the other sysdb attrs.
Diffstat (limited to 'server/db')
-rw-r--r--server/db/sysdb.c97
-rw-r--r--server/db/sysdb.h13
-rw-r--r--server/db/sysdb_ops.c65
3 files changed, 109 insertions, 66 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index 8ff96566d..979acf8b5 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -68,6 +68,11 @@ struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle)
return handle->ctx->ldb;
}
+struct sysdb_ctx *sysdb_handle_get_ctx(struct sysdb_handle *handle)
+{
+ return handle->ctx;
+}
+
struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx)
{
return talloc_zero(memctx, struct sysdb_attrs);
@@ -254,6 +259,98 @@ int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs,
return ret;
}
+int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
+ const char *attr_name,
+ const char *domain,
+ const char **list)
+{
+ struct ldb_message_element *el = NULL;
+ struct ldb_val *vals;
+ int i, j, num;
+ char *member;
+ int ret;
+
+ ret = sysdb_attrs_get_el(attrs, attr_name, &el);
+ if (!ret) {
+ return ret;
+ }
+
+ for (num = 0; list[num]; num++) /* count */ ;
+
+ vals = talloc_realloc(attrs->a, el->values,
+ struct ldb_val, el->num_values + num);
+ if (!vals) {
+ return ENOMEM;
+ }
+ el->values = vals;
+
+ DEBUG(9, ("Adding %d members to existing %d ones\n",
+ num, el->num_values));
+
+ for (i = 0, j = el->num_values; i < num; i++) {
+
+ member = sysdb_user_strdn(el->values, domain, list[i]);
+ if (!member) {
+ DEBUG(4, ("Failed to get user dn for [%s]\n", list[i]));
+ continue;
+ }
+ el->values[j].data = (uint8_t *)member;
+ el->values[j].length = strlen(member);
+ j++;
+
+ DEBUG(7, (" member #%d: [%s]\n", i, member));
+ }
+ el->num_values = j;
+
+ return EOK;
+}
+
+int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
+ const char *attr_name,
+ const char *domain,
+ struct ldb_val *values,
+ int num_values)
+{
+ struct ldb_message_element *el = NULL;
+ struct ldb_val *vals;
+ int i, j;
+ char *member;
+ int ret;
+
+ ret = sysdb_attrs_get_el(attrs, attr_name, &el);
+ if (!ret) {
+ return ret;
+ }
+
+ vals = talloc_realloc(el, el->values, struct ldb_val,
+ el->num_values + num_values);
+ if (!vals) {
+ return ENOMEM;
+ }
+ el->values = vals;
+
+ DEBUG(9, ("Adding %d members to existing %d ones\n",
+ num_values, el->num_values));
+
+ for (i = 0, j = el->num_values; i < num_values; i++) {
+ member = sysdb_user_strdn(el->values, domain,
+ (char *)values[i].data);
+ if (!member) {
+ DEBUG(4, ("Failed to get user dn for [%s]\n",
+ (char *)values[i].data));
+ return ENOMEM;
+ }
+ el->values[j].data = (uint8_t *)member;
+ el->values[j].length = strlen(member);
+ j++;
+
+ DEBUG(7, (" member #%d: [%s]\n", i, member));
+ }
+ el->num_values = j;
+
+ return EOK;
+}
+
static char *build_dom_dn_str_escape(TALLOC_CTX *memctx, const char *template,
const char *domain, const char *name)
{
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index c345caf8e..641ec6803 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -175,6 +175,16 @@ int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname,
const char *newname);
+int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
+ const char *attr_name,
+ const char *domain,
+ const char **list);
+int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
+ const char *attr_name,
+ const char *domain,
+ struct ldb_val *values,
+ int num_values);
+
/* convert an ldb error into an errno error */
int sysdb_error_to_errno(int ldberr);
@@ -200,6 +210,7 @@ char *sysdb_group_strdn(TALLOC_CTX *memctx,
struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx);
struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle);
+struct sysdb_ctx *sysdb_handle_get_ctx(struct sysdb_handle *handle);
int compare_ldb_dn_comp_num(const void *m1, const void *m2);
@@ -497,8 +508,6 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
gid_t gid,
- const char **member_users,
- const char **member_groups,
struct sysdb_attrs *attrs,
uint64_t cache_timeout);
int sysdb_store_group_recv(struct tevent_req *req);
diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c
index ae95b51be..86a9d33e8 100644
--- a/server/db/sysdb_ops.c
+++ b/server/db/sysdb_ops.c
@@ -2778,8 +2778,6 @@ struct sysdb_store_group_state {
const char *name;
gid_t gid;
- const char **member_users;
- const char **member_groups;
struct sysdb_attrs *attrs;
@@ -2796,8 +2794,6 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
gid_t gid,
- const char **member_users,
- const char **member_groups,
struct sysdb_attrs *attrs,
uint64_t cache_timeout)
{
@@ -2815,8 +2811,6 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
state->domain = domain;
state->name = name;
state->gid = gid;
- state->member_users = member_users;
- state->member_groups = member_groups;
state->attrs = attrs;
state->cache_timeout = cache_timeout;
@@ -2845,7 +2839,7 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
struct ldb_message *msg;
time_t now = time(NULL);
bool new_group = false;
- int ret, i;
+ int ret;
ret = sysdb_search_group_recv(subreq, state, &msg);
talloc_zfree(subreq);
@@ -2860,63 +2854,6 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
/* FIXME: use the remote modification timestamp to know if the
* group needs any update */
- if (state->member_users || state->member_groups) {
- if (!state->attrs) {
- state->attrs = sysdb_new_attrs(state);
- if (!state->attrs) {
- DEBUG(6, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
- }
-
- for (i = 0; state->member_users && state->member_users[i]; i++) {
- char *member;
-
- member = sysdb_user_strdn(state,
- state->domain->name,
- state->member_users[i]);
- if (!member) {
- DEBUG(4, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
- DEBUG(9, ("adding member: %s to group %s\n",
- member, state->name));
-
- ret = sysdb_attrs_steal_string(state->attrs,
- SYSDB_MEMBER, member);
- if (ret) {
- DEBUG(4, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
- }
-
- for (i = 0; state->member_groups && state->member_groups[i]; i++) {
- char *member;
-
- member = sysdb_group_strdn(state,
- state->domain->name,
- state->member_groups[i]);
- if (!member) {
- DEBUG(4, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
- }
- DEBUG(9, ("adding member: %s to group %s\n",
- member, state->name));
-
- ret = sysdb_attrs_steal_string(state->attrs,
- SYSDB_MEMBER, member);
- if (ret) {
- DEBUG(4, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
- }
- }
-
if (new_group) {
/* group doesn't exist, turn into adding a group */
subreq = sysdb_add_group_send(state, state->ev, state->handle,