summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-09-10 12:43:42 -0400
committerSimo Sorce <ssorce@redhat.com>2009-09-11 17:16:06 -0400
commitec56fb826b20b080bbfaf09da671d24faf6c5e88 (patch)
tree198c926b2d4420f7da0fca3d2a28933c350fc805 /server
parentb187d74a6d6e4e0c1102b510f7fc8340d41ae30a (diff)
downloadsssd-ec56fb826b20b080bbfaf09da671d24faf6c5e88.tar.gz
sssd-ec56fb826b20b080bbfaf09da671d24faf6c5e88.tar.xz
sssd-ec56fb826b20b080bbfaf09da671d24faf6c5e88.zip
Complete the removal of "legacy" option.
The code was still dependent on it for the ldap driver. Changed the driver code to depend on the schema type. Fix defaults for user and groups trees. ATM if you use the rfc2307bis schema you have to put users and groups in 2 separate trees (what people does by default anyway. If this limitation will turn to be too hard, we will change this later.
Diffstat (limited to 'server')
-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);
}