diff options
-rw-r--r-- | server/db/sysdb.c | 24 | ||||
-rw-r--r-- | server/db/sysdb.h | 14 | ||||
-rw-r--r-- | server/db/sysdb_ops.c | 261 | ||||
-rw-r--r-- | server/db/sysdb_search.c | 63 | ||||
-rw-r--r-- | server/providers/ldap/sdap_async.c | 5 |
5 files changed, 151 insertions, 216 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 0cac339e..00657f0b 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -121,6 +121,30 @@ int sysdb_attrs_add_string(struct sysdb_attrs *attrs, return sysdb_attrs_add_val(attrs, name, &v); } +int sysdb_attrs_steal_string(struct sysdb_attrs *attrs, + const char *name, char *str) +{ + struct ldb_message_element *el = NULL; + struct ldb_val *vals; + int ret; + + ret = sysdb_attrs_get_el(attrs, name, &el); + + vals = talloc_realloc(attrs->a, el->values, + struct ldb_val, el->num_values+1); + if (!vals) return ENOMEM; + el->values = vals; + + /* now steal and assign the string */ + talloc_steal(el->values, str); + + el->values[el->num_values].data = (uint8_t *)str; + el->values[el->num_values].length = strlen(str); + el->num_values++; + + return EOK; +} + int sysdb_attrs_add_long(struct sysdb_attrs *attrs, const char *name, long value) { diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 64a07fe7..70231f88 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -51,7 +51,7 @@ #define SYSDB_DISABLED "disabled" #define SYSDB_MEMBER "member" -#define SYSDB_LEGACY_MEMBER "memberUid" +#define SYSDB_MEMBERUID "memberUid" #define SYSDB_DEFAULTGROUP "defaultGroup" #define SYSDB_GECOS "gecos" @@ -65,9 +65,11 @@ #define SYSDB_CACHEDPWD "cachedPassword" -#define SYSDB_ORIG_DN "originalDN" #define SYSDB_UUID "uniqueID" -#define SYSDB_UPN "UserPrincipalName" +#define SYSDB_UPN "userPrincipalName" + +#define SYSDB_ORIG_DN "originalDN" +#define SYSDB_ORIG_MODSTAMP "originalModifyTimestamp" #define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)" @@ -89,8 +91,6 @@ #define SYSDB_INITGR_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=*))" -#define SYSDB_INITGR_LEGACY_FILTER "(&("SYSDB_GC")("SYSDB_LEGACY_MEMBER"=%s))" - #define SYSDB_GETCACHED_FILTER "(&"SYSDB_UC")("SYSDB_LAST_LOGIN">=%lu))" #define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ @@ -112,7 +112,7 @@ SYSDB_LAST_UPDATE, \ NULL} #define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \ - SYSDB_LAST_UPDATE, SYSDB_LEGACY_MEMBER, \ + SYSDB_LAST_UPDATE, \ "objectClass", \ NULL} #define SYSDB_GRPW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ @@ -157,6 +157,8 @@ int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs, const char *name, time_t value); int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name, struct ldb_message_element **el); +int sysdb_attrs_steal_string(struct sysdb_attrs *attrs, + const char *name, char *str); /* convert an ldb error into an errno error */ int sysdb_error_to_errno(int ldberr); diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index 56e2777a..a36b22fb 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -154,9 +154,9 @@ static int sldb_request_callback(struct ldb_request *ldbreq, state->ldbreply = talloc_steal(state, ldbreply); if (ldbreply->error != LDB_SUCCESS) { - err = sysdb_error_to_errno(ldbreply->error); - DEBUG(6, ("Error: %d (%s)\n", err, strerror(err))); - ERROR_OUT(err, err, fail); + DEBUG(6, ("LDB Error: %d (%s)\n", + ldbreply->error, ldb_errstring(state->ldbctx))); + ERROR_OUT(err, sysdb_error_to_errno(ldbreply->error), fail); } if (ldbreply->type == LDB_REPLY_DONE) { @@ -2811,7 +2811,9 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct sysdb_store_group_state *state; - int ret, i; + static const char *src_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, + SYSDB_ORIG_MODSTAMP, NULL }; + int ret; req = tevent_req_create(mem_ctx, &state, struct sysdb_store_group_state); if (!req) return NULL; @@ -2824,38 +2826,8 @@ struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx, state->members = members; state->attrs = NULL; - if (state->members) { - state->attrs = sysdb_new_attrs(state); - if (!state->attrs) { - ERROR_OUT(ret, ENOMEM, fail); - } - - for (i = 0; state->members[i]; i++) { - if (domain->legacy) { -/* - const char *member; - - member = talloc_asprintf(state, SYSDB_TMPL_USER, - domain->name, state->members[i]); - if (!member) { - ERROR_OUT(ret, ENOMEM, fail); - } -*/ - ret = sysdb_attrs_add_string(state->attrs, SYSDB_LEGACY_MEMBER, - state->members[i]); - if (ret) goto fail; - } else { - ret = sysdb_attrs_add_string(state->attrs, SYSDB_MEMBER, - state->members[i]); - if (ret) goto fail; - } - } - - state->members = NULL; - } - subreq = sysdb_search_group_by_name_send(state, ev, NULL, handle, - domain, name, NULL); + domain, name, src_attrs); if (!subreq) { ERROR_OUT(ret, ENOMEM, fail); } @@ -2877,7 +2849,8 @@ static void sysdb_store_group_check(struct tevent_req *subreq) struct sysdb_store_group_state *state = tevent_req_data(req, struct sysdb_store_group_state); struct ldb_message *msg; - int ret; + bool new_group = false; + int ret, i; ret = sysdb_search_group_recv(subreq, state, &msg); talloc_zfree(subreq); @@ -2885,22 +2858,92 @@ static void sysdb_store_group_check(struct tevent_req *subreq) tevent_req_error(req, ret); return; } - if (ret == ENOENT) { + new_group = true; + } + + /* FIXME: use the remote modification timestamp to know if the + * group needs any update */ + + if (state->members) { + state->attrs = sysdb_new_attrs(state); + if (!state->attrs) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + + for (i = 0; state->members[i]; i++) { + struct ldb_dn *tmp = NULL; + const struct ldb_val *val; + const char *mname; + 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); + 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)); + + talloc_zfree(tmp); + + 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; + } + } + } + + if (new_group) { /* groups doesn't exist, turn into adding a group */ subreq = sysdb_add_group_send(state, state->ev, state->handle, - state->domain, state->name, - state->gid, state->attrs); + state->domain, state->name, + state->gid, state->attrs); if (!subreq) { DEBUG(6, ("Error: Out of memory\n")); tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sysdb_store_group_add_done, req); + return; } /* the group exists, let's just replace attributes when set */ + if (!state->attrs) { state->attrs = sysdb_new_attrs(state); if (!state->attrs) { @@ -2919,8 +2962,6 @@ static void sysdb_store_group_check(struct tevent_req *subreq) } } - /* FIXME: handle non legacy groups */ - ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, time(NULL)); if (ret) { DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); @@ -2929,9 +2970,9 @@ static void sysdb_store_group_check(struct tevent_req *subreq) } subreq = sysdb_set_group_attr_send(state, state->ev, - state->handle, state->domain, - state->name, state->attrs, - SYSDB_MOD_REP); + state->handle, state->domain, + state->name, state->attrs, + SYSDB_MOD_REP); if (!subreq) { DEBUG(6, ("Error: Out of memory\n")); tevent_req_error(req, ENOMEM); @@ -2983,7 +3024,6 @@ int sysdb_store_group_recv(struct tevent_req *req) /* =Add-User-to-Group(Native/Legacy)====================================== */ static void sysdb_add_group_member_done(struct tevent_req *subreq); -static void sysdb_add_group_member_l_done(struct tevent_req *subreq); struct tevent_req *sysdb_add_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -2995,7 +3035,6 @@ struct tevent_req *sysdb_add_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct sysdb_op_state *state; struct ldb_dn *group_dn, *user_dn; - struct sysdb_attrs *attrs; int ret; req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state); @@ -3006,42 +3045,23 @@ struct tevent_req *sysdb_add_group_member_send(TALLOC_CTX *mem_ctx, state->ignore_not_found = false; state->ldbreply = NULL; - if (domain->legacy) { - attrs = sysdb_new_attrs(state); - if (!attrs) { - ERROR_OUT(ret, ENOMEM, fail); - } - - ret = sysdb_attrs_add_string(attrs, SYSDB_LEGACY_MEMBER, user); - if (ret) goto fail; - - subreq = sysdb_set_group_attr_send(state, ev, handle, - domain, group, attrs, - SYSDB_MOD_ADD); - if (!subreq) { - ERROR_OUT(ret, ENOMEM, fail); - } - tevent_req_set_callback(subreq, sysdb_add_group_member_l_done, req); - - } else { - group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group); - if (!group_dn) { - ERROR_OUT(ret, ENOMEM, fail); - } + group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group); + if (!group_dn) { + ERROR_OUT(ret, ENOMEM, fail); + } - user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user); - if (!user_dn) { - ERROR_OUT(ret, ENOMEM, fail); - } + user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user); + if (!user_dn) { + ERROR_OUT(ret, ENOMEM, fail); + } - subreq = sysdb_mod_group_member_send(state, ev, handle, - user_dn, group_dn, - SYSDB_MOD_ADD); - if (!subreq) { - ERROR_OUT(ret, ENOMEM, fail); - } - tevent_req_set_callback(subreq, sysdb_add_group_member_done, req); + subreq = sysdb_mod_group_member_send(state, ev, handle, + user_dn, group_dn, + SYSDB_MOD_ADD); + if (!subreq) { + ERROR_OUT(ret, ENOMEM, fail); } + tevent_req_set_callback(subreq, sysdb_add_group_member_done, req); return req; @@ -3069,23 +3089,6 @@ static void sysdb_add_group_member_done(struct tevent_req *subreq) tevent_req_done(req); } -static void sysdb_add_group_member_l_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_set_group_attr_recv(subreq); - talloc_zfree(subreq); - if (ret) { - DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - int sysdb_add_group_member_recv(struct tevent_req *req) { return sysdb_op_default_recv(req); @@ -3095,7 +3098,6 @@ int sysdb_add_group_member_recv(struct tevent_req *req) /* =Remove-member-from-Group(Native/Legacy)=============================== */ static void sysdb_remove_group_member_done(struct tevent_req *subreq); -static void sysdb_remove_group_member_l_done(struct tevent_req *subreq); struct tevent_req *sysdb_remove_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -3107,7 +3109,6 @@ struct tevent_req *sysdb_remove_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct sysdb_op_state *state; struct ldb_dn *group_dn, *user_dn; - struct sysdb_attrs *attrs; int ret; req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state); @@ -3118,42 +3119,23 @@ struct tevent_req *sysdb_remove_group_member_send(TALLOC_CTX *mem_ctx, state->ignore_not_found = false; state->ldbreply = NULL; - if (domain->legacy) { - attrs = sysdb_new_attrs(state); - if (!attrs) { - ERROR_OUT(ret, ENOMEM, fail); - } - - ret = sysdb_attrs_add_string(attrs, SYSDB_LEGACY_MEMBER, user); - if (ret) goto fail; - - subreq = sysdb_set_group_attr_send(state, ev, handle, - domain, group, attrs, - SYSDB_MOD_DEL); - if (!subreq) { - ERROR_OUT(ret, ENOMEM, fail); - } - tevent_req_set_callback(subreq, sysdb_remove_group_member_l_done, req); - - } else { - group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group); - if (!group_dn) { - ERROR_OUT(ret, ENOMEM, fail); - } + group_dn = sysdb_group_dn(handle->ctx, state, domain->name, group); + if (!group_dn) { + ERROR_OUT(ret, ENOMEM, fail); + } - user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user); - if (!user_dn) { - ERROR_OUT(ret, ENOMEM, fail); - } + user_dn = sysdb_user_dn(handle->ctx, state, domain->name, user); + if (!user_dn) { + ERROR_OUT(ret, ENOMEM, fail); + } - subreq = sysdb_mod_group_member_send(state, ev, handle, - user_dn, group_dn, - SYSDB_MOD_DEL); - if (!subreq) { - ERROR_OUT(ret, ENOMEM, fail); - } - tevent_req_set_callback(subreq, sysdb_remove_group_member_done, req); + subreq = sysdb_mod_group_member_send(state, ev, handle, + user_dn, group_dn, + SYSDB_MOD_DEL); + if (!subreq) { + ERROR_OUT(ret, ENOMEM, fail); } + tevent_req_set_callback(subreq, sysdb_remove_group_member_done, req); return req; @@ -3181,23 +3163,6 @@ static void sysdb_remove_group_member_done(struct tevent_req *subreq) tevent_req_done(req); } -static void sysdb_remove_group_member_l_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_set_group_attr_recv(subreq); - talloc_zfree(subreq); - if (ret) { - DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - int sysdb_remove_group_member_recv(struct tevent_req *req) { return sysdb_op_default_recv(req); diff --git a/server/db/sysdb_search.c b/server/db/sysdb_search.c index 5ee9f8c0..a3fdb16e 100644 --- a/server/db/sysdb_search.c +++ b/server/db/sysdb_search.c @@ -482,11 +482,6 @@ static int get_grp_callback(struct ldb_request *req, return LDB_SUCCESS; } - if (sctx->domain->legacy) { - request_done(sctx); - return LDB_SUCCESS; - } - if (res->count > 0) { sctx->gmctx = talloc_zero(req, struct get_mem_ctx); @@ -670,58 +665,6 @@ int sysdb_enumgrent(TALLOC_CTX *mem_ctx, return EOK; } -static void initgr_mem_legacy(struct sysdb_search_ctx *sctx) -{ - struct sysdb_ctx *ctx = sctx->ctx; - struct ldb_result *res = sctx->res; - struct ldb_request *req; - struct ldb_dn *base_dn; - static const char *attrs[] = SYSDB_INITGR_ATTRS; - const char *userid; - int ret; - - if (res->count == 0) { - return request_done(sctx); - } - if (res->count > 1) { - return request_ldberror(sctx, LDB_ERR_OPERATIONS_ERROR); - } - - /* make sure we don't loop with get_gen_callback() */ - sctx->gen_aux_fn = NULL; - - userid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); - if (!userid) { - return request_ldberror(sctx, LDB_ERR_OPERATIONS_ERROR); - } - - sctx->expression = talloc_asprintf(sctx, - SYSDB_INITGR_LEGACY_FILTER, userid); - if (!sctx->expression) { - return request_ldberror(sctx, LDB_ERR_OPERATIONS_ERROR); - } - - base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, - SYSDB_TMPL_GROUP_BASE, sctx->domain->name); - if (!base_dn) { - return request_ldberror(sctx, LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_build_search_req(&req, ctx->ldb, sctx, - base_dn, LDB_SCOPE_SUBTREE, - sctx->expression, attrs, NULL, - sctx, get_gen_callback, - NULL); - if (ret != LDB_SUCCESS) { - return request_ldberror(sctx, ret); - } - - ret = ldb_request(ctx->ldb, req); - if (ret != LDB_SUCCESS) { - return request_ldberror(sctx, ret); - } -} - static void initgr_mem_search(struct sysdb_search_ctx *sctx) { struct sysdb_ctx *ctx = sctx->ctx; @@ -801,11 +744,7 @@ static void initgr_search(struct tevent_req *treq) return request_error(sctx, ret); } - if (sctx->domain->legacy) { - sctx->gen_aux_fn = initgr_mem_legacy; - } else { - sctx->gen_aux_fn = initgr_mem_search; - } + sctx->gen_aux_fn = initgr_mem_search; base_dn = ldb_dn_new_fmt(sctx, sctx->ctx->ldb, SYSDB_TMPL_USER_BASE, sctx->domain->name); diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c index 539a0753..57ccd865 100644 --- a/server/providers/ldap/sdap_async.c +++ b/server/providers/ldap/sdap_async.c @@ -1488,6 +1488,11 @@ static void sdap_get_groups_done(struct sdap_op *op, case LDAP_RES_SEARCH_ENTRY: + /* FIXME: we should do this in 2 steps: + * first save groups, then add all memberships + * otherwise nested memberships may go missing + * if the member group is added only after the + * parent group is added */ subreq = sdap_save_group_send(state, state->ev, state->handle, state->opts, state->dom, state->sh, reply); |