summaryrefslogtreecommitdiff
path: root/server/providers
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers')
-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
4 files changed, 196 insertions, 28 deletions
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;