diff options
Diffstat (limited to 'server/providers')
-rw-r--r-- | server/providers/ldap/sdap.c | 6 | ||||
-rw-r--r-- | server/providers/ldap/sdap.h | 3 | ||||
-rw-r--r-- | server/providers/ldap/sdap_async.c | 207 | ||||
-rw-r--r-- | server/providers/proxy.c | 8 |
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; |