From ed80c73efa51780a39dfc9c72821cf88e95d264c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Apr 12 2010 13:22:14 +0000 Subject: sysdb: convert sysdb_delete_user --- diff --git a/src/db/sysdb.h b/src/db/sysdb.h index e60777c..c219006 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -565,13 +565,10 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx, size_t *msgs_count, struct ldb_message ***msgs); -struct tevent_req *sysdb_delete_user_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *name, uid_t uid); -int sysdb_delete_user_recv(struct tevent_req *req); +int sysdb_delete_user(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, uid_t uid); struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 0eb12a1..86aa61a 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -1805,110 +1805,62 @@ fail: /* =Delete-User-by-Name-OR-uid============================================ */ -struct sysdb_delete_user_state { - struct tevent_context *ev; - struct sss_domain_info *domain; - - const char *name; - uid_t uid; - - struct sysdb_handle *handle; -}; - -void sysdb_delete_user_check_handle(struct tevent_req *subreq); - -struct tevent_req *sysdb_delete_user_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *name, uid_t uid) -{ - struct tevent_req *req, *subreq; - struct sysdb_delete_user_state *state; - - req = tevent_req_create(mem_ctx, &state, struct sysdb_delete_user_state); - if (!req) return NULL; - - state->ev = ev; - state->handle = handle; - state->domain = domain; - state->name = name; - state->uid = uid; - - subreq = sysdb_check_handle_send(state, ev, sysdb, handle); - if (!subreq) { - DEBUG(1, ("sysdb_check_handle_send failed.\n")); - tevent_req_error(req, ENOMEM); - tevent_req_post(req, ev); - return req; - } - tevent_req_set_callback(subreq, sysdb_delete_user_check_handle, req); - - return req; -} - -void sysdb_delete_user_check_handle(struct tevent_req *subreq) +int sysdb_delete_user(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, uid_t uid) { - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_delete_user_state *state = tevent_req_data(req, - struct sysdb_delete_user_state); + TALLOC_CTX *tmpctx; struct ldb_message *msg; int ret; - ret = sysdb_check_handle_recv(subreq, state, &state->handle); - talloc_zfree(subreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; + tmpctx = talloc_new(mem_ctx); + if (!tmpctx) { + return ENOMEM; } - if (state->name) { - ret = sysdb_search_user_by_name(state, state->handle->ctx, - state->domain, state->name, - NULL, &msg); + if (name) { + ret = sysdb_search_user_by_name(tmpctx, sysdb, + domain, name, NULL, &msg); } else { - ret = sysdb_search_user_by_uid(state, state->handle->ctx, - state->domain, state->uid, - NULL, &msg); + ret = sysdb_search_user_by_uid(tmpctx, sysdb, + domain, uid, NULL, &msg); } if (ret) { - tevent_req_error(req, ret); - return; + goto fail; } - if (state->name && state->uid) { + if (name && uid) { /* verify name/gid match */ - const char *name; - uint64_t uid; + const char *c_name; + uint64_t c_uid; - name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); - uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); - if (name == NULL || uid == 0) { + c_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + c_uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); + if (c_name == NULL || c_uid == 0) { DEBUG(2, ("Attribute is missing but this should never happen!\n")); - tevent_req_error(req, EFAULT); - return; + ret = EFAULT; + goto fail; } - if (strcmp(state->name, name) || state->uid != uid) { + if (strcmp(name, c_name) || uid != c_uid) { /* this is not the entry we are looking for */ - tevent_req_error(req, EINVAL); - return; + ret = EINVAL; + goto fail; } } - ret = sysdb_delete_entry(state->handle->ctx, msg->dn, false); + ret = sysdb_delete_entry(sysdb, msg->dn, false); if (ret) { - tevent_req_error(req, ret); - return; + goto fail; } - tevent_req_done(req); -} + talloc_zfree(tmpctx); + return EOK; -int sysdb_delete_user_recv(struct tevent_req *req) -{ - return sysdb_op_default_recv(req); +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + talloc_zfree(tmpctx); + return ret; } diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 4bbc07a..8ac0989 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -48,7 +48,6 @@ struct users_get_state { static void users_get_connect_done(struct tevent_req *subreq); static void users_get_done(struct tevent_req *subreq); -static void users_get_delete(struct tevent_req *subreq); struct tevent_req *users_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, @@ -191,15 +190,13 @@ static void users_get_done(struct tevent_req *subreq) switch (state->filter_type) { case BE_FILTER_NAME: - subreq = sysdb_delete_user_send(state, state->ev, - state->sysdb, NULL, - state->domain, state->name, 0); - if (!subreq) { - tevent_req_error(req, ENOMEM); + ret = sysdb_delete_user(state, state->sysdb, + state->domain, state->name, 0); + if (ret) { + tevent_req_error(req, ret); return; } - tevent_req_set_callback(subreq, users_get_delete, req); - return; + break; case BE_FILTER_IDNUM: errno = 0; @@ -209,15 +206,13 @@ static void users_get_done(struct tevent_req *subreq) return; } - subreq = sysdb_delete_user_send(state, state->ev, - state->sysdb, NULL, - state->domain, NULL, uid); - if (!subreq) { - tevent_req_error(req, ENOMEM); + ret = sysdb_delete_user(state, state->sysdb, + state->domain, NULL, uid); + if (ret) { + tevent_req_error(req, ret); return; } - tevent_req_set_callback(subreq, users_get_delete, req); - return; + break; default: tevent_req_error(req, EINVAL); @@ -228,24 +223,6 @@ static void users_get_done(struct tevent_req *subreq) tevent_req_done(req); } -static void users_get_delete(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct users_get_state *state = tevent_req_data(req, - struct users_get_state); - int ret; - - ret = sysdb_delete_user_recv(subreq); - talloc_zfree(subreq); - if (ret) { - DEBUG(2, ("User (%s) delete returned %d (%s)\n", - state->name, ret, strerror(ret))); - } - - tevent_req_done(req); -} - int users_get_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c index fa6d907..6b37950 100644 --- a/src/providers/ldap/ldap_id_cleanup.c +++ b/src/providers/ldap/ldap_id_cleanup.c @@ -147,10 +147,7 @@ struct global_cleanup_state { struct sdap_id_ctx *ctx; }; -static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx); -static void ldap_id_cleanup_users_done(struct tevent_req *subreq); +static int cleanup_users(TALLOC_CTX *memctx, struct sdap_id_ctx *ctx); static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, @@ -163,6 +160,7 @@ struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, { struct global_cleanup_state *state; struct tevent_req *req, *subreq; + int ret; req = tevent_req_create(memctx, &state, struct global_cleanup_state); if (!req) return NULL; @@ -170,52 +168,30 @@ struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, state->ev = ev; state->ctx = ctx; - subreq = cleanup_users_send(state, ev, state->ctx); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - tevent_req_set_callback(subreq, ldap_id_cleanup_users_done, req); - ctx->last_purge = tevent_timeval_current(); - return req; -} - -static void ldap_id_cleanup_users_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct global_cleanup_state *state = tevent_req_data(req, - struct global_cleanup_state); - enum tevent_req_state tstate; - uint64_t err = 0; - - if (tevent_req_is_error(subreq, &tstate, &err)) { - if (tstate != TEVENT_REQ_USER_ERROR) { - err = EIO; - } - if (err != ENOENT) { - goto fail; - } + ret = cleanup_users(state, state->ctx); + if (ret && ret != ENOENT) { + goto fail; } - talloc_zfree(subreq); subreq = cleanup_groups_send(state, state->ev, state->ctx->be->sysdb, state->ctx->be->domain); if (!subreq) { - err = ENOMEM; + ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req); - return; + return req; fail: DEBUG(1, ("Failed to cleanup users (%d [%s]), retrying later!\n", - (int)err, strerror(err))); + (int)ret, strerror(ret))); tevent_req_done(req); + tevent_req_post(req, ev); + return req; } static void ldap_id_cleanup_groups_done(struct tevent_req *subreq) @@ -247,59 +223,37 @@ fail: /* ==User-Cleanup-Process================================================= */ -struct cleanup_users_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sss_domain_info *domain; - struct sdap_id_ctx *ctx; - - struct sysdb_handle *handle; - - hash_table_t *uid_table; - - struct ldb_message **msgs; - size_t count; - int cur; -}; - static int cleanup_users_logged_in(hash_table_t *table, const struct ldb_message *msg); -static int cleanup_users_delete(struct tevent_req *req); -static int cleanup_users_next(struct tevent_req *req); -static void cleanup_users_delete_done(struct tevent_req *subreq); -static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sdap_id_ctx *ctx) +static int cleanup_users(TALLOC_CTX *memctx, struct sdap_id_ctx *ctx) { - struct tevent_req *req; - struct cleanup_users_state *state; - static const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL }; + TALLOC_CTX *tmpctx; + struct sysdb_ctx *sysdb = ctx->be->sysdb; + struct sss_domain_info *domain = ctx->be->domain; + const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL }; time_t now = time(NULL); char *subfilter = NULL; int account_cache_expiration; + hash_table_t *uid_table; + struct ldb_message **msgs; + size_t count; + const char *name; int ret; + int i; - req = tevent_req_create(memctx, &state, struct cleanup_users_state); - if (!req) { - return NULL; + tmpctx = talloc_new(memctx); + if (!tmpctx) { + return ENOMEM; } - state->ev = ev; - state->sysdb = ctx->be->sysdb; - state->domain = ctx->be->domain; - state->ctx = ctx; - state->msgs = NULL; - state->count = 0; - state->cur = 0; - - account_cache_expiration = dp_opt_get_int(state->ctx->opts->basic, + account_cache_expiration = dp_opt_get_int(ctx->opts->basic, SDAP_ACCOUNT_CACHE_EXPIRATION); DEBUG(9, ("Cache expiration is set to %d days\n", account_cache_expiration)); if (account_cache_expiration > 0) { - subfilter = talloc_asprintf(state, + subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld)(|(!(%s=*))(%s<=%ld)))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, @@ -308,7 +262,7 @@ static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx, SYSDB_LAST_LOGIN, (long) (now - (account_cache_expiration * 86400))); } else { - subfilter = talloc_asprintf(state, + subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld)(!(%s=*)))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, @@ -317,89 +271,65 @@ static struct tevent_req *cleanup_users_send(TALLOC_CTX *memctx, } if (!subfilter) { DEBUG(2, ("Failed to build filter\n")); - tevent_req_error(req, ENOMEM); + ret = ENOMEM; goto done; } - ret = sysdb_search_users(state, state->sysdb, - state->domain, subfilter, attrs, - &state->count, &state->msgs); + ret = sysdb_search_users(tmpctx, sysdb, + domain, subfilter, attrs, &count, &msgs); if (ret) { if (ret == ENOENT) { - tevent_req_done(req);; + ret = EOK; } - tevent_req_error(req, ret); goto done; } - DEBUG(4, ("Found %d expired user entries!\n", state->count)); + DEBUG(4, ("Found %d expired user entries!\n", count)); - if (state->count == 0) { - tevent_req_done(req); + if (count == 0) { + ret = EOK; goto done; } - ret = get_uid_table(state, &state->uid_table); + ret = get_uid_table(tmpctx, &uid_table); /* get_uid_table returns ENOSYS on non-Linux platforms. We proceed with * the cleanup in that case */ if (ret != EOK && ret != ENOSYS) { - tevent_req_error(req, ret); - goto done; - } - - ret = cleanup_users_delete(req); - if (ret != 0) { goto done; } - return req; - -done: - tevent_req_post(req, ev); - return req; -} - -static int cleanup_users_delete(struct tevent_req *req) -{ - struct tevent_req *subreq; - struct cleanup_users_state *state = tevent_req_data(req, - struct cleanup_users_state); - const char *name; - int ret; + for (i = 0; i < count; i++) { + name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); + if (!name) { + DEBUG(2, ("Entry %s has no Name Attribute ?!?\n", + ldb_dn_get_linearized(msgs[i]->dn))); + ret = EFAULT; + goto done; + } - name = ldb_msg_find_attr_as_string(state->msgs[state->cur], - SYSDB_NAME, NULL); - if (!name) { - DEBUG(2, ("Entry %s has no Name Attribute ?!?\n", - ldb_dn_get_linearized(state->msgs[state->cur]->dn))); - tevent_req_error(req, EFAULT); - return 1; - } + if (uid_table) { + ret = cleanup_users_logged_in(uid_table, msgs[i]); + if (ret == EOK) { + /* If the user is logged in, proceed to the next one */ + DEBUG(5, ("User %s is still logged in, keeping data\n", name)); + continue; + } else if (ret != ENOENT) { + goto done; + } + } - if (state->uid_table) { - ret = cleanup_users_logged_in(state->uid_table, state->msgs[state->cur]); - if (ret == EOK) { - /* If the user is logged in, proceed to the next one */ - DEBUG(5, ("User %s is still logged in, keeping his data\n", name)); - return cleanup_users_next(req); - } else if (ret != ENOENT) { - tevent_req_error(req, ret); - return 1; + /* If not logged in or cannot check the table, delete him */ + DEBUG(9, ("About to delete user %s\n", name)); + ret = sysdb_delete_user(tmpctx, sysdb, domain, name, 0); + if (ret) { + goto done; } } - /* If not logged in or cannot check the table, delete him */ - DEBUG(9, ("About to delete user %s\n", name)); - subreq = sysdb_delete_user_send(state, state->ev, - state->sysdb, NULL, - state->domain, name, 0); - if (!subreq) { - tevent_req_error(req, ENOMEM); - return 1; - } - tevent_req_set_callback(subreq, cleanup_users_delete_done, req); - return 0; +done: + talloc_zfree(tmpctx); + return ret; } static int cleanup_users_logged_in(hash_table_t *table, @@ -431,38 +361,6 @@ static int cleanup_users_logged_in(hash_table_t *table, return EIO; } -static int cleanup_users_next(struct tevent_req *req) -{ - struct cleanup_users_state *state = tevent_req_data(req, - struct cleanup_users_state); - - state->cur++; - if (state->cur < state->count) { - return cleanup_users_delete(req); - } - - tevent_req_done(req); - return 1; -} - -static void cleanup_users_delete_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_delete_user_recv(subreq); - talloc_zfree(subreq); - if (ret) { - DEBUG(2, ("User delete returned %d (%s)\n", - ret, strerror(ret))); - tevent_req_error(req, ret); - return; - } - - cleanup_users_next(req); -} - /* ==Group-Cleanup-Process================================================ */ struct cleanup_groups_state { diff --git a/src/providers/proxy.c b/src/providers/proxy.c index 4426f13..7b56a95 100644 --- a/src/providers/proxy.c +++ b/src/providers/proxy.c @@ -492,7 +492,6 @@ static int delete_user(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, /* =Getpwuid-wrapper======================================================*/ static void get_pw_uid_process(struct tevent_req *subreq); -static void get_pw_uid_remove_done(struct tevent_req *subreq); static struct tevent_req *get_pw_uid_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -623,39 +622,12 @@ static void get_pw_uid_process(struct tevent_req *subreq) DEBUG(7, ("User %d does not exist (or is invalid) on remote server," " deleting!\n", state->uid)); - subreq = sysdb_delete_user_send(state, state->ev, - NULL, state->handle, - state->domain, - NULL, state->uid); - if (!subreq) { - tevent_req_error(req, ENOMEM); + ret = sysdb_delete_user(state, sysdb_handle_get_ctx(state->handle), + state->domain, NULL, state->uid); + if (ret) { + tevent_req_error(req, ret); 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) -{ - 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; - - ret = sysdb_delete_user_recv(subreq); - talloc_zfree(subreq); - if (ret && ret != ENOENT) { - tevent_req_error(req, ret); - return; } subreq = sysdb_transaction_commit_send(state, state->ev, state->handle); diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 320e6f2..b01404f 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -290,12 +290,9 @@ static void test_remove_user(struct tevent_req *req) return test_return(data, ret); } -static void test_remove_user_by_uid_done(struct tevent_req *subreq); - static void test_remove_user_by_uid(struct tevent_req *req) { struct test_data *data = tevent_req_callback_data(req, struct test_data); - struct tevent_req *subreq; int ret; ret = sysdb_transaction_recv(req, data, &data->handle); @@ -303,24 +300,8 @@ static void test_remove_user_by_uid(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_user_send(data, data->ev, - NULL, data->handle, - data->ctx->domain, - NULL, data->uid); - if (!subreq) return test_return(data, ENOMEM); - - tevent_req_set_callback(subreq, test_remove_user_by_uid_done, data); -} - -static void test_remove_user_by_uid_done(struct tevent_req *subreq) -{ - struct test_data *data = tevent_req_callback_data(subreq, - struct test_data); - int ret; - - ret = sysdb_delete_user_recv(subreq); - if (ret == ENOENT) ret = EOK; - talloc_zfree(subreq); + ret = sysdb_delete_user(data, data->handle->ctx, + data->ctx->domain, NULL, data->uid); return test_return(data, ret); } @@ -359,12 +340,9 @@ static void test_remove_nonexistent_group_done(struct tevent_req *subreq) return test_return(data, ret); } -static void test_remove_nonexistent_user_done(struct tevent_req *subreq); - static void test_remove_nonexistent_user(struct tevent_req *req) { struct test_data *data = tevent_req_callback_data(req, struct test_data); - struct tevent_req *subreq; int ret; ret = sysdb_transaction_recv(req, data, &data->handle); @@ -372,23 +350,8 @@ static void test_remove_nonexistent_user(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_user_send(data, data->ev, - NULL, data->handle, - data->ctx->domain, - NULL, data->uid); - if (!subreq) return test_return(data, ENOMEM); - - tevent_req_set_callback(subreq, test_remove_nonexistent_user_done, data); -} - -static void test_remove_nonexistent_user_done(struct tevent_req *subreq) -{ - struct test_data *data = tevent_req_callback_data(subreq, - struct test_data); - int ret; - - ret = sysdb_delete_user_recv(subreq); - talloc_zfree(subreq); + ret = sysdb_delete_user(data, data->handle->ctx, + data->ctx->domain, NULL, data->uid); return test_return(data, ret); }