summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/db/sysdb.c24
-rw-r--r--server/db/sysdb.h14
-rw-r--r--server/db/sysdb_ops.c261
-rw-r--r--server/db/sysdb_search.c63
-rw-r--r--server/providers/ldap/sdap_async.c5
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);