summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/db/sysdb.h64
-rw-r--r--src/db/sysdb_ops.c484
-rw-r--r--src/providers/ldap/sdap_async_accounts.c280
-rw-r--r--src/providers/proxy.c306
-rw-r--r--src/tests/sysdb-tests.c52
-rw-r--r--src/tools/sss_sync_ops.c135
6 files changed, 430 insertions, 891 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 1e4e0c16..156dc0b8 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -411,30 +411,26 @@ int sysdb_get_new_id(TALLOC_CTX *mem_ctx,
uint32_t *id);
/* Add user (only basic attrs and w/o checks) */
-struct tevent_req *sysdb_add_basic_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell);
-int sysdb_add_basic_user_recv(struct tevent_req *req);
+int sysdb_add_basic_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell);
/* Add user (all checks) */
-struct tevent_req *sysdb_add_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell,
- struct sysdb_attrs *attrs,
- int cache_timeout);
-int sysdb_add_user_recv(struct tevent_req *req);
+int sysdb_add_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell,
+ struct sysdb_attrs *attrs,
+ int cache_timeout);
/* Add group (only basic attrs and w/o checks) */
struct tevent_req *sysdb_add_basic_group_send(TALLOC_CTX *mem_ctx,
@@ -468,19 +464,17 @@ int sysdb_set_group_gid(struct sysdb_handle *handle,
const char *name, gid_t gid,
sysdb_callback_t fn, void *pvt);
-struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- const char *pwd,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell,
- struct sysdb_attrs *attrs,
- uint64_t cache_timeout);
-int sysdb_store_user_recv(struct tevent_req *req);
+int sysdb_store_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ const char *pwd,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell,
+ struct sysdb_attrs *attrs,
+ uint64_t cache_timeout);
struct tevent_req *sysdb_store_group_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index ee86f972..6f8df5fe 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -790,52 +790,40 @@ done:
/* =Add-Basic-User-NO-CHECKS============================================== */
-struct tevent_req *sysdb_add_basic_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell)
+int sysdb_add_basic_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell)
{
- struct tevent_req *req, *subreq;
- struct sysdb_op_state *state;
- struct ldb_request *ldbreq;
struct ldb_message *msg;
int ret;
- req = tevent_req_create(mem_ctx, &state, struct sysdb_op_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->ignore_not_found = false;
- state->ldbreply = NULL;
-
- msg = ldb_msg_new(state);
+ msg = ldb_msg_new(mem_ctx);
if (!msg) {
- ERROR_OUT(ret, ENOMEM, fail);
+ return ENOMEM;
}
/* user dn */
- msg->dn = sysdb_user_dn(handle->ctx, msg, domain->name, name);
+ msg->dn = sysdb_user_dn(ctx, msg, domain->name, name);
if (!msg->dn) {
- ERROR_OUT(ret, ENOMEM, fail);
+ ERROR_OUT(ret, ENOMEM, done);
}
ret = add_string(msg, LDB_FLAG_MOD_ADD, "objectClass", SYSDB_USER_CLASS);
- if (ret) goto fail;
+ if (ret) goto done;
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name);
- if (ret) goto fail;
+ if (ret) goto done;
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_UIDNUM, (unsigned long)uid);
- if (ret) goto fail;
+ if (ret) goto done;
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid);
- if (ret) goto fail;
+ if (ret) goto done;
/* We set gecos to be the same as fullname on user creation,
* But we will not enforce coherency after that, it's up to
@@ -843,270 +831,164 @@ struct tevent_req *sysdb_add_basic_user_send(TALLOC_CTX *mem_ctx,
* one of the 2 */
if (gecos && *gecos) {
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_FULLNAME, gecos);
- if (ret) goto fail;
+ if (ret) goto done;
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_GECOS, gecos);
- if (ret) goto fail;
+ if (ret) goto done;
}
if (homedir && *homedir) {
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_HOMEDIR, homedir);
- if (ret) goto fail;
+ if (ret) goto done;
}
if (shell && *shell) {
ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_SHELL, shell);
- if (ret) goto fail;
+ if (ret) goto done;
}
/* creation time */
ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
(unsigned long)time(NULL));
- if (ret) goto fail;
+ if (ret) goto done;
+ ret = ldb_add(ctx->ldb, msg);
+ ret = sysdb_error_to_errno(ret);
- ret = ldb_build_add_req(&ldbreq, handle->ctx->ldb, state, msg,
- NULL, NULL, NULL, NULL);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to build modify request: %s(%d)[%s]\n",
- ldb_strerror(ret), ret, ldb_errstring(handle->ctx->ldb)));
- ERROR_OUT(ret, sysdb_error_to_errno(ret), fail);
- }
-
- subreq = sldb_request_send(state, ev, handle->ctx->ldb, ldbreq);
- if (!subreq) {
- ERROR_OUT(ret, ENOMEM, fail);
+done:
+ if (ret) {
+ DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
}
- tevent_req_set_callback(subreq, sysdb_op_default_done, req);
-
- return req;
-
-fail:
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-int sysdb_add_basic_user_recv(struct tevent_req *req)
-{
- return sysdb_op_default_recv(req);
+ talloc_zfree(msg);
+ return ret;
}
/* =Add-User-Function===================================================== */
-struct sysdb_add_user_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sss_domain_info *domain;
-
- const char *name;
- uid_t uid;
- gid_t gid;
- const char *gecos;
- const char *homedir;
- const char *shell;
- struct sysdb_attrs *attrs;
-
- int cache_timeout;
-};
-
-static void sysdb_add_user_basic_done(struct tevent_req *subreq);
-
-struct tevent_req *sysdb_add_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell,
- struct sysdb_attrs *attrs,
- int cache_timeout)
+int sysdb_add_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell,
+ struct sysdb_attrs *attrs,
+ int cache_timeout)
{
- struct tevent_req *req, *subreq;
- struct sysdb_add_user_state *state;
+ TALLOC_CTX *tmpctx;
struct ldb_message *msg;
+ struct sysdb_attrs *id_attrs;
+ uint32_t id;
+ time_t now;
int ret;
- req = tevent_req_create(mem_ctx, &state, struct sysdb_add_user_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->domain = domain;
- state->name = name;
- state->uid = uid;
- state->gid = gid;
- state->gecos = gecos;
- state->homedir = homedir;
- state->shell = shell;
- state->attrs = attrs;
- state->cache_timeout = cache_timeout;
-
- if (handle->ctx->mpg) {
+ if (ctx->mpg) {
if (gid != 0) {
DEBUG(0, ("Cannot add user with arbitrary GID in MPG domain!\n"));
- ERROR_OUT(ret, EINVAL, fail);
+ return EINVAL;
}
- state->gid = state->uid;
+ gid = uid;
}
if (domain->id_max != 0 && uid != 0 &&
(uid < domain->id_min || uid > domain->id_max)) {
DEBUG(2, ("Supplied uid [%d] is not in the allowed range [%d-%d].\n",
uid, domain->id_min, domain->id_max));
- ERROR_OUT(ret, ERANGE, fail);
+ return ERANGE;
}
if (domain->id_max != 0 && gid != 0 &&
(gid < domain->id_min || gid > domain->id_max)) {
DEBUG(2, ("Supplied gid [%d] is not in the allowed range [%d-%d].\n",
gid, domain->id_min, domain->id_max));
- ERROR_OUT(ret, ERANGE, fail);
+ return ERANGE;
}
- if (handle->ctx->mpg) {
+ tmpctx = talloc_new(mem_ctx);
+ if (!tmpctx) {
+ return ENOMEM;
+ }
+
+ if (ctx->mpg) {
/* In MPG domains you can't have groups with the same name as users,
* search if a group with the same name exists.
* Don't worry about users, if we try to add a user with the same
* name the operation will fail */
- ret = sysdb_search_group_by_name(state, handle->ctx,
+ ret = sysdb_search_group_by_name(tmpctx, ctx,
domain, name, NULL, &msg);
if (ret != ENOENT) {
if (ret == EOK) ret = EEXIST;
- goto fail;
+ goto done;
}
}
/* check no other user with the same uid exist */
- if (state->uid != 0) {
- ret = sysdb_search_user_by_uid(state, handle->ctx,
+ if (uid != 0) {
+ ret = sysdb_search_user_by_uid(tmpctx, ctx,
domain, uid, NULL, &msg);
if (ret != ENOENT) {
if (ret == EOK) ret = EEXIST;
- goto fail;
+ goto done;
}
}
/* try to add the user */
- subreq = sysdb_add_basic_user_send(state, ev, handle,
- domain, name, uid, gid,
- gecos, homedir, shell);
- if (!subreq) {
- ERROR_OUT(ret, ENOMEM, fail);
- }
- tevent_req_set_callback(subreq, sysdb_add_user_basic_done, req);
- return req;
-
-fail:
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sysdb_add_user_basic_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sysdb_add_user_state *state = tevent_req_data(req,
- struct sysdb_add_user_state);
- struct sysdb_attrs *id_attrs;
- uint32_t id;
- time_t now;
- int ret;
-
- ret = sysdb_add_basic_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
+ ret = sysdb_add_basic_user(tmpctx, ctx,
+ domain, name, uid, gid,
+ gecos, homedir, shell);
+ if (ret) goto done;
- if (state->uid == 0) {
- ret = sysdb_get_new_id(state, state->handle->ctx, state->domain, &id);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
+ if (uid == 0) {
+ ret = sysdb_get_new_id(tmpctx, ctx, domain, &id);
+ if (ret) goto done;
- id_attrs = sysdb_new_attrs(state);
+ id_attrs = sysdb_new_attrs(tmpctx);
if (!id_attrs) {
- DEBUG(6, ("Error: Out of memory\n"));
- tevent_req_error(req, ENOMEM);
- return;
+ ret = ENOMEM;
+ goto done;
}
ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_UIDNUM, id);
- if (ret) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
- if (state->handle->ctx->mpg) {
+ if (ret) goto done;
+
+ if (ctx->mpg) {
ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_GIDNUM, id);
- if (ret) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
+ if (ret) goto done;
}
- ret = sysdb_set_user_attr(state, state->handle->ctx,
- state->domain, state->name,
- id_attrs, SYSDB_MOD_REP);
- if (ret) {
- tevent_req_error(req, ret);
- } else {
- tevent_req_done(req);
- }
- return;
+ ret = sysdb_set_user_attr(tmpctx, ctx,
+ domain, name, id_attrs, SYSDB_MOD_REP);
+ goto done;
}
- if (!state->attrs) {
- state->attrs = sysdb_new_attrs(state);
- if (!state->attrs) {
- tevent_req_error(req, ENOMEM);
- return;
+ if (!attrs) {
+ attrs = sysdb_new_attrs(tmpctx);
+ if (!attrs) {
+ ret = ENOMEM;
+ goto done;
}
}
now = time(NULL);
- ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
- if (ret) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
+ if (ret) goto done;
- ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
- ((state->cache_timeout) ?
- (now + state->cache_timeout) : 0));
- if (ret) {
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
- }
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
+ ((cache_timeout) ?
+ (now + cache_timeout) : 0));
+ if (ret) goto done;
- ret = sysdb_set_user_attr(state, state->handle->ctx,
- state->domain, state->name,
- state->attrs, SYSDB_MOD_REP);
+ ret = sysdb_set_user_attr(tmpctx, ctx,
+ domain, name, attrs, SYSDB_MOD_REP);
+
+done:
if (ret) {
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
}
-
- tevent_req_done(req);
-}
-
-int sysdb_add_user_recv(struct tevent_req *req)
-{
- return sysdb_op_default_recv(req);
+ talloc_zfree(tmpctx);
+ return ret;
}
@@ -1441,174 +1323,104 @@ int sysdb_mod_group_member_recv(struct tevent_req *req)
/* if one of the basic attributes is empty ("") as opposed to NULL,
* this will just remove it */
-struct sysdb_store_user_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sss_domain_info *domain;
-
- const char *name;
- uid_t uid;
- gid_t gid;
- const char *gecos;
- const char *homedir;
- const char *shell;
- struct sysdb_attrs *attrs;
-
- uint64_t cache_timeout;
-};
-
-static void sysdb_store_user_add_done(struct tevent_req *subreq);
-
-struct tevent_req *sysdb_store_user_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name,
- const char *pwd,
- uid_t uid, gid_t gid,
- const char *gecos,
- const char *homedir,
- const char *shell,
- struct sysdb_attrs *attrs,
- uint64_t cache_timeout)
+int sysdb_store_user(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ const char *pwd,
+ uid_t uid, gid_t gid,
+ const char *gecos,
+ const char *homedir,
+ const char *shell,
+ struct sysdb_attrs *attrs,
+ uint64_t cache_timeout)
{
- struct tevent_req *req, *subreq;
- struct sysdb_store_user_state *state;
+ TALLOC_CTX *tmpctx;
struct ldb_message *msg;
time_t now;
int ret;
- req = tevent_req_create(mem_ctx, &state, struct sysdb_store_user_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->domain = domain;
- state->name = name;
- state->uid = uid;
- state->gid = gid;
- state->gecos = gecos;
- state->homedir = homedir;
- state->shell = shell;
- state->attrs = attrs;
- state->cache_timeout = cache_timeout;
+ tmpctx = talloc_new(mem_ctx);
+ if (!tmpctx) {
+ return ENOMEM;
+ }
if (pwd && (domain->legacy_passwords || !*pwd)) {
- ret = sysdb_attrs_add_string(state->attrs, SYSDB_PWD, pwd);
- if (ret) goto fail;
+ ret = sysdb_attrs_add_string(attrs, SYSDB_PWD, pwd);
+ if (ret) goto done;
}
- ret = sysdb_search_user_by_name(state, handle->ctx,
+ ret = sysdb_search_user_by_name(tmpctx, ctx,
domain, name, NULL, &msg);
if (ret && ret != ENOENT) {
- goto fail;
+ goto done;
}
if (ret == ENOENT) {
/* users doesn't exist, turn into adding a user */
- subreq = sysdb_add_user_send(state, state->ev, state->handle,
- state->domain, state->name,
- state->uid, state->gid,
- state->gecos, state->homedir,
- state->shell, state->attrs,
- state->cache_timeout);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sysdb_store_user_add_done, req);
-
- return req;
+ ret = sysdb_add_user(tmpctx, ctx, domain, name, uid, gid,
+ gecos, homedir, shell, attrs, cache_timeout);
+ goto done;
}
/* the user exists, let's just replace attributes when set */
- if (!state->attrs) {
- state->attrs = sysdb_new_attrs(state);
- if (!state->attrs) {
+ if (!attrs) {
+ attrs = sysdb_new_attrs(tmpctx);
+ if (!attrs) {
ret = ENOMEM;
- goto fail;
+ goto done;
}
}
- if (state->uid) {
- ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_UIDNUM, state->uid);
- if (ret) goto fail;
+ if (uid) {
+ ret = sysdb_attrs_add_uint32(attrs, SYSDB_UIDNUM, uid);
+ if (ret) goto done;
}
- if (state->gid) {
- ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, state->gid);
- if (ret) goto fail;
+ if (gid) {
+ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
+ if (ret) goto done;
}
- if (state->uid && !state->gid && state->handle->ctx->mpg) {
- ret = sysdb_attrs_add_uint32(state->attrs, SYSDB_GIDNUM, state->uid);
- if (ret) goto fail;
+ if (uid && !gid && ctx->mpg) {
+ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, uid);
+ if (ret) goto done;
}
- if (state->gecos) {
- ret = sysdb_attrs_add_string(state->attrs, SYSDB_GECOS, state->gecos);
- if (ret) goto fail;
+ if (gecos) {
+ ret = sysdb_attrs_add_string(attrs, SYSDB_GECOS, gecos);
+ if (ret) goto done;
}
- if (state->homedir) {
- ret = sysdb_attrs_add_string(state->attrs,
- SYSDB_HOMEDIR, state->homedir);
- if (ret) goto fail;
+ if (homedir) {
+ ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, homedir);
+ if (ret) goto done;
}
- if (state->shell) {
- ret = sysdb_attrs_add_string(state->attrs, SYSDB_SHELL, state->shell);
- if (ret) goto fail;
+ if (shell) {
+ ret = sysdb_attrs_add_string(attrs, SYSDB_SHELL, shell);
+ if (ret) goto done;
}
now = time(NULL);
- ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_LAST_UPDATE, now);
- if (ret) goto fail;
-
- ret = sysdb_attrs_add_time_t(state->attrs, SYSDB_CACHE_EXPIRE,
- ((state->cache_timeout) ?
- (now + state->cache_timeout) : 0));
- if (ret) goto fail;
-
- ret = sysdb_set_user_attr(state, state->handle->ctx,
- state->domain, state->name,
- state->attrs, SYSDB_MOD_REP);
- if (ret) {
- goto fail;
- }
-
- tevent_req_done(req);
- tevent_req_post(req, ev);
- return req;
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
+ if (ret) goto done;
-fail:
- DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
+ ((cache_timeout) ?
+ (now + cache_timeout) : 0));
+ if (ret) goto done;
-static void sysdb_store_user_add_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- int ret;
+ ret = sysdb_set_user_attr(tmpctx, ctx,
+ domain, name, attrs, SYSDB_MOD_REP);
- ret = sysdb_add_user_recv(subreq);
- talloc_zfree(subreq);
+done:
if (ret) {
DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret)));
- tevent_req_error(req, ret);
- return;
}
-
- tevent_req_done(req);
-}
-
-int sysdb_store_user_recv(struct tevent_req *req)
-{
- return sysdb_op_default_recv(req);
+ talloc_zfree(tmpctx);
+ return ret;
}
/* =Store-Group-(Native/Legacy)-(replaces-existing-data)================== */
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 56bd85fb..422e6a5d 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -25,34 +25,19 @@
/* ==Save-User-Entry====================================================== */
-struct sdap_save_user_state {
- struct tevent_context *ev;
- struct sysdb_handle *handle;
- struct sdap_options *opts;
-
- struct sss_domain_info *dom;
-
- const char *name;
- struct sysdb_attrs *attrs;
- char *timestamp;
-};
-
-static void sdap_save_user_done(struct tevent_req *subreq);
-
- /* FIXME: support storing additional attributes */
-
-static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle,
- struct sdap_options *opts,
- struct sss_domain_info *dom,
- struct sysdb_attrs *attrs,
- bool is_initgr)
+/* FIXME: support storing additional attributes */
+
+static int sdap_save_user(TALLOC_CTX *memctx,
+ struct sysdb_ctx *ctx,
+ struct sdap_options *opts,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs *attrs,
+ bool is_initgr,
+ char **_timestamp)
{
- struct tevent_req *req, *subreq;
- struct sdap_save_user_state *state;
struct ldb_message_element *el;
int ret;
+ const char *name;
const char *pwd;
const char *gecos;
const char *homedir;
@@ -65,58 +50,49 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
int i;
char *val = NULL;
int cache_timeout;
+ char *timestamp = NULL;
DEBUG(9, ("Save user\n"));
- req = tevent_req_create(memctx, &state, struct sdap_save_user_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->handle = handle;
- state->dom = dom;
- state->opts = opts;
- state->attrs = attrs;
- state->timestamp = NULL;
-
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_NAME].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) {
ret = EINVAL;
goto fail;
}
- state->name = (const char *)el->values[0].data;
+ name = (const char *)el->values[0].data;
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_PWD].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) pwd = NULL;
else pwd = (const char *)el->values[0].data;
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) gecos = NULL;
else gecos = (const char *)el->values[0].data;
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_HOME].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) homedir = NULL;
else homedir = (const char *)el->values[0].data;
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) shell = NULL;
else shell = (const char *)el->values[0].data;
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_UID].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) {
DEBUG(1, ("no uid provided for [%s] in domain [%s].\n",
- state->name, dom->name));
+ name, dom->name));
ret = EINVAL;
goto fail;
}
@@ -131,17 +107,17 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
/* check that the uid is valid for this domain */
if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
+ name));
ret = EINVAL;
goto fail;
}
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_GID].sys_name, &el);
if (ret) goto fail;
if (el->num_values == 0) {
DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
- state->name, dom->name));
+ name, dom->name));
ret = EINVAL;
goto fail;
}
@@ -156,26 +132,26 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
/* check that the gid is valid for this domain */
if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
+ name));
ret = EINVAL;
goto fail;
}
- user_attrs = sysdb_new_attrs(state);
+ user_attrs = sysdb_new_attrs(memctx);
if (user_attrs == NULL) {
ret = ENOMEM;
goto fail;
}
- ret = sysdb_attrs_get_el(state->attrs, SYSDB_ORIG_DN, &el);
+ ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
if (ret) {
goto fail;
}
if (el->num_values == 0) {
- DEBUG(7, ("Original DN is not available for [%s].\n", state->name));
+ DEBUG(7, ("Original DN is not available for [%s].\n", name));
} else {
DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
- el->values[0].data, state->name));
+ el->values[0].data, name));
ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN,
(const char *) el->values[0].data);
if (ret) {
@@ -183,16 +159,16 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
}
}
- ret = sysdb_attrs_get_el(state->attrs, SYSDB_MEMBEROF, &el);
+ ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el);
if (ret) {
goto fail;
}
if (el->num_values == 0) {
DEBUG(7, ("Original memberOf is not available for [%s].\n",
- state->name));
+ name));
} else {
DEBUG(7, ("Adding original memberOf attributes to [%s].\n",
- state->name));
+ name));
for (i = 0; i < el->num_values; i++) {
ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF,
(const char *) el->values[i].data);
@@ -202,14 +178,14 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
}
}
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name, &el);
if (ret) {
goto fail;
}
if (el->num_values == 0) {
DEBUG(7, ("Original mod-Timestamp is not available for [%s].\n",
- state->name));
+ name));
} else {
ret = sysdb_attrs_add_string(user_attrs,
opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name,
@@ -217,21 +193,20 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
if (ret) {
goto fail;
}
- state->timestamp = talloc_strdup(state,
- (const char*)el->values[0].data);
- if (!state->timestamp) {
+ timestamp = talloc_strdup(memctx, (const char*)el->values[0].data);
+ if (!timestamp) {
ret = ENOMEM;
goto fail;
}
}
- ret = sysdb_attrs_get_el(state->attrs,
+ ret = sysdb_attrs_get_el(attrs,
opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el);
if (ret) {
goto fail;
}
if (el->num_values == 0) {
- DEBUG(7, ("User principle is not available for [%s].\n", state->name));
+ DEBUG(7, ("User principle is not available for [%s].\n", name));
} else {
upn = talloc_strdup(user_attrs, (const char*) el->values[0].data);
if (!upn) {
@@ -242,7 +217,7 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
make_realm_upper_case(upn);
}
DEBUG(7, ("Adding user principle [%s] to attributes of [%s].\n",
- upn, state->name));
+ upn, name));
ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn);
if (ret) {
goto fail;
@@ -250,7 +225,7 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
}
for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
- ret = sysdb_attrs_get_el(state->attrs, opts->user_map[i].sys_name, &el);
+ ret = sysdb_attrs_get_el(attrs, opts->user_map[i].sys_name, &el);
if (ret) {
goto fail;
}
@@ -282,58 +257,22 @@ static struct tevent_req *sdap_save_user_send(TALLOC_CTX *memctx,
}
}
- DEBUG(6, ("Storing info for user %s\n", state->name));
+ DEBUG(6, ("Storing info for user %s\n", name));
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->dom, state->name, pwd,
- uid, gid, gecos, homedir, shell,
- user_attrs, cache_timeout);
- if (!subreq) {
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sdap_save_user_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void sdap_save_user_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_save_user_state *state = tevent_req_data(req,
- struct sdap_save_user_state);
- int ret;
-
- ret = sysdb_store_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Failed to save user %s\n", state->name));
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int sdap_save_user_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx, char **timestamp)
-{
- struct sdap_save_user_state *state = tevent_req_data(req,
- struct sdap_save_user_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
+ ret = sysdb_store_user(memctx, ctx, dom,
+ name, pwd, uid, gid, gecos, homedir, shell,
+ user_attrs, cache_timeout);
+ if (ret) goto fail;
- if (timestamp) {
- *timestamp = talloc_steal(mem_ctx, state->timestamp);
+ if (_timestamp) {
+ *_timestamp = timestamp;
}
return EOK;
+
+fail:
+ DEBUG(2, ("Failed to save user %s\n", name));
+ return ret;
}
@@ -347,7 +286,6 @@ struct sdap_save_users_state {
struct sysdb_attrs **users;
int count;
- int cur;
struct sysdb_handle *handle;
@@ -355,8 +293,6 @@ struct sdap_save_users_state {
};
static void sdap_save_users_trans(struct tevent_req *subreq);
-static void sdap_save_users_store(struct tevent_req *req);
-static void sdap_save_users_process(struct tevent_req *subreq);
struct tevent_req *sdap_save_users_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sss_domain_info *dom,
@@ -377,7 +313,6 @@ struct tevent_req *sdap_save_users_send(TALLOC_CTX *memctx,
state->dom = dom;
state->users = users;
state->count = num_users;
- state->cur = 0;
state->handle = NULL;
state->higher_timestamp = NULL;
@@ -396,7 +331,9 @@ static void sdap_save_users_trans(struct tevent_req *subreq)
{
struct tevent_req *req;
struct sdap_save_users_state *state;
+ char *timestamp;
int ret;
+ int i;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_save_users_state);
@@ -408,73 +345,44 @@ static void sdap_save_users_trans(struct tevent_req *subreq)
return;
}
- sdap_save_users_store(req);
-}
-
-static void sdap_save_users_store(struct tevent_req *req)
-{
- struct tevent_req *subreq;
- struct sdap_save_users_state *state;
-
- state = tevent_req_data(req, struct sdap_save_users_state);
-
- subreq = sdap_save_user_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->users[state->cur], false);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_save_users_process, req);
-}
-
-static void sdap_save_users_process(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct sdap_save_users_state *state;
- char *timestamp = NULL;
- int ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct sdap_save_users_state);
+ for (i = 0; i < state->count; i++) {
+ timestamp = NULL;
- ret = sdap_save_user_recv(subreq, state, &timestamp);
- talloc_zfree(subreq);
+ ret = sdap_save_user(state, state->sysdb,
+ state->opts, state->dom,
+ state->users[i],
+ false, &timestamp);
- /* Do not fail completely on errors.
- * Just report the failure to save and go on */
- if (ret) {
- DEBUG(2, ("Failed to store user %d. Ignoring.\n", state->cur));
- } else {
- DEBUG(9, ("User %d processed!\n", state->cur));
- }
+ /* Do not fail completely on errors.
+ * Just report the failure to save and go on */
+ if (ret) {
+ DEBUG(2, ("Failed to store user %d. Ignoring.\n", i));
+ } else {
+ DEBUG(9, ("User %d processed!\n", i));
+ }
- if (timestamp) {
- if (state->higher_timestamp) {
- if (strcmp(timestamp, state->higher_timestamp) > 0) {
- talloc_zfree(state->higher_timestamp);
- state->higher_timestamp = timestamp;
+ if (timestamp) {
+ if (state->higher_timestamp) {
+ if (strcmp(timestamp, state->higher_timestamp) > 0) {
+ talloc_zfree(state->higher_timestamp);
+ state->higher_timestamp = timestamp;
+ } else {
+ talloc_zfree(timestamp);
+ }
} else {
- talloc_zfree(timestamp);
+ state->higher_timestamp = timestamp;
}
- } else {
- state->higher_timestamp = timestamp;
}
}
- state->cur++;
- if (state->cur < state->count) {
- sdap_save_users_store(req);
- } else {
- subreq = sysdb_transaction_commit_send(state, state->ev,
- state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- /* sysdb_transaction_complete will call tevent_req_done(req) */
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
+ subreq = sysdb_transaction_commit_send(state, state->ev,
+ state->handle);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
}
+ /* sysdb_transaction_complete will call tevent_req_done(req) */
+ tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
}
static int sdap_save_users_recv(struct tevent_req *req,
@@ -1780,7 +1688,6 @@ struct sdap_get_initgr_state {
static void sdap_get_initgr_user(struct tevent_req *subreq);
static void sdap_get_initgr_store(struct tevent_req *subreq);
-static void sdap_get_initgr_commit(struct tevent_req *subreq);
static void sdap_get_initgr_process(struct tevent_req *subreq);
static void sdap_get_initgr_done(struct tevent_req *subreq);
@@ -1903,33 +1810,16 @@ static void sdap_get_initgr_store(struct tevent_req *subreq)
return;
}
- subreq = sdap_save_user_send(state, state->ev, state->handle,
- state->opts, state->dom,
- state->orig_user, true);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, sdap_get_initgr_commit, req);
-}
-
-static void sdap_get_initgr_commit(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sdap_get_initgr_state *state = tevent_req_data(req,
- struct sdap_get_initgr_state);
- int ret;
-
- DEBUG(9, ("Commit change\n"));
-
- ret = sdap_save_user_recv(subreq, NULL, NULL);
- talloc_zfree(subreq);
+ ret = sdap_save_user(state, state->sysdb,
+ state->opts, state->dom,
+ state->orig_user, true, NULL);
if (ret) {
tevent_req_error(req, ret);
return;
}
+ DEBUG(9, ("Commit change\n"));
+
subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
if (!subreq) {
tevent_req_error(req, ENOMEM);
diff --git a/src/providers/proxy.c b/src/providers/proxy.c
index 84a966a2..150639ce 100644
--- a/src/providers/proxy.c
+++ b/src/providers/proxy.c
@@ -345,7 +345,8 @@ static int proxy_default_recv(struct tevent_req *req)
/* =Getpwnam-wrapper======================================================*/
static void get_pw_name_process(struct tevent_req *subreq);
-static void get_pw_name_add_done(struct tevent_req *subreq);
+static int delete_user(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain, const char *name);
static struct tevent_req *get_pw_name_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -389,7 +390,6 @@ static void get_pw_name_process(struct tevent_req *subreq)
enum nss_status status;
char *buffer;
size_t buflen;
- bool delete_user = false;
int ret;
DEBUG(7, ("Searching user by name (%s)\n", state->name));
@@ -423,7 +423,12 @@ static void get_pw_name_process(struct tevent_req *subreq)
case NSS_STATUS_NOTFOUND:
DEBUG(7, ("User %s not found.\n", state->name));
- delete_user = true;
+ ret = delete_user(state, state->sysdb,
+ state->domain, state->name);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
break;
case NSS_STATUS_SUCCESS:
@@ -437,28 +442,32 @@ static void get_pw_name_process(struct tevent_req *subreq)
if (OUT_OF_ID_RANGE(state->pwd->pw_uid, dom->id_min, dom->id_max) ||
OUT_OF_ID_RANGE(state->pwd->pw_gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
- delete_user = true;
+ DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
+ state->name));
+ ret = delete_user(state, state->sysdb,
+ state->domain, state->name);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
break;
}
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->domain,
- state->pwd->pw_name,
- state->pwd->pw_passwd,
- state->pwd->pw_uid,
- state->pwd->pw_gid,
- state->pwd->pw_gecos,
- state->pwd->pw_dir,
- state->pwd->pw_shell,
- NULL, ctx->entry_cache_timeout);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
+ ret = sysdb_store_user(state, state->sysdb,
+ state->domain,
+ state->pwd->pw_name,
+ state->pwd->pw_passwd,
+ state->pwd->pw_uid,
+ state->pwd->pw_gid,
+ state->pwd->pw_gecos,
+ state->pwd->pw_dir,
+ state->pwd->pw_shell,
+ NULL, ctx->entry_cache_timeout);
+ if (ret) {
+ tevent_req_error(req, ret);
return;
}
- tevent_req_set_callback(subreq, get_pw_name_add_done, req);
- return;
+ break;
case NSS_STATUS_UNAVAIL:
/* "remote" backend unavailable. Enter offline mode */
@@ -466,63 +475,37 @@ static void get_pw_name_process(struct tevent_req *subreq)
return;
default:
- break;
+ goto fail;
}
- if (delete_user) {
- struct ldb_dn *dn;
-
- DEBUG(7, ("User %s does not exist (or is invalid) on remote server,"
- " deleting!\n", state->name));
-
- dn = sysdb_user_dn(state->sysdb, state,
- state->domain->name, state->name);
- if (!dn) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- ret = sysdb_delete_entry(state->sysdb, dn, true);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, proxy_default_done, req);
+ subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
return;
}
+ tevent_req_set_callback(subreq, proxy_default_done, req);
+ return;
+fail:
DEBUG(2, ("proxy -> getpwnam_r failed for '%s' <%d>\n",
state->name, status));
tevent_req_error(req, EIO);
}
-static void get_pw_name_add_done(struct tevent_req *subreq)
+static int delete_user(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
+ struct sss_domain_info *domain, const char *name)
{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct proxy_state *state = tevent_req_data(req,
- struct proxy_state);
- int ret;
+ struct ldb_dn *dn;
- ret = sysdb_store_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
+ DEBUG(7, ("User %s does not exist (or is invalid) on remote server,"
+ " deleting!\n", name));
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
+ dn = sysdb_user_dn(sysdb, mem_ctx, domain->name, name);
+ if (!dn) {
+ return ENOMEM;
}
- tevent_req_set_callback(subreq, proxy_default_done, req);
+
+ return sysdb_delete_entry(sysdb, dn, true);
}
/* =Getpwuid-wrapper======================================================*/
@@ -572,7 +555,7 @@ static void get_pw_uid_process(struct tevent_req *subreq)
enum nss_status status;
char *buffer;
size_t buflen;
- bool delete_user = false;
+ bool del_user = false;
int ret;
DEBUG(7, ("Searching user by uid (%d)\n", state->uid));
@@ -607,7 +590,7 @@ static void get_pw_uid_process(struct tevent_req *subreq)
case NSS_STATUS_NOTFOUND:
DEBUG(7, ("User %d not found.\n", state->uid));
- delete_user = true;
+ del_user = true;
break;
case NSS_STATUS_SUCCESS:
@@ -621,28 +604,27 @@ static void get_pw_uid_process(struct tevent_req *subreq)
if (OUT_OF_ID_RANGE(state->pwd->pw_uid, dom->id_min, dom->id_max) ||
OUT_OF_ID_RANGE(state->pwd->pw_gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
- delete_user = true;
+ DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
+ state->pwd->pw_name));
+ del_user = true;
break;
}
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->domain,
- state->pwd->pw_name,
- state->pwd->pw_passwd,
- state->pwd->pw_uid,
- state->pwd->pw_gid,
- state->pwd->pw_gecos,
- state->pwd->pw_dir,
- state->pwd->pw_shell,
- NULL, ctx->entry_cache_timeout);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
+ ret = sysdb_store_user(state, state->sysdb,
+ state->domain,
+ state->pwd->pw_name,
+ state->pwd->pw_passwd,
+ state->pwd->pw_uid,
+ state->pwd->pw_gid,
+ state->pwd->pw_gecos,
+ state->pwd->pw_dir,
+ state->pwd->pw_shell,
+ NULL, ctx->entry_cache_timeout);
+ if (ret) {
+ tevent_req_error(req, ret);
return;
}
- tevent_req_set_callback(subreq, get_pw_name_add_done, req);
- return;
+ break;
case NSS_STATUS_UNAVAIL:
/* "remote" backend unavailable. Enter offline mode */
@@ -656,7 +638,7 @@ static void get_pw_uid_process(struct tevent_req *subreq)
return;
}
- if (delete_user) {
+ if (del_user) {
DEBUG(7, ("User %d does not exist (or is invalid) on remote server,"
" deleting!\n", state->uid));
@@ -669,7 +651,15 @@ static void get_pw_uid_process(struct tevent_req *subreq)
return;
}
tevent_req_set_callback(subreq, get_pw_uid_remove_done, req);
+ return;
}
+
+ subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, proxy_default_done, req);
}
static void get_pw_uid_remove_done(struct tevent_req *subreq)
@@ -708,8 +698,6 @@ struct enum_users_state {
size_t buflen;
char *buffer;
-
- bool in_transaction;
};
static void enum_users_process(struct tevent_req *subreq);
@@ -748,8 +736,6 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *mem_ctx,
goto fail;
}
- state->in_transaction = false;
-
status = ctx->ops.setpwent();
if (status != NSS_STATUS_SUCCESS) {
tevent_req_error(req, EIO);
@@ -782,23 +768,11 @@ static void enum_users_process(struct tevent_req *subreq)
char *newbuf;
int ret;
- if (!state->in_transaction) {
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- if (ret) {
- goto fail;
- }
- talloc_zfree(subreq);
-
- state->in_transaction = true;
- } else {
- ret = sysdb_store_user_recv(subreq);
- if (ret) {
- /* Do not fail completely on errors.
- * Just report the failure to save and go on */
- DEBUG(2, ("Failed to store user. Ignoring.\n"));
- }
- talloc_zfree(subreq);
+ ret = sysdb_transaction_recv(subreq, state, &state->handle);
+ if (ret) {
+ goto fail;
}
+ talloc_zfree(subreq);
again:
/* always zero out the pwd structure */
@@ -850,28 +824,29 @@ again:
if (OUT_OF_ID_RANGE(state->pwd->pw_uid, dom->id_min, dom->id_max) ||
OUT_OF_ID_RANGE(state->pwd->pw_gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->pwd->pw_name));
+ DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
+ state->pwd->pw_name));
goto again; /* skip */
}
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->domain,
- state->pwd->pw_name,
- state->pwd->pw_passwd,
- state->pwd->pw_uid,
- state->pwd->pw_gid,
- state->pwd->pw_gecos,
- state->pwd->pw_dir,
- state->pwd->pw_shell,
- NULL, ctx->entry_cache_timeout);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
+ ret = sysdb_store_user(state, state->sysdb,
+ state->domain,
+ state->pwd->pw_name,
+ state->pwd->pw_passwd,
+ state->pwd->pw_uid,
+ state->pwd->pw_gid,
+ state->pwd->pw_gecos,
+ state->pwd->pw_dir,
+ state->pwd->pw_shell,
+ NULL, ctx->entry_cache_timeout);
+ if (ret) {
+ /* Do not fail completely on errors.
+ * Just report the failure to save and go on */
+ DEBUG(2, ("Failed to store user %s. Ignoring.\n",
+ state->pwd->pw_name));
}
- tevent_req_set_callback(subreq, enum_users_process, req);
- return;
+ goto again; /* next */
case NSS_STATUS_UNAVAIL:
/* "remote" backend unavailable. Enter offline mode */
@@ -1542,7 +1517,7 @@ fail:
/* =Initgroups-wrapper====================================================*/
static void get_initgr_process(struct tevent_req *subreq);
-static void get_initgr_groups_process(struct tevent_req *subreq);
+static void get_initgr_groups_process(struct tevent_req *req);
static void get_initgr_groups_done(struct tevent_req *subreq);
static struct tevent_req *get_groups_by_gid_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -1605,7 +1580,6 @@ static void get_initgr_process(struct tevent_req *subreq)
enum nss_status status;
char *buffer;
size_t buflen;
- bool delete_user = false;
int ret;
ret = sysdb_transaction_recv(subreq, state, &state->handle);
@@ -1636,7 +1610,13 @@ static void get_initgr_process(struct tevent_req *subreq)
switch (status) {
case NSS_STATUS_NOTFOUND:
- delete_user = true;
+ DEBUG(7, ("User %s not found.\n", state->name));
+ ret = delete_user(state, state->sysdb,
+ state->domain, state->name);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
break;
case NSS_STATUS_SUCCESS:
@@ -1646,27 +1626,33 @@ static void get_initgr_process(struct tevent_req *subreq)
if (OUT_OF_ID_RANGE(state->pwd->pw_uid, dom->id_min, dom->id_max) ||
OUT_OF_ID_RANGE(state->pwd->pw_gid, dom->id_min, dom->id_max)) {
- DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
- state->name));
- delete_user = true;
+ DEBUG(2, ("User [%s] filtered out! (id out of range)\n",
+ state->name));
+ ret = delete_user(state, state->sysdb,
+ state->domain, state->name);
+ if (ret) {
+ tevent_req_error(req, ret);
+ return;
+ }
break;
}
- subreq = sysdb_store_user_send(state, state->ev, state->handle,
- state->domain,
- state->pwd->pw_name,
- state->pwd->pw_passwd,
- state->pwd->pw_uid,
- state->pwd->pw_gid,
- state->pwd->pw_gecos,
- state->pwd->pw_dir,
- state->pwd->pw_shell,
- NULL, ctx->entry_cache_timeout);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
+ ret = sysdb_store_user(state, state->sysdb,
+ state->domain,
+ state->pwd->pw_name,
+ state->pwd->pw_passwd,
+ state->pwd->pw_uid,
+ state->pwd->pw_gid,
+ state->pwd->pw_gecos,
+ state->pwd->pw_dir,
+ state->pwd->pw_shell,
+ NULL, ctx->entry_cache_timeout);
+ if (ret) {
+ tevent_req_error(req, ret);
return;
}
- tevent_req_set_callback(subreq, get_initgr_groups_process, req);
+
+ get_initgr_groups_process(req);
return;
case NSS_STATUS_UNAVAIL:
@@ -1675,43 +1661,26 @@ static void get_initgr_process(struct tevent_req *subreq)
return;
default:
- break;
+ goto fail;
}
- if (delete_user) {
- struct ldb_dn *dn;
-
- dn = sysdb_user_dn(state->sysdb, state,
- state->domain->name, state->name);
- if (!dn) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- ret = sysdb_delete_entry(state->sysdb, dn, true);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, proxy_default_done, req);
+ subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
return;
}
+ tevent_req_set_callback(subreq, proxy_default_done, req);
+ return;
+fail:
DEBUG(2, ("proxy -> getpwnam_r failed for '%s' <%d>\n",
state->name, status));
tevent_req_error(req, EIO);
}
-static void get_initgr_groups_process(struct tevent_req *subreq)
+static void get_initgr_groups_process(struct tevent_req *req)
{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
+ struct tevent_req *subreq;
struct proxy_state *state = tevent_req_data(req,
struct proxy_state);
struct proxy_ctx *ctx = state->ctx;
@@ -1723,13 +1692,6 @@ static void get_initgr_groups_process(struct tevent_req *subreq)
gid_t *gids;
int ret;
- ret = sysdb_store_user_recv(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
- talloc_zfree(subreq);
-
num_gids = 0;
limit = 4096;
num = 4096;
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 519d1c4b..e75a415f 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -223,8 +223,6 @@ fail:
data->finished = true;
}
-static void test_add_user_done(struct tevent_req *subreq);
-
static void test_add_user(struct tevent_req *subreq)
{
struct test_data *data = tevent_req_callback_data(subreq,
@@ -242,34 +240,17 @@ static void test_add_user(struct tevent_req *subreq)
homedir = talloc_asprintf(data, "/home/testuser%d", data->uid);
gecos = talloc_asprintf(data, "Test User %d", data->uid);
- subreq = sysdb_add_user_send(data, data->ev, data->handle,
- data->ctx->domain, data->username,
- data->uid, 0,
- gecos, homedir, "/bin/bash",
- NULL, 0);
- if (!subreq) {
- return test_return(data, ENOMEM);
- }
- tevent_req_set_callback(subreq, test_add_user_done, data);
-}
-
-static void test_add_user_done(struct tevent_req *subreq)
-{
- struct test_data *data = tevent_req_callback_data(subreq, struct test_data);
- int ret;
-
- ret = sysdb_add_user_recv(subreq);
- talloc_zfree(subreq);
+ ret = sysdb_add_user(data, data->handle->ctx,
+ data->ctx->domain, data->username,
+ data->uid, 0, gecos, homedir, "/bin/bash",
+ NULL, 0);
return test_return(data, ret);
}
-static void test_store_user_done(struct tevent_req *subreq);
-
static void test_store_user(struct tevent_req *req)
{
struct test_data *data = tevent_req_callback_data(req, struct test_data);
- struct tevent_req *subreq;
char *homedir;
char *gecos;
int ret;
@@ -282,26 +263,11 @@ static void test_store_user(struct tevent_req *req)
homedir = talloc_asprintf(data, "/home/testuser%d", data->uid);
gecos = talloc_asprintf(data, "Test User %d", data->uid);
- subreq = sysdb_store_user_send(data, data->ev, data->handle,
- data->ctx->domain, data->username, "x",
- data->uid, 0,
- gecos, homedir,
- data->shell ? data->shell : "/bin/bash",
- NULL, -1);
- if (!subreq) {
- test_return(data, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, test_store_user_done, data);
-}
-
-static void test_store_user_done(struct tevent_req *subreq)
-{
- struct test_data *data = tevent_req_callback_data(subreq, struct test_data);
- int ret;
-
- ret = sysdb_store_user_recv(subreq);
- talloc_zfree(subreq);
+ ret = sysdb_store_user(data, data->handle->ctx,
+ data->ctx->domain, data->username, "x",
+ data->uid, 0, gecos, homedir,
+ data->shell ? data->shell : "/bin/bash",
+ NULL, -1);
return test_return(data, ret);
}
diff --git a/src/tools/sss_sync_ops.c b/src/tools/sss_sync_ops.c
index b68bd4a6..86c17ce6 100644
--- a/src/tools/sss_sync_ops.c
+++ b/src/tools/sss_sync_ops.c
@@ -293,110 +293,6 @@ static int remove_from_groups_recv(struct tevent_req *req)
}
/*
- * Add a user
- */
-struct user_add_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sysdb_handle *handle;
-
- struct ops_ctx *data;
-};
-
-static void user_add_to_group_done(struct tevent_req *groupreq);
-static void user_add_done(struct tevent_req *subreq);
-
-static struct tevent_req *user_add_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data)
-{
- struct user_add_state *state = NULL;
- struct tevent_req *req;
- struct tevent_req *subreq;
-
- req = tevent_req_create(mem_ctx, &state, struct user_add_state);
- if (req == NULL) {
- return NULL;
- }
- state->ev = ev;
- state->sysdb = sysdb;
- state->handle = handle;
- state->data = data;
-
- subreq = sysdb_add_user_send(state, state->ev, state->handle,
- state->data->domain, state->data->name,
- state->data->uid, state->data->gid,
- state->data->gecos, state->data->home,
- state->data->shell, NULL, 0);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
-
- tevent_req_set_callback(subreq, user_add_done, req);
- return req;
-}
-
-static void user_add_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct user_add_state *state = tevent_req_data(req,
- struct user_add_state);
- int ret;
- struct ldb_dn *member_dn;
- struct tevent_req *groupreq;
-
- ret = sysdb_add_user_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (state->data->addgroups) {
- member_dn = sysdb_user_dn(state->sysdb, state,
- state->data->domain->name,
- state->data->name);
- if (!member_dn) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- groupreq = add_to_groups_send(state, state->ev, state->sysdb,
- state->handle, state->data, member_dn);
- tevent_req_set_callback(groupreq, user_add_to_group_done, req);
- return;
- }
-
- return tevent_req_done(req);
-}
-
-static void user_add_to_group_done(struct tevent_req *groupreq)
-{
- struct tevent_req *req = tevent_req_callback_data(groupreq,
- struct tevent_req);
- int ret;
-
- ret = add_to_groups_recv(groupreq);
- talloc_zfree(groupreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
- return;
-}
-
-static int user_add_recv(struct tevent_req *req)
-{
- return sync_ops_recv(req);
-}
-
-/*
* Modify a user
*/
struct user_mod_state {
@@ -1049,23 +945,42 @@ int useradd(TALLOC_CTX *mem_ctx,
int ret;
struct tevent_req *req;
struct sync_op_res *res = NULL;
+ struct ldb_dn *member_dn;
res = talloc_zero(mem_ctx, struct sync_op_res);
if (!res) {
return ENOMEM;
}
- req = user_add_send(res, ev, sysdb, handle, data);
- if (!req) {
- return ENOMEM;
+ ret = sysdb_add_user(res, sysdb,
+ data->domain, data->name, data->uid, data->gid,
+ data->gecos, data->home, data->shell, NULL, 0);
+ if (ret) {
+ goto done;
}
- tevent_req_set_callback(req, useradd_done, res);
- SYNC_LOOP(res, ret);
+ if (data->addgroups) {
+ member_dn = sysdb_user_dn(sysdb, res,
+ data->domain->name, data->name);
+ if (!member_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ req = add_to_groups_send(res, ev, sysdb, handle, data, member_dn);
+ if (!req) {
+ ret = ENOMEM;
+ goto done;
+ }
+ tevent_req_set_callback(req, useradd_done, res);
+
+ SYNC_LOOP(res, ret);
+ }
flush_nscd_cache(mem_ctx, NSCD_DB_PASSWD);
flush_nscd_cache(mem_ctx, NSCD_DB_GROUP);
+done:
talloc_free(res);
return ret;
}
@@ -1076,7 +991,7 @@ static void useradd_done(struct tevent_req *req)
struct sync_op_res *res = tevent_req_callback_data(req,
struct sync_op_res);
- ret = user_add_recv(req);
+ ret = add_to_groups_recv(req);
talloc_free(req);
if (ret) {
DEBUG(2, ("Adding user failed: %s (%d)\n", strerror(ret), ret));