summaryrefslogtreecommitdiff
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.bz2
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 8fbae2f7..a3bb62c8 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 d49040fe..a0da9b4f 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 d4f25797..87d0de96 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 2d8b3eae..9afb957f 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 57705275..3a53c9e5 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 dacce9c2..616e4a37 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 0145091b..a39eef51 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 84e13b51..bcdf22a0 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 c308d3f8..5428a6dc 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 5250b088..424393cf 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);
}