summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/confdb/confdb.c5
-rw-r--r--server/confdb/confdb.h1
-rw-r--r--server/db/sysdb.c5
-rw-r--r--server/db/sysdb.h6
-rw-r--r--server/db/sysdb_ops.c72
-rw-r--r--server/providers/ldap/sdap.c6
-rw-r--r--server/providers/ldap/sdap.h3
-rw-r--r--server/providers/ldap/sdap_async.c207
-rw-r--r--server/providers/proxy.c8
-rw-r--r--server/tests/sysdb-tests.c6
10 files changed, 243 insertions, 76 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 8fbae2f7a..a3bb62c87 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -797,11 +797,6 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
DEBUG(1, ("No enumeration for [%s]!\n", domain->name));
}
- /* Determine if this is a legacy domain */
- if (ldb_msg_find_attr_as_bool(res->msgs[0], "legacy", 0)) {
- domain->legacy = true;
- }
-
/* Determine if this is domain uses MPG */
if (strcasecmp(domain->provider, "local") == 0 ||
ldb_msg_find_attr_as_bool(res->msgs[0], CONFDB_MPG, 0)) {
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index d49040fee..a0da9b4f0 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -45,7 +45,6 @@ struct sss_domain_info {
int timeout;
bool enumerate;
bool fqnames;
- bool legacy;
bool mpg;
uint32_t id_min;
uint32_t id_max;
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index d4f257977..87d0de965 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -47,6 +47,11 @@ struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx)
return ctx->ldb;
}
+struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle)
+{
+ return handle->ctx->ldb;
+}
+
struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx)
{
return talloc_zero(memctx, struct sysdb_attrs);
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 2d8b3eaea..9afb957f5 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -177,6 +177,9 @@ struct ldb_dn *sysdb_group_dn(struct sysdb_ctx *ctx, void *memctx,
struct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *ctx, void *memctx,
const char *domain);
+struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx);
+struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle);
+
/* function to start and finish a transaction
* sysdb_transaction_send() will queue a request for a transaction
* when it is done it will call the tevent_req callback, which must
@@ -477,7 +480,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
gid_t gid,
- const char **members,
+ const char **member_users,
+ const char **member_groups,
struct sysdb_attrs *attrs);
int sysdb_store_group_recv(struct tevent_req *req);
diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c
index 57705275b..3a53c9e5e 100644
--- a/server/db/sysdb_ops.c
+++ b/server/db/sysdb_ops.c
@@ -2771,7 +2771,8 @@ struct sysdb_store_group_state {
const char *name;
gid_t gid;
- const char **members;
+ const char **member_users;
+ const char **member_groups;
struct sysdb_attrs *attrs;
};
@@ -2786,7 +2787,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
gid_t gid,
- const char **members,
+ const char **member_users,
+ const char **member_groups,
struct sysdb_attrs *attrs)
{
struct tevent_req *req, *subreq;
@@ -2803,7 +2805,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
state->domain = domain;
state->name = name;
state->gid = gid;
- state->members = members;
+ state->member_users = member_users;
+ state->member_groups = member_groups;
state->attrs = attrs;
subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle,
@@ -2845,7 +2848,7 @@ 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->members) {
+ if (state->member_users || state->member_groups) {
if (!state->attrs) {
state->attrs = sysdb_new_attrs(state);
if (!state->attrs) {
@@ -2855,49 +2858,42 @@ static void sysdb_store_group_check(struct tevent_req *subreq)
}
}
- for (i = 0; state->members[i]; i++) {
- struct ldb_dn *tmp = NULL;
- const struct ldb_val *val;
- const char *mname;
+ for (i = 0; state->member_users && state->member_users[i]; i++) {
char *member;
- if (state->domain->legacy) {
- mname = state->members[i];
- } else {
-
- tmp = ldb_dn_new(state, state->handle->ctx->ldb,
- state->members[i]);
- if (!tmp) {
- DEBUG(2, ("Out of memory, converting DN [%s]!\n",
- state->members[i]));
- continue;
- }
- val = ldb_dn_get_rdn_val(tmp);
- if (!val) {
- DEBUG(2, ("Out of memory, converting DN [%s]!\n",
- state->members[i]));
- continue;
- }
- mname = talloc_strndup(tmp,
- (const char *)val->data, val->length);
- if (!mname) {
- DEBUG(2, ("Out of memory, converting DN [%s]!\n",
- state->members[i]));
- continue;
- }
- }
-
member = talloc_asprintf(state, SYSDB_TMPL_USER,
- mname, state->domain->name);
+ state->member_users[i],
+ state->domain->name);
if (!member) {
DEBUG(6, ("Error: Out of memory\n"));
tevent_req_error(req, ENOMEM);
return;
}
- DEBUG(9, ("adding member: %s [orig: %s] to group %s\n",
- member, state->members[i], state->name));
+ 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(6, ("Error: %d (%s)\n", ret, strerror(ret)));
+ tevent_req_error(req, ret);
+ return;
+ }
+ }
- talloc_zfree(tmp);
+ for (i = 0; state->member_groups && state->member_groups[i]; i++) {
+ char *member;
+
+ member = talloc_asprintf(state, SYSDB_TMPL_GROUP,
+ state->member_users[i],
+ state->domain->name);
+ if (!member) {
+ DEBUG(6, ("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);
diff --git a/server/providers/ldap/sdap.c b/server/providers/ldap/sdap.c
index dacce9c20..616e4a37c 100644
--- a/server/providers/ldap/sdap.c
+++ b/server/providers/ldap/sdap.c
@@ -33,10 +33,10 @@ struct sdap_gen_opts default_basic_opts[] = {
{ "network_timeout", "5", NULL },
{ "opt_timeout", "5", NULL },
{ "tls_reqcert", "hard", NULL },
- { "userSearchBase", "dc=example,dc=com", NULL },
+ { "userSearchBase", "ou=People,dc=example,dc=com", NULL },
{ "userSearchScope", "sub", NULL },
{ "userSearchFilter", NULL, NULL },
- { "groupSearchBase", "dc=example,dc=com", NULL },
+ { "groupSearchBase", "ou=Group,dc=example,dc=com", NULL },
{ "groupSearchScope", "sub", NULL },
{ "groupSearchFilter", NULL, NULL },
{ "ldapSchema", "rfc2307", NULL },
@@ -111,7 +111,7 @@ int sdap_get_options(TALLOC_CTX *memctx,
struct sdap_options *opts;
int i, ret;
- opts = talloc(memctx, struct sdap_options);
+ opts = talloc_zero(memctx, struct sdap_options);
if (!opts) return ENOMEM;
opts->basic = talloc_array(opts, struct sdap_gen_opts, SDAP_OPTS_BASIC);
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index 0145091bf..a39eef515 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -152,6 +152,9 @@ struct sdap_options {
SDAP_SCHEMA_RFC2307BIS = 2, /* member = dn */
SDAP_SCHEMA_IPA_V1 = 3 /* member/memberof with unrolling */
} schema_type;
+
+ struct ldb_dn *users_base;
+ struct ldb_dn *groups_base;
};
int sdap_get_options(TALLOC_CTX *memctx,
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index 84e13b51a..bcdf22a08 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -1120,11 +1120,14 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
struct tevent_req *req, *subreq;
struct sdap_save_group_state *state;
struct ldb_message_element *el;
- int i, ret;
- const char **members;
+ const char **member_groups = NULL;
+ const char **member_users = NULL;
+ struct sysdb_attrs *group_attrs;
+ int mu, mg;
+ int i;
long int l;
gid_t gid;
- struct sysdb_attrs *group_attrs;
+ int ret;
req = tevent_req_create(memctx, &state, struct sdap_save_group_state);
if (!req) return NULL;
@@ -1150,22 +1153,6 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
state->name = (const char *)el->values[0].data;
ret = sysdb_attrs_get_el(state->attrs,
- opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
- if (ret) goto fail;
- if (el->num_values == 0) members = NULL;
- else {
- members = talloc_array(state, const char *, el->num_values +1);
- if (!members) {
- ret = ENOMEM;
- goto fail;
- }
- for (i = 0; i < el->num_values; i++) {
- members[i] = (char *)el->values[i].data;
- }
- members[i] = NULL;
- }
-
- ret = sysdb_attrs_get_el(state->attrs,
opts->group_map[SDAP_AT_GROUP_GID].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) {
@@ -1211,11 +1198,182 @@ static struct tevent_req *sdap_save_group_send(TALLOC_CTX *memctx,
}
}
+ switch (opts->schema_type) {
+ case SDAP_SCHEMA_RFC2307:
+
+ ret = sysdb_attrs_get_el(state->attrs,
+ opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
+ if (ret) goto fail;
+ if (el->num_values == 0) {
+ DEBUG(7, ("[RFC2307bis] No members for group [%s]\n", state->name));
+ break;
+ }
+
+ DEBUG(7, ("[RFC2307] Adding member users to group [%s]\n",
+ state->name));
+
+ member_users = talloc_array(state, const char *,
+ el->num_values +1);
+ if (!member_users) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ for (i = 0; i < el->num_values; i++) {
+ member_users[i] = (char *)el->values[i].data;
+ DEBUG(7, (" member user %d: [%s]\n", i, member_users[i]));
+ }
+ member_users[i] = NULL;
+
+ break;
+
+ case SDAP_SCHEMA_RFC2307BIS:
+ case SDAP_SCHEMA_IPA_V1:
+
+ /* if this is the first time we are called, check if users and
+ * groups base DNs are set, if not do it */
+ if (!opts->users_base) {
+ opts->users_base = ldb_dn_new_fmt(opts,
+ sysdb_handle_get_ldb(state->handle), "%s",
+ opts->basic[SDAP_USER_SEARCH_BASE].value);
+ if (!opts->users_base) {
+ DEBUG(1, ("Unable to get casefold Users Base DN from [%s]\n",
+ opts->basic[SDAP_USER_SEARCH_BASE].value));
+ DEBUG(1, ("Out of memory?!\n"));
+ ret = ENOMEM;
+ goto fail;
+ }
+ }
+ if (!opts->groups_base) {
+ opts->groups_base = ldb_dn_new_fmt(state->handle,
+ sysdb_handle_get_ldb(state->handle), "%s",
+ opts->basic[SDAP_GROUP_SEARCH_BASE].value);
+ if (!opts->users_base) {
+ DEBUG(1, ("Unable to get casefold Users Base DN from [%s]\n",
+ opts->basic[SDAP_USER_SEARCH_BASE].value));
+ DEBUG(1, ("Out of memory?!\n"));
+ ret = ENOMEM;
+ goto fail;
+ }
+ }
+
+ ret = sysdb_attrs_get_el(state->attrs,
+ opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
+ if (ret) goto fail;
+ if (el->num_values == 0) {
+ DEBUG(7, ("[RFC2307bis] No members for group [%s]\n", state->name));
+ break;
+ }
+
+ /* this will hold both lists,
+ * users filling up from top and groups from bottom,
+ * so the array will need 2 slots for NULL terminating element */
+ member_users = talloc_zero_array(state, const char *,
+ el->num_values +2);
+ if (!member_users) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ mg = el->num_values;
+ mu = 0;
+
+ DEBUG(7, ("[RFC2307bis] Adding members to group [%s]\n", state->name));
+
+ for (i = 0; i < el->num_values; i++) {
+
+ struct ldb_dn *tmp_dn = NULL;
+ const struct ldb_val *v;
+
+
+ /* parse out DN */
+ tmp_dn = ldb_dn_new_fmt(member_users,
+ sysdb_handle_get_ldb(state->handle),
+ "%.*s",
+ (int)el->values[i].length,
+ (char *)el->values[i].data);
+ if (!tmp_dn) {
+ DEBUG(1, ("Unable to parse DN: [%.*s]\n",
+ (int)el->values[i].length,
+ (char *)el->values[i].data));
+ continue;
+ }
+ v = ldb_dn_get_rdn_val(tmp_dn);
+ if (!v) {
+ DEBUG(1, ("Unable to parse DN: [%.*s]\n",
+ (int)el->values[i].length,
+ (char *)el->values[i].data));
+ continue;
+ }
+ DEBUG(9, ("Member DN [%.*s], RDN [%.*s]\n",
+ (int)el->values[i].length, (char *)el->values[i].data,
+ (int)v->length, (char *)v->data));
+
+ if (ldb_dn_compare_base(opts->users_base, tmp_dn) == 0) {
+ member_users[mu] = talloc_asprintf(member_users,
+ "%.*s",
+ (int)v->length,
+ (char *)v->data);
+ if (!member_users[mu]) {
+ DEBUG(1, ("Out of memory?!\n"));
+ continue;
+ }
+
+ DEBUG(7, (" member user %d: [%s]\n", i, member_users[mu]));
+
+ mu++;
+
+ } else if (ldb_dn_compare_base(opts->groups_base, tmp_dn) == 0) {
+ member_users[mg] = talloc_asprintf(member_users,
+ "%.*s",
+ (int)v->length,
+ (char *)v->data);
+ if (!member_users[mg]) {
+ DEBUG(1, ("Out of memory?!\n"));
+ continue;
+ }
+
+ DEBUG(7, (" member group %d: [%s]\n", i, member_users[mg]));
+
+ mg--;
+
+ } else {
+ DEBUG(1, ("Unkown Member type for DN: [%s]\n",
+ (int)el->values[i].length,
+ (char *)el->values[i].data));
+ continue;
+ }
+ if (mu > mg) { /* shouldn't be possible */
+ DEBUG(0, ("Fatal Internal error: aborting\n"));
+ ret = EFAULT;
+ goto fail;
+ }
+ }
+
+ /* if there are groups, set member_groups */
+ if (mg != el->num_values) {
+ member_groups = &member_users[mg+1];
+ }
+
+ /* if there are no users, reset member_users */
+ if (mu == 0) {
+ member_users = NULL;
+ }
+
+ break;
+
+ default:
+ DEBUG(0, ("FATAL ERROR: Unhandled schema type! (%d)\n",
+ opts->schema_type));
+ ret = EFAULT;
+ goto fail;
+ }
+
DEBUG(6, ("Storing info for group %s\n", state->name));
subreq = sysdb_store_group_send(state, state->ev,
state->handle, state->dom,
- state->name, gid, members,
+ state->name, gid,
+ member_users, member_groups,
group_attrs);
if (!subreq) {
ret = ENOMEM;
@@ -1555,7 +1713,14 @@ static void sdap_get_groups_transaction(struct tevent_req *subreq)
return;
}
- DEBUG(5, ("calling ldap_search_ext with [%s].\n", state->filter));
+ DEBUG(7, ("calling ldap_search_ext with [%s].\n", state->filter));
+ if (debug_level >= 7) {
+ int i;
+
+ for (i = 0; state->attrs[i]; i++) {
+ DEBUG(7, ("Requesting attrs: [%s]\n", state->attrs[i]));
+ }
+ }
lret = ldap_search_ext(state->sh->ldap,
state->opts->basic[SDAP_GROUP_SEARCH_BASE].value,
diff --git a/server/providers/proxy.c b/server/providers/proxy.c
index c308d3f80..5428a6dc8 100644
--- a/server/providers/proxy.c
+++ b/server/providers/proxy.c
@@ -968,7 +968,7 @@ again:
state->grp->gr_name,
state->grp->gr_gid,
(const char **)state->grp->gr_mem,
- NULL);
+ NULL, NULL);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -1162,7 +1162,7 @@ again:
state->grp->gr_name,
state->grp->gr_gid,
(const char **)state->grp->gr_mem,
- NULL);
+ NULL, NULL);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -1367,7 +1367,7 @@ again:
state->grp->gr_name,
state->grp->gr_gid,
(const char **)state->grp->gr_mem,
- NULL);
+ NULL, NULL);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -1815,7 +1815,7 @@ again:
state->grp->gr_name,
state->grp->gr_gid,
(const char **)state->grp->gr_mem,
- NULL);
+ NULL, NULL);
if (!subreq) {
ret = ENOMEM;
goto fail;
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index 5250b0883..424393cf3 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -105,7 +105,7 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
talloc_free(test_ctx);
return ret;
}
-/*
+
val[0] = "TRUE";
ret = confdb_add_param(test_ctx->confdb, true,
"config/domains/LOCAL", "magicPrivateGroups", val);
@@ -114,7 +114,7 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
talloc_free(test_ctx);
return ret;
}
-*/
+
val[0] = "TRUE";
ret = confdb_add_param(test_ctx->confdb, true,
"config/domains/LOCAL", "enumerate", val);
@@ -471,7 +471,7 @@ static void test_store_group(struct tevent_req *req)
subreq = sysdb_store_group_send(data, data->ev, data->handle,
data->ctx->domain, data->groupname,
- data->gid, NULL, NULL);
+ data->gid, NULL, NULL, NULL);
if (!subreq) {
test_return(data, ret);
}