From 0f6f40eee34677b0169fe9fdbbf65c3a838165bb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 7 Nov 2009 21:21:36 -0500 Subject: Refactor delete functions and add a few Refactor user/group delete functions so that they can be used without a transaction (they autostart an operation). Add user and group search function where a subfilter can be specified. --- server/db/sysdb.h | 55 ++-- server/db/sysdb_ops.c | 749 ++++++++++++++++++++++++++++++++++----------- server/providers/proxy.c | 37 +-- server/tests/sysdb-tests.c | 41 +-- 4 files changed, 648 insertions(+), 234 deletions(-) (limited to 'server') diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 68486de42..4c92c3777 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -366,15 +366,6 @@ int sysdb_search_user_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct ldb_message **msg); -/* Delete User by uid */ -struct tevent_req *sysdb_delete_user_by_uid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - uid_t uid, - bool ignore_not_found); -int sysdb_delete_user_by_uid_recv(struct tevent_req *req); - /* Search Group (gy gid or name) */ struct tevent_req *sysdb_search_group_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -394,15 +385,6 @@ int sysdb_search_group_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct ldb_message **msg); -/* Delete group by gid */ -struct tevent_req *sysdb_delete_group_by_gid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - gid_t gid, - bool ignore_not_found); -int sysdb_delete_group_by_gid_recv(struct tevent_req *req); - /* Replace entry attrs */ struct tevent_req *sysdb_set_entry_attr_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -593,4 +575,41 @@ struct tevent_req *sysdb_asq_search_send(TALLOC_CTX *mem_ctx, const char **attrs); int sysdb_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *msgs_count, struct ldb_message ***msgs); + +struct tevent_req *sysdb_search_users_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs); +int sysdb_search_users_recv(struct tevent_req *req, 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); + +struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs); +int sysdb_search_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + size_t *msgs_count, struct ldb_message ***msgs); + +struct tevent_req *sysdb_delete_group_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, gid_t gid); +int sysdb_delete_group_recv(struct tevent_req *req); + #endif /* __SYS_DB_H__ */ diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index 83082a0ff..7e232a4d7 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -793,92 +793,6 @@ int sysdb_search_user_recv(struct tevent_req *req, } -/* =Delete-User-by-UID==================================================== */ - -static void sysdb_delete_user_by_uid_found(struct tevent_req *subreq); -static void sysdb_delete_user_by_uid_done(struct tevent_req *subreq); - -struct tevent_req *sysdb_delete_user_by_uid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - uid_t uid, - bool ignore_not_found) -{ - struct tevent_req *req, *subreq; - struct sysdb_op_state *state; - - 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 = ignore_not_found; - state->ldbreply = NULL; - - subreq = sysdb_search_user_by_uid_send(state, ev, NULL, handle, - domain, uid, NULL); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - tevent_req_set_callback(subreq, sysdb_delete_user_by_uid_found, req); - - return req; -} - -static void sysdb_delete_user_by_uid_found(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_op_state *state = tevent_req_data(req, - struct sysdb_op_state); - struct ldb_message *msg; - int ret; - - ret = sysdb_search_user_recv(subreq, state, &msg); - talloc_zfree(subreq); - if (ret) { - if (state->ignore_not_found && ret == ENOENT) { - return tevent_req_done(req); - } - tevent_req_error(req, ret); - return; - } - - subreq = sysdb_delete_entry_send(state, state->ev, - state->handle, msg->dn, - state->ignore_not_found); - if (!subreq) { - DEBUG(6, ("Error: Out of memory\n")); - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(subreq, sysdb_delete_user_by_uid_done, req); -} - -static void sysdb_delete_user_by_uid_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_delete_entry_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - -int sysdb_delete_user_by_uid_recv(struct tevent_req *req) -{ - return sysdb_op_default_recv(req); -} - - /* =Search-Group-by-[GID/NAME]============================================ */ struct sysdb_search_group_state { @@ -1089,92 +1003,6 @@ int sysdb_search_group_recv(struct tevent_req *req, } -/* =Delete-Group-by-GID=================================================== */ - -static void sysdb_delete_group_by_gid_found(struct tevent_req *subreq); -static void sysdb_delete_group_by_gid_done(struct tevent_req *subreq); - -struct tevent_req *sysdb_delete_group_by_gid_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - gid_t gid, - bool ignore_not_found) -{ - struct tevent_req *req, *subreq; - struct sysdb_op_state *state; - - 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 = ignore_not_found; - state->ldbreply = NULL; - - subreq = sysdb_search_group_by_gid_send(state, ev, NULL, handle, - domain, gid, NULL); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - tevent_req_set_callback(subreq, sysdb_delete_group_by_gid_found, req); - - return req; -} - -static void sysdb_delete_group_by_gid_found(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_op_state *state = tevent_req_data(req, - struct sysdb_op_state); - struct ldb_message *msg; - int ret; - - ret = sysdb_search_group_recv(subreq, state, &msg); - talloc_zfree(subreq); - if (ret) { - if (state->ignore_not_found && ret == ENOENT) { - return tevent_req_done(req); - } - tevent_req_error(req, ret); - return; - } - - subreq = sysdb_delete_entry_send(state, state->ev, - state->handle, msg->dn, - state->ignore_not_found); - if (!subreq) { - DEBUG(6, ("Error: Out of memory\n")); - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(subreq, sysdb_delete_group_by_gid_done, req); -} - -static void sysdb_delete_group_by_gid_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_delete_entry_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); -} - -int sysdb_delete_group_by_gid_recv(struct tevent_req *req) -{ - return sysdb_op_default_recv(req); -} - - /* =Replace-Attributes-On-Entry=========================================== */ struct tevent_req *sysdb_set_entry_attr_send(TALLOC_CTX *mem_ctx, @@ -4169,8 +3997,9 @@ static void sysdb_asq_search_done(struct tevent_req *subreq) int ret; ret = sldb_request_recv(subreq, state, &ldbreply); + /* DO NOT free the subreq here, the subrequest search is not + * finished until we get an ldbreply of type LDB_REPLY_DONE */ if (ret != EOK) { - talloc_free(subreq); DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); tevent_req_error(req, ret); return; @@ -4196,6 +4025,8 @@ static void sysdb_asq_search_done(struct tevent_req *subreq) return; case LDB_REPLY_DONE: + /* now it is safe to free the subrequest, the search is complete */ + talloc_zfree(subreq); break; default: @@ -4204,7 +4035,6 @@ static void sysdb_asq_search_done(struct tevent_req *subreq) return; } - talloc_zfree(subreq); tevent_req_done(req); } @@ -4213,15 +4043,580 @@ int sysdb_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, { struct sysdb_asq_search_state *state = tevent_req_data(req, struct sysdb_asq_search_state); - int i; TEVENT_REQ_RETURN_ON_ERROR(req); *msgs_count = state->msgs_count; - for (i = 0; i < state->msgs_count; i++) { - talloc_steal(mem_ctx, state->msgs[i]); + *msgs = talloc_move(mem_ctx, &state->msgs); + + return EOK; +} + +/* =Search-Users-with-Custom-Filter====================================== */ + +struct sysdb_search_users_state { + struct tevent_context *ev; + struct sysdb_handle *handle; + struct sss_domain_info *domain; + const char *sub_filter; + const char **attrs; + + struct ldb_message **msgs; + size_t msgs_count; +}; + +void sysdb_search_users_check_handle(struct tevent_req *subreq); +static void sysdb_search_users_done(struct tevent_req *subreq); + +struct tevent_req *sysdb_search_users_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs) +{ + struct tevent_req *req, *subreq; + struct sysdb_search_users_state *state; + int ret; + + req = tevent_req_create(mem_ctx, &state, struct sysdb_search_users_state); + if (req == NULL) { + DEBUG(1, ("tevent_req_create failed.\n")); + return NULL; + } + + state->ev = ev; + state->handle = handle; + state->domain = domain; + state->sub_filter = sub_filter; + state->attrs = attrs; + + state->msgs_count = 0; + state->msgs = NULL; + + subreq = sysdb_check_handle_send(state, ev, sysdb, handle); + if (!subreq) { + DEBUG(1, ("sysdb_check_handle_send failed.\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, sysdb_search_users_check_handle, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +void sysdb_search_users_check_handle(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_search_users_state *state = tevent_req_data(req, + struct sysdb_search_users_state); + struct ldb_dn *basedn; + char *filter; + int ret; + + ret = sysdb_check_handle_recv(subreq, state, &state->handle); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + basedn = ldb_dn_new_fmt(state, state->handle->ctx->ldb, + SYSDB_TMPL_USER_BASE, state->domain->name); + if (!basedn) { + DEBUG(2, ("Failed to build base dn\n")); + tevent_req_error(req, ENOMEM); + return; + } + + filter = talloc_asprintf(state, "(&(%s)%s)", + SYSDB_UC, state->sub_filter); + if (!filter) { + DEBUG(2, ("Failed to build filter\n")); + tevent_req_error(req, ENOMEM); + return; + } + + DEBUG(6, ("Search users with filter: %s\n", filter)); + + subreq = sysdb_search_entry_send(state, state->ev, state->handle, + basedn, LDB_SCOPE_SUBTREE, + filter, state->attrs); + if (!subreq) { + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_search_users_done, req); +} + +static void sysdb_search_users_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_search_users_state *state = tevent_req_data(req, + struct sysdb_search_users_state); + int ret; + + ret = sysdb_search_entry_recv(subreq, state, + &state->msgs_count, &state->msgs); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; } + + tevent_req_done(req); +} + +int sysdb_search_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + size_t *msgs_count, struct ldb_message ***msgs) +{ + struct sysdb_search_users_state *state = tevent_req_data(req, + struct sysdb_search_users_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *msgs_count = state->msgs_count; *msgs = talloc_move(mem_ctx, &state->msgs); return EOK; } + +/* =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); +static void sysdb_delete_user_found(struct tevent_req *subreq); +static void sysdb_delete_user_done(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) +{ + 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); + static const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL }; + int ret; + + ret = sysdb_check_handle_recv(subreq, state, &state->handle); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + if (state->name) { + subreq = sysdb_search_user_by_name_send(state, state->ev, NULL, + state->handle, state->domain, + state->name, attrs); + } else { + subreq = sysdb_search_user_by_uid_send(state, state->ev, NULL, + state->handle, state->domain, + state->uid, NULL); + } + + if (!subreq) { + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_delete_user_found, req); +} + +static void sysdb_delete_user_found(struct tevent_req *subreq) +{ + 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); + struct ldb_message *msg; + int ret; + + ret = sysdb_search_user_recv(subreq, state, &msg); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; + } + + if (state->name && state->uid) { + /* verify name/gid match */ + const char *name; + uint64_t 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) { + DEBUG(2, ("Attribute is missing but this should never happen!\n")); + tevent_req_error(req, EFAULT); + return; + } + if (strcmp(state->name, name) || state->uid != uid) { + /* this is not the entry we are looking for */ + tevent_req_error(req, EINVAL); + return; + } + } + + subreq = sysdb_delete_entry_send(state, state->ev, + state->handle, msg->dn, false); + if (!subreq) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_delete_user_done, req); +} + +static void sysdb_delete_user_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + int ret; + + ret = sysdb_delete_entry_recv(subreq); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +int sysdb_delete_user_recv(struct tevent_req *req) +{ + return sysdb_op_default_recv(req); +} + + +/* =Search-Groups-with-Custom-Filter===================================== */ + +struct sysdb_search_groups_state { + struct tevent_context *ev; + struct sysdb_handle *handle; + struct sss_domain_info *domain; + const char *sub_filter; + const char **attrs; + + struct ldb_message **msgs; + size_t msgs_count; +}; + +void sysdb_search_groups_check_handle(struct tevent_req *subreq); +static void sysdb_search_groups_done(struct tevent_req *subreq); + +struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs) +{ + struct tevent_req *req, *subreq; + struct sysdb_search_groups_state *state; + int ret; + + req = tevent_req_create(mem_ctx, &state, struct sysdb_search_groups_state); + if (req == NULL) { + DEBUG(1, ("tevent_req_create failed.\n")); + return NULL; + } + + state->ev = ev; + state->handle = handle; + state->domain = domain; + state->sub_filter = sub_filter; + state->attrs = attrs; + + state->msgs_count = 0; + state->msgs = NULL; + + subreq = sysdb_check_handle_send(state, ev, sysdb, handle); + if (!subreq) { + DEBUG(1, ("sysdb_check_handle_send failed.\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, sysdb_search_groups_check_handle, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +void sysdb_search_groups_check_handle(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_search_groups_state *state = tevent_req_data(req, + struct sysdb_search_groups_state); + struct ldb_dn *basedn; + char *filter; + int ret; + + ret = sysdb_check_handle_recv(subreq, state, &state->handle); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + basedn = ldb_dn_new_fmt(state, state->handle->ctx->ldb, + SYSDB_TMPL_GROUP_BASE, state->domain->name); + if (!basedn) { + DEBUG(2, ("Failed to build base dn\n")); + tevent_req_error(req, ENOMEM); + return; + } + + filter = talloc_asprintf(state, "(&(%s)%s)", + SYSDB_GC, state->sub_filter); + if (!filter) { + DEBUG(2, ("Failed to build filter\n")); + tevent_req_error(req, ENOMEM); + return; + } + + DEBUG(6, ("Search groups with filter: %s\n", filter)); + + subreq = sysdb_search_entry_send(state, state->ev, state->handle, + basedn, LDB_SCOPE_SUBTREE, + filter, state->attrs); + if (!subreq) { + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_search_groups_done, req); +} + +static void sysdb_search_groups_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_search_groups_state *state = tevent_req_data(req, + struct sysdb_search_groups_state); + int ret; + + ret = sysdb_search_entry_recv(subreq, state, + &state->msgs_count, &state->msgs); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +int sysdb_search_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + size_t *msgs_count, struct ldb_message ***msgs) +{ + struct sysdb_search_groups_state *state = tevent_req_data(req, + struct sysdb_search_groups_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *msgs_count = state->msgs_count; + *msgs = talloc_move(mem_ctx, &state->msgs); + + return EOK; +} + +/* =Delete-Group-by-Name-OR-gid=========================================== */ + +struct sysdb_delete_group_state { + struct tevent_context *ev; + struct sss_domain_info *domain; + + const char *name; + gid_t gid; + + struct sysdb_handle *handle; +}; + +void sysdb_delete_group_check_handle(struct tevent_req *subreq); +static void sysdb_delete_group_found(struct tevent_req *subreq); +static void sysdb_delete_group_done(struct tevent_req *subreq); + +struct tevent_req *sysdb_delete_group_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, gid_t gid) +{ + struct tevent_req *req, *subreq; + struct sysdb_delete_group_state *state; + + req = tevent_req_create(mem_ctx, &state, struct sysdb_delete_group_state); + if (!req) return NULL; + + state->ev = ev; + state->handle = handle; + state->domain = domain; + state->name = name; + state->gid = gid; + + 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_group_check_handle, req); + + return req; +} + +void sysdb_delete_group_check_handle(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_delete_group_state *state = tevent_req_data(req, + struct sysdb_delete_group_state); + static const char *attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL }; + int ret; + + ret = sysdb_check_handle_recv(subreq, state, &state->handle); + talloc_zfree(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + if (state->name) { + subreq = sysdb_search_group_by_name_send(state, state->ev, NULL, + state->handle, state->domain, + state->name, attrs); + } else { + subreq = sysdb_search_group_by_gid_send(state, state->ev, NULL, + state->handle, state->domain, + state->gid, NULL); + } + + if (!subreq) { + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_delete_group_found, req); +} + +static void sysdb_delete_group_found(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_delete_group_state *state = tevent_req_data(req, + struct sysdb_delete_group_state); + struct ldb_message *msg; + int ret; + + ret = sysdb_search_group_recv(subreq, state, &msg); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; + } + + if (state->name && state->gid) { + /* verify name/gid match */ + const char *name; + uint64_t gid; + + name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); + gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); + if (name == NULL || gid == 0) { + DEBUG(2, ("Attribute is missing but this should never happen!\n")); + tevent_req_error(req, EFAULT); + return; + } + if (strcmp(state->name, name) || state->gid != gid) { + /* this is not the entry we are looking for */ + tevent_req_error(req, EINVAL); + return; + } + } + + subreq = sysdb_delete_entry_send(state, state->ev, + state->handle, msg->dn, false); + if (!subreq) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_delete_group_done, req); +} + +static void sysdb_delete_group_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + int ret; + + ret = sysdb_delete_entry_recv(subreq); + talloc_zfree(subreq); + if (ret) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +int sysdb_delete_group_recv(struct tevent_req *req) +{ + return sysdb_op_default_recv(req); +} + + diff --git a/server/providers/proxy.c b/server/providers/proxy.c index 628f9d496..aea2df307 100644 --- a/server/providers/proxy.c +++ b/server/providers/proxy.c @@ -628,11 +628,10 @@ 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_by_uid_send(state, state->ev, - state->handle, - state->domain, - state->uid, - true); + subreq = sysdb_delete_user_send(state, state->ev, + NULL, state->handle, + state->domain, + NULL, state->uid); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -649,9 +648,9 @@ static void get_pw_uid_remove_done(struct tevent_req *subreq) struct proxy_state); int ret; - ret = sysdb_delete_user_by_uid_recv(subreq); + ret = sysdb_delete_user_recv(subreq); talloc_zfree(subreq); - if (ret) { + if (ret && ret != ENOENT) { tevent_req_error(req, ret); return; } @@ -1239,11 +1238,10 @@ again: DEBUG(7, ("Group %d does not exist (or is invalid) on remote server," " deleting!\n", state->gid)); - subreq = sysdb_delete_group_by_gid_send(state, state->ev, - state->handle, - state->domain, - state->gid, - true); + subreq = sysdb_delete_group_send(state, state->ev, + NULL, state->handle, + state->domain, + NULL, state->gid); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -1260,9 +1258,9 @@ static void get_gr_gid_remove_done(struct tevent_req *subreq) struct proxy_state); int ret; - ret = sysdb_delete_group_by_gid_recv(subreq); + ret = sysdb_delete_group_recv(subreq); talloc_zfree(subreq); - if (ret) { + if (ret && ret != ENOENT) { tevent_req_error(req, ret); return; } @@ -1911,11 +1909,10 @@ again: } if (delete_user) { - subreq = sysdb_delete_group_by_gid_send(state, state->ev, - state->handle, - state->domain, - state->gid, - true); + subreq = sysdb_delete_group_send(state, state->ev, + NULL, state->handle, + state->domain, + NULL, state->gid); if (!subreq) { ret = ENOMEM; goto fail; @@ -1955,7 +1952,7 @@ static void get_group_from_gid_send_del_done(struct tevent_req *subreq) ret = sysdb_delete_entry_recv(subreq); talloc_zfree(subreq); - if (ret) { + if (ret && ret != ENOENT) { tevent_req_error(req, ret); return; } diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index 32ed7bb27..fffcb72ad 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -340,10 +340,10 @@ static void test_remove_user_by_uid(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_user_by_uid_send(data, - data->ev, data->handle, - data->ctx->domain, data->uid, - true); + 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); @@ -355,7 +355,8 @@ static void test_remove_user_by_uid_done(struct tevent_req *subreq) struct test_data); int ret; - ret = sysdb_delete_user_by_uid_recv(subreq); + ret = sysdb_delete_user_recv(subreq); + if (ret == ENOENT) ret = EOK; talloc_zfree(subreq); return test_return(data, ret); @@ -374,10 +375,10 @@ static void test_remove_nonexistent_group(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_group_by_gid_send(data, - data->ev, data->handle, - data->ctx->domain, data->uid, - false); + subreq = sysdb_delete_group_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_group_done, data); @@ -389,7 +390,7 @@ static void test_remove_nonexistent_group_done(struct tevent_req *subreq) struct test_data); int ret; - ret = sysdb_delete_group_by_gid_recv(subreq); + ret = sysdb_delete_group_recv(subreq); talloc_zfree(subreq); return test_return(data, ret); @@ -408,10 +409,10 @@ static void test_remove_nonexistent_user(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_user_by_uid_send(data, - data->ev, data->handle, - data->ctx->domain, data->uid, - false); + 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); @@ -423,7 +424,7 @@ static void test_remove_nonexistent_user_done(struct tevent_req *subreq) struct test_data); int ret; - ret = sysdb_delete_user_by_uid_recv(subreq); + ret = sysdb_delete_user_recv(subreq); talloc_zfree(subreq); return test_return(data, ret); @@ -543,9 +544,10 @@ static void test_remove_group_by_gid(struct tevent_req *req) return test_return(data, ret); } - subreq = sysdb_delete_group_by_gid_send(data, data->ev, data->handle, - data->ctx->domain, data->gid, - true); + subreq = sysdb_delete_group_send(data, data->ev, + NULL, data->handle, + data->ctx->domain, + NULL, data->gid); if (!subreq) return test_return(data, ENOMEM); tevent_req_set_callback(subreq, test_remove_group_by_gid_done, data); @@ -557,7 +559,8 @@ static void test_remove_group_by_gid_done(struct tevent_req *subreq) struct test_data); int ret; - ret = sysdb_delete_group_by_gid_recv(subreq); + ret = sysdb_delete_group_recv(subreq); + if (ret == ENOENT) ret = EOK; talloc_zfree(subreq); return test_return(data, ret); -- cgit