First of the responders is converted -)
From e057a44aa2166109baa28df055b9116772dd940e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Mon, 8 Feb 2016 14:02:59 +0100 Subject: [PATCH 1/4] sudo: remove unused structure sudo_dp_request
--- src/responder/sudo/sudosrv_private.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 186ed2cb5114d00524b41b801b5f32bac50f7153..f602f6a83cd52a54ce180d3aaaa1febd1d991f32 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -79,11 +79,6 @@ struct sudo_dom_ctx { bool check_provider; }; -struct sudo_dp_request { - struct cli_ctx *cctx; - struct sss_domain_info *domain; -}; - struct sss_cmd_table *get_sudo_cmds(void); errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret); -- 2.1.0
From 939baba58d12fbedd146b71c2f7015b6441049bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Mon, 8 Feb 2016 14:30:16 +0100 Subject: [PATCH 2/4] sudo: use cache_req for initgroups This is just blind code change, the next patch will improve it so for example we don't do initgroups during query-parsing phase. Resolves: https://fedorahosted.org/sssd/ticket/1126 --- src/responder/sudo/sudosrv_cmd.c | 29 +-- src/responder/sudo/sudosrv_get_sudorules.c | 292 ++--------------------------- src/responder/sudo/sudosrv_private.h | 13 +- src/responder/sudo/sudosrv_query.c | 114 ++++------- 4 files changed, 47 insertions(+), 401 deletions(-) diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c index dd636e949200dd49c1422a5789e9328dc4b25fb0..c68a6980ba817071e3766a0ddf7c158499d47aec 100644 --- a/src/responder/sudo/sudosrv_cmd.c +++ b/src/responder/sudo/sudosrv_cmd.c @@ -221,7 +221,7 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) goto done; } - req = sudosrv_parse_query_send(cmd_ctx, cli_ctx->rctx, + req = sudosrv_parse_query_send(cmd_ctx, cmd_ctx->sudo_ctx, query_body, query_len); if (req == NULL) { ret = ENOMEM; @@ -239,8 +239,6 @@ done: static void sudosrv_cmd_parse_query_done(struct tevent_req *req) { struct sudo_cmd_ctx *cmd_ctx = NULL; - struct sudo_dom_ctx *dom_ctx = NULL; - struct sudo_ctx *sudo_ctx = NULL; errno_t ret; cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx); @@ -254,8 +252,6 @@ static void sudosrv_cmd_parse_query_done(struct tevent_req *req) goto done; } - cmd_ctx->check_next = cmd_ctx->domain == NULL; - switch (cmd_ctx->type) { case SSS_SUDO_DEFAULTS: DEBUG(SSSDBG_FUNC_DATA, "Requesting default options " @@ -269,28 +265,7 @@ static void sudosrv_cmd_parse_query_done(struct tevent_req *req) break; } - /* create domain ctx */ - - dom_ctx = talloc_zero(cmd_ctx, struct sudo_dom_ctx); - if (dom_ctx == NULL) { - ret = ENOMEM; - goto done; - } - dom_ctx->cmd_ctx = cmd_ctx; - dom_ctx->domain = cmd_ctx->domain != NULL ? cmd_ctx->domain - : cmd_ctx->cli_ctx->rctx->domains; - - sudo_ctx = talloc_get_type(cmd_ctx->cli_ctx->rctx->pvt_ctx, struct sudo_ctx); - ret = sss_ncache_check_user(sudo_ctx->ncache, sudo_ctx->neg_timeout, - dom_ctx->domain, cmd_ctx->username); - if (ret == EEXIST) { - DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out (ncache)\n", - cmd_ctx->username, dom_ctx->domain->name); - ret = ENOENT; - goto done; - } - - ret = sudosrv_get_sudorules(dom_ctx); + ret = sudosrv_get_sudorules(cmd_ctx); done: sudosrv_cmd_done(cmd_ctx, ret); diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index 75d8cac41d57ff65449cdf5ed3b08cf7d46d55c1..13015072e6daf1455b0b8e66a225f84c94280958 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -30,26 +30,12 @@ #include "responder/sudo/sudosrv_private.h" #include "providers/data_provider.h" -static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx); - -errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx) +errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx) { errno_t ret; - dctx->check_provider = true; - ret = sudosrv_get_user(dctx); - if (ret == EAGAIN) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Looking up the user info from Data Provider\n"); - return EAGAIN; - } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Error looking up user information [%d]: %s\n", ret, strerror(ret)); - return ret; - } - /* OK, got the user from cache. Try to get the rules. */ - ret = sudosrv_get_rules(dctx->cmd_ctx); + ret = sudosrv_get_rules(cmd_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up the sudo rules from Data Provider\n"); @@ -63,262 +49,6 @@ errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx) return EOK; } -static void sudosrv_dp_send_acct_req_done(struct tevent_req *req); -static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, - const char *err_msg, void *ptr); - -static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) -{ - TALLOC_CTX *tmp_ctx = NULL; - struct sss_domain_info *dom = dctx->domain; - struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx; - struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx; - struct ldb_result *user; - time_t cache_expire = 0; - struct tevent_req *dpreq; - struct dp_callback_ctx *cb_ctx; - const char *original_name = NULL; - const char *extra_flag = NULL; - const char *search_name = NULL; - char *name = NULL; - uid_t uid = 0; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); - return ENOMEM; - } - - while (dom) { - /* if it is a domainless search, skip domains that require fully - * qualified names instead */ - while (dom && cmd_ctx->check_next && dom->fqnames) { - dom = get_next_domain(dom, 0); - } - - if (!dom) break; - - /* make sure to update the dctx if we changed domain */ - dctx->domain = dom; - - talloc_free(name); - name = sss_get_cased_name(tmp_ctx, cmd_ctx->username, - dom->case_sensitive); - if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); - ret = ENOMEM; - goto done; - } - - name = sss_reverse_replace_space(tmp_ctx, name, - cmd_ctx->sudo_ctx->rctx->override_space); - if (name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "sss_reverse_replace_whitespaces failed\n"); - return ENOMEM; - } - - DEBUG(SSSDBG_FUNC_DATA, "Requesting info about [%s@%s]\n", - name, dom->name); - - ret = sysdb_getpwnam_with_views(dctx, dctx->domain, name, &user); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to make request to our cache!\n"); - ret = EIO; - goto done; - } - - if (user->count > 1) { - DEBUG(SSSDBG_CRIT_FAILURE, - "getpwnam call returned more than one result !?!\n"); - ret = EIO; - goto done; - } - - if (user->count == 0 && !dctx->check_provider) { - /* if a multidomain search, try with next */ - if (cmd_ctx->check_next) { - dctx->check_provider = true; - dom = get_next_domain(dom, 0); - if (dom) continue; - } - - DEBUG(SSSDBG_MINOR_FAILURE, "No results for getpwnam call\n"); - ret = ENOENT; - goto done; - } - - /* One result found, check cache expiry */ - if (user->count == 1) { - cache_expire = ldb_msg_find_attr_as_uint64(user->msgs[0], - SYSDB_CACHE_EXPIRE, 0); - } - - /* If cache miss and we haven't checked DP yet OR the entry is - * outdated, go to DP */ - if ((user->count == 0 || cache_expire < time(NULL)) - && dctx->check_provider) { - - search_name = cmd_ctx->username; - if (is_local_view(dom->view_name)) { - /* Search with original name in case of local view. */ - if (user->count != 0) { - search_name = ldb_msg_find_attr_as_string(user->msgs[0], - SYSDB_NAME, NULL); - } - } else if (DOM_HAS_VIEWS(dom) && (user->count == 0 - || ldb_msg_find_attr_as_string(user->msgs[0], - OVERRIDE_PREFIX SYSDB_NAME, - NULL) != NULL)) { - extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; - } - - dpreq = sss_dp_get_account_send(cli_ctx, cli_ctx->rctx, - dom, false, SSS_DP_INITGROUPS, - search_name, 0, extra_flag); - if (!dpreq) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Out of memory sending data provider request\n"); - ret = ENOMEM; - goto done; - } - - cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx); - if(!cb_ctx) { - talloc_zfree(dpreq); - ret = ENOMEM; - goto done; - } - - cb_ctx->callback = sudosrv_check_user_dp_callback; - cb_ctx->ptr = dctx; - cb_ctx->cctx = cli_ctx; - cb_ctx->mem_ctx = cli_ctx; - - tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx); - - /* tell caller we are in an async call */ - ret = EAGAIN; - goto done; - } - - /* check uid */ - uid = sss_view_ldb_msg_find_attr_as_uint64(dom, user->msgs[0], - SYSDB_UIDNUM, 0); - if (uid != cmd_ctx->uid) { - /* if a multidomain search, try with next */ - if (cmd_ctx->check_next) { - dctx->check_provider = true; - dom = get_next_domain(dom, 0); - if (dom) continue; - } - - DEBUG(SSSDBG_MINOR_FAILURE, "UID does not match\n"); - ret = ENOENT; - goto done; - } - - /* user is stored in cache, remember cased and original name */ - original_name = ldb_msg_find_attr_as_string(user->msgs[0], - SYSDB_NAME, NULL); - if (original_name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n"); - ret = EFAULT; - goto done; - } - - cmd_ctx->cased_username = talloc_move(cmd_ctx, &name); - cmd_ctx->orig_username = talloc_strdup(cmd_ctx, original_name); - if (cmd_ctx->orig_username == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); - ret = ENOMEM; - goto done; - } - - /* and set domain */ - cmd_ctx->domain = dom; - - DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s@%s]\n", - cmd_ctx->username, dctx->domain->name); - ret = EOK; - goto done; - } - - ret = ENOENT; -done: - talloc_free(tmp_ctx); - return ret; -} - -static void sudosrv_dp_send_acct_req_done(struct tevent_req *req) -{ - struct dp_callback_ctx *cb_ctx = - tevent_req_callback_data(req, struct dp_callback_ctx); - - errno_t ret; - dbus_uint16_t err_maj; - dbus_uint32_t err_min; - char *err_msg; - - ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req, - &err_maj, &err_min, - &err_msg); - talloc_zfree(req); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Fatal error, killing connection!\n"); - talloc_free(cb_ctx->cctx); - return; - } - - cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); -} - -static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, - const char *err_msg, void *ptr) -{ - errno_t ret; - struct sudo_dom_ctx *dctx = talloc_get_type(ptr, struct sudo_dom_ctx); - - if (err_maj) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to get information from Data Provider\n" - "Error: %u, %u, %s\n", - (unsigned int)err_maj, (unsigned int)err_min, err_msg); - } - - DEBUG(SSSDBG_TRACE_INTERNAL, - "Data Provider returned, check the cache again\n"); - dctx->check_provider = false; - ret = sudosrv_get_user(dctx); - if (ret == EAGAIN) { - goto done; - } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Could not look up the user [%d]: %s\n", - ret, strerror(ret)); - sudosrv_cmd_done(dctx->cmd_ctx, ret); - return; - } - - DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up sudo rules..\n"); - ret = sudosrv_get_rules(dctx->cmd_ctx); - if (ret == EAGAIN) { - goto done; - } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Error getting sudo rules [%d]: %s\n", - ret, strerror(ret)); - sudosrv_cmd_done(dctx->cmd_ctx, EIO); - return; - } - -done: - sudosrv_cmd_done(dctx->cmd_ctx, ret); -} - static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, struct sudo_cmd_ctx *cmd_ctx, struct sysdb_attrs ***_rules, @@ -367,12 +97,12 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) switch (cmd_ctx->type) { case SSS_SUDO_DEFAULTS: DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options " - "for [%s] from [%s]\n", cmd_ctx->orig_username, + "for [%s] from [%s]\n", cmd_ctx->username, cmd_ctx->domain->name); break; case SSS_SUDO_USER: DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules " - "for [%s] from [%s]\n", cmd_ctx->orig_username, + "for [%s] from [%s]\n", cmd_ctx->username, cmd_ctx->domain->name); break; } @@ -383,7 +113,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) * provider call */ ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->domain, - cmd_ctx->orig_username, NULL, &groupnames); + cmd_ctx->username, NULL, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve user info [%d]: %s\n", ret, strerror(ret)); @@ -396,7 +126,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) | SYSDB_SUDO_FILTER_USERINFO; ret = sudosrv_get_sudorules_query_cache(tmp_ctx, cmd_ctx->domain, attrs, flags, - cmd_ctx->orig_username, + cmd_ctx->username, cmd_ctx->uid, groupnames, cmd_ctx->sudo_ctx->inverse_order, &expired_rules, &expired_rules_num); @@ -414,7 +144,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) dpreq = sss_dp_get_sudoers_send(tmp_ctx, cmd_ctx->cli_ctx->rctx, cmd_ctx->domain, false, SSS_DP_SUDO_REFRESH_RULES, - cmd_ctx->orig_username, + cmd_ctx->username, expired_rules_num, expired_rules); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -535,7 +265,7 @@ sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, cmd_ctx->cli_ctx->rctx, cmd_ctx->domain, false, SSS_DP_SUDO_FULL_REFRESH, - cmd_ctx->orig_username, + cmd_ctx->username, 0, NULL); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -587,10 +317,10 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, switch (cmd_ctx->type) { case SSS_SUDO_USER: - debug_name = cmd_ctx->cased_username; + debug_name = cmd_ctx->username; ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->domain, - cmd_ctx->orig_username, + cmd_ctx->username, NULL, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -608,7 +338,7 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, ret = sudosrv_get_sudorules_query_cache(tmp_ctx, cmd_ctx->domain, attrs, flags, - cmd_ctx->orig_username, + cmd_ctx->username, cmd_ctx->uid, groupnames, cmd_ctx->sudo_ctx->inverse_order, &rules, &num_rules); diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index f602f6a83cd52a54ce180d3aaaa1febd1d991f32..dceb113b530c8adfdb361cafff95b49d7dc323b5 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -61,10 +61,7 @@ struct sudo_cmd_ctx { /* input data */ uid_t uid; char *username; - const char *orig_username; - const char *cased_username; struct sss_domain_info *domain; - bool check_next; uint32_t expired_rules_num; @@ -73,22 +70,16 @@ struct sudo_cmd_ctx { uint32_t num_rules; }; -struct sudo_dom_ctx { - struct sudo_cmd_ctx *cmd_ctx; - struct sss_domain_info *domain; - bool check_provider; -}; - struct sss_cmd_table *get_sudo_cmds(void); errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret); -errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx); +errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx); errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx); struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, - struct resp_ctx *rctx, + struct sudo_ctx *sudo_ctx, uint8_t *query_body, size_t query_len); diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c index 4cb07e32b3d7f2897dcd7f4941aa44bf8928d5c2..08b359c0464f1cc00866e46634e571562910018d 100644 --- a/src/responder/sudo/sudosrv_query.c +++ b/src/responder/sudo/sudosrv_query.c @@ -25,6 +25,7 @@ #include <tevent.h> #include "util/util.h" +#include "responder/common/responder_cache_req.h" #include "responder/sudo/sudosrv_private.h" static int sudosrv_response_append_string(TALLOC_CTX *mem_ctx, @@ -252,15 +253,15 @@ fail: } struct sudosrv_parse_query_state { - struct resp_ctx *rctx; uid_t uid; - char *rawname; + char *username; + struct sss_domain_info *domain; }; static void sudosrv_parse_query_done(struct tevent_req *subreq); struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, - struct resp_ctx *rctx, + struct sudo_ctx *sudo_ctx, uint8_t *query_body, size_t query_len) { @@ -270,7 +271,6 @@ struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, size_t offset = 0; size_t rawname_len = 0; char *rawname = NULL; - char *domainname = NULL; errno_t ret; /* create request */ @@ -281,14 +281,12 @@ struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, return NULL; } - state->rctx = rctx; - /* uid */ if (query_len < sizeof(uid_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "Query is too small\n"); ret = EINVAL; - goto done; + goto immediately; } safealign_memcpy(&state->uid, query_body, sizeof(uid_t), &offset); @@ -300,68 +298,59 @@ struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, if (rawname[rawname_len - 1] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Username is not zero terminated\n"); ret = EINVAL; - goto done; + goto immediately; } if (rawname_len < 2) { /* at least one character and zero */ DEBUG(SSSDBG_CRIT_FAILURE, "Query does not contain username\n"); ret = EINVAL; - goto done; + goto immediately; } if (!sss_utf8_check((uint8_t*)rawname, rawname_len - 1)) { DEBUG(SSSDBG_CRIT_FAILURE, "Supplied data is not valid UTF-8 string\n"); ret = EINVAL; - goto done; + goto immediately; } /* parse username */ - state->rawname = rawname; - ret = sss_parse_name_for_domains(state, rctx->domains, - rctx->default_domain, state->rawname, - &domainname, NULL); - if (ret == EAGAIN) { - DEBUG(SSSDBG_TRACE_FUNC, "Domain [%s] not found, " - "sending subdomain request\n", domainname); - - subreq = sss_dp_get_domains_send(state, rctx, true, domainname); - if (subreq == NULL) { - ret = ENOMEM; - } else { - tevent_req_set_callback(subreq, sudosrv_parse_query_done, req); - ret = EAGAIN; - } - goto done; - } else if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name received [%s]\n", rawname); - goto done; + subreq = cache_req_initgr_by_name_send(state, sudo_ctx->rctx->ev, + sudo_ctx->rctx, sudo_ctx->ncache, + sudo_ctx->neg_timeout, 0, + NULL, rawname); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; } - ret = EOK; + tevent_req_set_callback(subreq, sudosrv_parse_query_done, req); + + return req; -done: - if (ret != EAGAIN) { - if (ret == EOK) { - tevent_req_done(req); - } else { - tevent_req_error(req, ret); - } - tevent_req_post(req, rctx->ev); +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); } + tevent_req_post(req, sudo_ctx->rctx->ev); return req; } static void sudosrv_parse_query_done(struct tevent_req *subreq) { - struct tevent_req *req = NULL; + struct sudosrv_parse_query_state *state; + struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct sudosrv_parse_query_state); - ret = sss_dp_get_domains_recv(subreq); - talloc_free(subreq); + ret = cache_req_initgr_by_name_recv(state, subreq, NULL, + &state->domain, &state->username); + talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; @@ -377,53 +366,14 @@ errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx, struct sss_domain_info **_domain) { struct sudosrv_parse_query_state *state = NULL; - struct sss_domain_info *domain = NULL; - char *username = NULL; - char *domainname = NULL; - errno_t ret; state = tevent_req_data(req, struct sudosrv_parse_query_state); TEVENT_REQ_RETURN_ON_ERROR(req); - if (state->rawname == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "No query specified?!\n"); - return EINVAL; - } - - /* Try to parse username@domain again because if the first call - * returned EAGAIN, then username is unset. If we get EAGAIN again, - * we will not search for it again. - */ - ret = sss_parse_name_for_domains(state, state->rctx->domains, - state->rctx->default_domain, - state->rawname, - &domainname, &username); - if (ret != EOK) { - DEBUG(SSSDBG_TRACE_FUNC, "Unable to parse domain [%d]: %s\n", - ret, strerror(ret)); - return ret; - } - - if (username == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "No username specified!\n"); - return EINVAL; - } - - if (domainname != NULL) { - /* mem_ctx because it duplicates only subdomains not domains - * so I cannot easily steal it */ - domain = responder_get_domain(state->rctx, domainname); - if (domain == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "Corresponding domain [%s] has not been " - "found\n", domainname); - return ENOENT; - } - } - *_uid = state->uid; - *_username = talloc_steal(mem_ctx, username); - *_domain = domain; /* do not steal on mem_ctx */ + *_username = talloc_steal(mem_ctx, state->username); + *_domain = state->domain; /* do not steal on mem_ctx */ return EOK; } -- 2.1.0
From 414e89774091c97393676a945d7fdcbcd03df6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Tue, 9 Feb 2016 10:52:51 +0100 Subject: [PATCH 3/4] sudo: do not use tevent when parsing query --- src/responder/sudo/sudosrv_cmd.c | 30 +++++--- src/responder/sudo/sudosrv_get_sudorules.c | 2 +- src/responder/sudo/sudosrv_private.h | 16 ++-- src/responder/sudo/sudosrv_query.c | 115 +++++------------------------ 4 files changed, 45 insertions(+), 118 deletions(-) diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c index c68a6980ba817071e3766a0ddf7c158499d47aec..bdf01fac73886ed91507f318575c4af546ad7528 100644 --- a/src/responder/sudo/sudosrv_cmd.c +++ b/src/responder/sudo/sudosrv_cmd.c @@ -25,6 +25,7 @@ #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" +#include "responder/common/responder_cache_req.h" #include "responder/sudo/sudosrv_private.h" #include "db/sysdb_sudo.h" #include "sss_client/sss_cli.h" @@ -164,7 +165,7 @@ errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret) return EOK; } -static void sudosrv_cmd_parse_query_done(struct tevent_req *req); +static void sudosrv_cmd_initgr_done(struct tevent_req *req); static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) { @@ -213,7 +214,6 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) } /* parse query */ - sss_packet_get_body(cli_ctx->creq->in, &query_body, &query_len); if (query_len <= 0 || query_body == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Query is empty\n"); @@ -221,14 +221,24 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) goto done; } - req = sudosrv_parse_query_send(cmd_ctx, cmd_ctx->sudo_ctx, - query_body, query_len); + ret = sudosrv_parse_query(cmd_ctx, query_body, query_len, + &cmd_ctx->rawname, &cmd_ctx->uid); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse sudo query [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + req = cache_req_initgr_by_name_send(cmd_ctx, cli_ctx->ev, cli_ctx->rctx, + cmd_ctx->sudo_ctx->ncache, + cmd_ctx->sudo_ctx->neg_timeout, + 0, NULL, cmd_ctx->rawname); if (req == NULL) { ret = ENOMEM; goto done; } - tevent_req_set_callback(req, sudosrv_cmd_parse_query_done, cmd_ctx); + tevent_req_set_callback(req, sudosrv_cmd_initgr_done, cmd_ctx); ret = EAGAIN; @@ -236,19 +246,19 @@ done: return sudosrv_cmd_done(cmd_ctx, ret); } -static void sudosrv_cmd_parse_query_done(struct tevent_req *req) +static void sudosrv_cmd_initgr_done(struct tevent_req *req) { struct sudo_cmd_ctx *cmd_ctx = NULL; errno_t ret; cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx); - ret = sudosrv_parse_query_recv(cmd_ctx, req, &cmd_ctx->uid, - &cmd_ctx->username, &cmd_ctx->domain); + ret = cache_req_initgr_by_name_recv(cmd_ctx, req, NULL, &cmd_ctx->domain, + &cmd_ctx->username); talloc_zfree(req); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid query [%d]: %s\n", - ret, strerror(ret)); + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform initgroups [%d]: %s\n", + ret, strerror(ret)); goto done; } diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index 13015072e6daf1455b0b8e66a225f84c94280958..c81c990ac07d949ade47bbaf5b26f56117b5bfe7 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -24,6 +24,7 @@ #include <stdint.h> #include <string.h> #include <talloc.h> +#include <tevent.h> #include "util/util.h" #include "db/sysdb_sudo.h" @@ -34,7 +35,6 @@ errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx) { errno_t ret; - /* OK, got the user from cache. Try to get the rules. */ ret = sudosrv_get_rules(cmd_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index dceb113b530c8adfdb361cafff95b49d7dc323b5..38de16960d9eaff38b92cddb859fcb8ef2c90c5d 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -60,6 +60,7 @@ struct sudo_cmd_ctx { /* input data */ uid_t uid; + char *rawname; char *username; struct sss_domain_info *domain; @@ -78,16 +79,11 @@ errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx); errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx); -struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, - struct sudo_ctx *sudo_ctx, - uint8_t *query_body, - size_t query_len); - -errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - uid_t *_uid, - char **_username, - struct sss_domain_info **_domain); +errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx, + uint8_t *query_body, + size_t query_len, + char **_rawname, + uid_t *_uid); errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx, uint32_t error, diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c index 08b359c0464f1cc00866e46634e571562910018d..36d777eb52e8fa7f1d366433b56d37431bf0bb7c 100644 --- a/src/responder/sudo/sudosrv_query.c +++ b/src/responder/sudo/sudosrv_query.c @@ -25,7 +25,6 @@ #include <tevent.h> #include "util/util.h" -#include "responder/common/responder_cache_req.h" #include "responder/sudo/sudosrv_private.h" static int sudosrv_response_append_string(TALLOC_CTX *mem_ctx, @@ -252,128 +251,50 @@ fail: return ret; } -struct sudosrv_parse_query_state { - uid_t uid; - char *username; - struct sss_domain_info *domain; -}; - -static void sudosrv_parse_query_done(struct tevent_req *subreq); - -struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, - struct sudo_ctx *sudo_ctx, - uint8_t *query_body, - size_t query_len) +errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx, + uint8_t *query_body, + size_t query_len, + char **_rawname, + uid_t *_uid) { - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; - struct sudosrv_parse_query_state *state = NULL; size_t offset = 0; - size_t rawname_len = 0; - char *rawname = NULL; - errno_t ret; - - /* create request */ - req = tevent_req_create(mem_ctx, &state, - struct sudosrv_parse_query_state); - if (req == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "tevent_req_create() failed\n"); - return NULL; - } + size_t rawname_len; + char *rawname; + uid_t uid; /* uid */ - if (query_len < sizeof(uid_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "Query is too small\n"); - ret = EINVAL; - goto immediately; + return EINVAL; } - safealign_memcpy(&state->uid, query_body, sizeof(uid_t), &offset); + safealign_memcpy(&uid, query_body, sizeof(uid_t), &offset); /* username[@domain] */ - rawname = (char*)(query_body + offset); rawname_len = query_len - offset; /* strlen + zero */ if (rawname[rawname_len - 1] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Username is not zero terminated\n"); - ret = EINVAL; - goto immediately; + return EINVAL; } if (rawname_len < 2) { /* at least one character and zero */ DEBUG(SSSDBG_CRIT_FAILURE, "Query does not contain username\n"); - ret = EINVAL; - goto immediately; + return EINVAL; } if (!sss_utf8_check((uint8_t*)rawname, rawname_len - 1)) { DEBUG(SSSDBG_CRIT_FAILURE, "Supplied data is not valid UTF-8 string\n"); - ret = EINVAL; - goto immediately; + return EINVAL; } - /* parse username */ - - subreq = cache_req_initgr_by_name_send(state, sudo_ctx->rctx->ev, - sudo_ctx->rctx, sudo_ctx->ncache, - sudo_ctx->neg_timeout, 0, - NULL, rawname); - if (subreq == NULL) { - ret = ENOMEM; - goto immediately; - } - - tevent_req_set_callback(subreq, sudosrv_parse_query_done, req); - - return req; - -immediately: - if (ret == EOK) { - tevent_req_done(req); - } else { - tevent_req_error(req, ret); - } - tevent_req_post(req, sudo_ctx->rctx->ev); - - return req; -} - -static void sudosrv_parse_query_done(struct tevent_req *subreq) -{ - struct sudosrv_parse_query_state *state; - struct tevent_req *req; - errno_t ret; - - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sudosrv_parse_query_state); - - ret = cache_req_initgr_by_name_recv(state, subreq, NULL, - &state->domain, &state->username); - talloc_zfree(subreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; + rawname = talloc_strdup(mem_ctx, rawname); + if (rawname == NULL) { + return ENOMEM; } - tevent_req_done(req); -} - -errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - uid_t *_uid, - char **_username, - struct sss_domain_info **_domain) -{ - struct sudosrv_parse_query_state *state = NULL; - - state = tevent_req_data(req, struct sudosrv_parse_query_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - *_uid = state->uid; - *_username = talloc_steal(mem_ctx, state->username); - *_domain = state->domain; /* do not steal on mem_ctx */ + *_uid = uid; + *_rawname = rawname; return EOK; } -- 2.1.0
From 45ce91a5124e45f762a3028615600cd4e09de0db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com> Date: Tue, 9 Feb 2016 12:57:59 +0100 Subject: [PATCH 4/4] sudo: convert get_sudorules to tevent There was a lot of confusion with different error codes and where to call sudosrv_cmd_done to finish the client request. Converting it whole to tevent makes it much more simpler to read and follow the request logic. --- src/responder/sudo/sudosrv_cmd.c | 46 +- src/responder/sudo/sudosrv_get_sudorules.c | 867 +++++++++++++++-------------- src/responder/sudo/sudosrv_private.h | 18 +- 3 files changed, 481 insertions(+), 450 deletions(-) diff --git a/src/responder/sudo/sudosrv_cmd.c b/src/responder/sudo/sudosrv_cmd.c index bdf01fac73886ed91507f318575c4af546ad7528..eeb388c48e6255959ad4afd0f10a358d1fab44bc 100644 --- a/src/responder/sudo/sudosrv_cmd.c +++ b/src/responder/sudo/sudosrv_cmd.c @@ -25,7 +25,6 @@ #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" -#include "responder/common/responder_cache_req.h" #include "responder/sudo/sudosrv_private.h" #include "db/sysdb_sudo.h" #include "sss_client/sss_cli.h" @@ -96,7 +95,7 @@ static errno_t sudosrv_cmd_send_error(TALLOC_CTX *mem_ctx, return sudosrv_cmd_send_reply(cmd_ctx, response_body, response_len); } -errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret) +errno_t sudosrv_cmd_reply(struct sudo_cmd_ctx *cmd_ctx, int ret) { uint8_t *response_body = NULL; size_t response_len = 0; @@ -165,7 +164,7 @@ errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret) return EOK; } -static void sudosrv_cmd_initgr_done(struct tevent_req *req); +static void sudosrv_cmd_done(struct tevent_req *req); static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) { @@ -185,7 +184,6 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) return ENOMEM; } - cmd_ctx->domain = NULL; cmd_ctx->cli_ctx = cli_ctx; cmd_ctx->type = type; cmd_ctx->sudo_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct sudo_ctx); @@ -229,56 +227,40 @@ static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) goto done; } - req = cache_req_initgr_by_name_send(cmd_ctx, cli_ctx->ev, cli_ctx->rctx, - cmd_ctx->sudo_ctx->ncache, - cmd_ctx->sudo_ctx->neg_timeout, - 0, NULL, cmd_ctx->rawname); + req = sudosrv_get_rules_send(cmd_ctx, cli_ctx->ev, cmd_ctx->sudo_ctx, + cmd_ctx->type, cmd_ctx->uid, + cmd_ctx->rawname); if (req == NULL) { ret = ENOMEM; goto done; } - tevent_req_set_callback(req, sudosrv_cmd_initgr_done, cmd_ctx); + tevent_req_set_callback(req, sudosrv_cmd_done, cmd_ctx); ret = EAGAIN; done: - return sudosrv_cmd_done(cmd_ctx, ret); + return sudosrv_cmd_reply(cmd_ctx, ret); } -static void sudosrv_cmd_initgr_done(struct tevent_req *req) +static void sudosrv_cmd_done(struct tevent_req *req) { - struct sudo_cmd_ctx *cmd_ctx = NULL; + struct sudo_cmd_ctx *cmd_ctx; errno_t ret; cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx); - ret = cache_req_initgr_by_name_recv(cmd_ctx, req, NULL, &cmd_ctx->domain, - &cmd_ctx->username); + ret = sudosrv_get_rules_recv(cmd_ctx, req, &cmd_ctx->rules, + &cmd_ctx->num_rules); talloc_zfree(req); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform initgroups [%d]: %s\n", - ret, strerror(ret)); + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain cached rules [%d]: %s\n", + ret, sss_strerror(ret)); goto done; } - switch (cmd_ctx->type) { - case SSS_SUDO_DEFAULTS: - DEBUG(SSSDBG_FUNC_DATA, "Requesting default options " - "for [%s] from [%s]\n", cmd_ctx->username, - cmd_ctx->domain ? cmd_ctx->domain->name : "<ALL>"); - break; - case SSS_SUDO_USER: - DEBUG(SSSDBG_FUNC_DATA, "Requesting rules " - "for [%s] from [%s]\n", cmd_ctx->username, - cmd_ctx->domain ? cmd_ctx->domain->name : "<ALL>"); - break; - } - - ret = sudosrv_get_sudorules(cmd_ctx); - done: - sudosrv_cmd_done(cmd_ctx, ret); + sudosrv_cmd_reply(cmd_ctx, ret); } static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx) diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index c81c990ac07d949ade47bbaf5b26f56117b5bfe7..1861e3f3c78db277f94949d45335c9206813df20 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -28,419 +28,10 @@ #include "util/util.h" #include "db/sysdb_sudo.h" +#include "responder/common/responder_cache_req.h" #include "responder/sudo/sudosrv_private.h" #include "providers/data_provider.h" -errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx) -{ - errno_t ret; - - ret = sudosrv_get_rules(cmd_ctx); - if (ret == EAGAIN) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Looking up the sudo rules from Data Provider\n"); - return EAGAIN; - } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Error looking up sudo rules [%d]: %s\n", ret, strerror(ret)); - return ret; - } - - return EOK; -} - -static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, - struct sudo_cmd_ctx *cmd_ctx, - struct sysdb_attrs ***_rules, - uint32_t *_num_rules); -static void -sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, - const char *err_msg, void *ptr); -static void -sudosrv_dp_req_done(struct tevent_req *req); - -static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - const char **attrs, - unsigned int flags, - const char *username, - uid_t uid, - char **groupnames, - bool inverse_order, - struct sysdb_attrs ***_rules, - uint32_t *_count); - -errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) -{ - TALLOC_CTX *tmp_ctx = NULL; - struct tevent_req *dpreq = NULL; - struct dp_callback_ctx *cb_ctx = NULL; - char **groupnames = NULL; - uint32_t expired_rules_num = 0; - struct sysdb_attrs **expired_rules = NULL; - errno_t ret; - unsigned int flags = SYSDB_SUDO_FILTER_NONE; - const char *attrs[] = { SYSDB_NAME, - NULL }; - - if (cmd_ctx->domain == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Domain is not set!\n"); - return EFAULT; - } - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); - return ENOMEM; - } - - switch (cmd_ctx->type) { - case SSS_SUDO_DEFAULTS: - DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options " - "for [%s] from [%s]\n", cmd_ctx->username, - cmd_ctx->domain->name); - break; - case SSS_SUDO_USER: - DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules " - "for [%s] from [%s]\n", cmd_ctx->username, - cmd_ctx->domain->name); - break; - } - - /* Fetch all expired rules: - * sudo asks sssd twice - for defaults and for rules. If we refresh all - * expired rules for this user and defaults at once we will save one - * provider call - */ - ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->domain, - cmd_ctx->username, NULL, &groupnames); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to retrieve user info [%d]: %s\n", ret, strerror(ret)); - goto done; - } - - flags = SYSDB_SUDO_FILTER_INCLUDE_ALL - | SYSDB_SUDO_FILTER_INCLUDE_DFL - | SYSDB_SUDO_FILTER_ONLY_EXPIRED - | SYSDB_SUDO_FILTER_USERINFO; - ret = sudosrv_get_sudorules_query_cache(tmp_ctx, - cmd_ctx->domain, attrs, flags, - cmd_ctx->username, - cmd_ctx->uid, groupnames, - cmd_ctx->sudo_ctx->inverse_order, - &expired_rules, &expired_rules_num); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve expired sudo rules " - "[%d]: %s\n", ret, strerror(ret)); - goto done; - } - - cmd_ctx->expired_rules_num = expired_rules_num; - if (expired_rules_num > 0) { - /* refresh expired rules then continue */ - DEBUG(SSSDBG_TRACE_INTERNAL, "Refreshing %d expired rules\n", - expired_rules_num); - dpreq = sss_dp_get_sudoers_send(tmp_ctx, cmd_ctx->cli_ctx->rctx, - cmd_ctx->domain, false, - SSS_DP_SUDO_REFRESH_RULES, - cmd_ctx->username, - expired_rules_num, expired_rules); - if (dpreq == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Cannot issue DP request.\n"); - ret = EIO; - goto done; - } - - cb_ctx = talloc_zero(tmp_ctx, struct dp_callback_ctx); - if (!cb_ctx) { - talloc_zfree(dpreq); - ret = ENOMEM; - goto done; - } - - cb_ctx->callback = sudosrv_get_sudorules_dp_callback; - cb_ctx->ptr = cmd_ctx; - cb_ctx->cctx = cmd_ctx->cli_ctx; - cb_ctx->mem_ctx = cmd_ctx; - - tevent_req_set_callback(dpreq, sudosrv_dp_req_done, cb_ctx); - ret = EAGAIN; - - } else { - /* nothing is expired return what we have in the cache */ - DEBUG(SSSDBG_TRACE_INTERNAL, "About to get sudo rules from cache\n"); - ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx, - &cmd_ctx->rules, - &cmd_ctx->num_rules); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to make a request to our cache [%d]: %s\n", - ret, strerror(ret)); - goto done; - } - } - - if (dpreq != NULL) { - talloc_steal(cmd_ctx->cli_ctx, dpreq); - } - - if (cb_ctx != NULL) { - talloc_steal(cmd_ctx, cb_ctx); - } - -done: - talloc_free(tmp_ctx); - return ret; -} - -static void -sudosrv_dp_req_done(struct tevent_req *req) -{ - struct dp_callback_ctx *cb_ctx = - tevent_req_callback_data(req, struct dp_callback_ctx); - struct cli_ctx *cli_ctx; - - errno_t ret; - dbus_uint16_t err_maj; - dbus_uint32_t err_min; - char *err_msg; - - cli_ctx = talloc_get_type(cb_ctx->cctx, struct cli_ctx); - - ret = sss_dp_get_sudoers_recv(cb_ctx->mem_ctx, req, - &err_maj, &err_min, - &err_msg); - talloc_free(req); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); - talloc_free(cli_ctx); - return; - } - - cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); -} - -static void -sudosrv_dp_oob_req_done(struct tevent_req *req) -{ - DEBUG(SSSDBG_TRACE_FUNC, "Out of band refresh finished\n"); - talloc_free(req); -} - -static void -sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, - const char *err_msg, void *ptr) -{ - struct sudo_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct sudo_cmd_ctx); - struct tevent_req *dpreq = NULL; - errno_t ret; - - if (err_maj) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to get information from Data Provider\n" - "Error: %u, %u, %s\n" - "Will try to return what we have in cache\n", - (unsigned int)err_maj, (unsigned int)err_min, err_msg); - } - - DEBUG(SSSDBG_TRACE_INTERNAL, "About to get sudo rules from cache\n"); - ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx, &cmd_ctx->rules, - &cmd_ctx->num_rules); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to make a request to our cache [%d]: %s\n", - ret, strerror(ret)); - sudosrv_cmd_done(cmd_ctx, EIO); - return; - } - - if (cmd_ctx->expired_rules_num > 0 - && err_min == ENOENT) { - DEBUG(SSSDBG_TRACE_INTERNAL, - "Some expired rules were removed from the server, " - "scheduling full refresh out of band\n"); - dpreq = sss_dp_get_sudoers_send(cmd_ctx->cli_ctx->rctx, - cmd_ctx->cli_ctx->rctx, - cmd_ctx->domain, false, - SSS_DP_SUDO_FULL_REFRESH, - cmd_ctx->username, - 0, NULL); - if (dpreq == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Cannot issue DP request.\n"); - } else { - tevent_req_set_callback(dpreq, sudosrv_dp_oob_req_done, NULL); - } - } - - sudosrv_cmd_done(cmd_ctx, ret); -} - -static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, - struct sudo_cmd_ctx *cmd_ctx, - struct sysdb_attrs ***_rules, - uint32_t *_num_rules) -{ - TALLOC_CTX *tmp_ctx; - errno_t ret; - char **groupnames = NULL; - const char *debug_name = NULL; - unsigned int flags = SYSDB_SUDO_FILTER_NONE; - struct sysdb_attrs **rules = NULL; - uint32_t num_rules = 0; - const char *attrs[] = { SYSDB_OBJECTCLASS, - SYSDB_SUDO_CACHE_AT_CN, - SYSDB_SUDO_CACHE_AT_USER, - SYSDB_SUDO_CACHE_AT_HOST, - SYSDB_SUDO_CACHE_AT_COMMAND, - SYSDB_SUDO_CACHE_AT_OPTION, - SYSDB_SUDO_CACHE_AT_RUNAS, - SYSDB_SUDO_CACHE_AT_RUNASUSER, - SYSDB_SUDO_CACHE_AT_RUNASGROUP, - SYSDB_SUDO_CACHE_AT_NOTBEFORE, - SYSDB_SUDO_CACHE_AT_NOTAFTER, - SYSDB_SUDO_CACHE_AT_ORDER, - NULL }; - - if (cmd_ctx->domain == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Domain is not set!\n"); - return EFAULT; - } - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); - return ENOMEM; - } - - switch (cmd_ctx->type) { - case SSS_SUDO_USER: - debug_name = cmd_ctx->username; - ret = sysdb_get_sudo_user_info(tmp_ctx, - cmd_ctx->domain, - cmd_ctx->username, - NULL, &groupnames); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to retrieve user info [%d]: %s\n", - ret, strerror(ret)); - goto done; - } - flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL; - break; - case SSS_SUDO_DEFAULTS: - debug_name = "<default options>"; - flags = SYSDB_SUDO_FILTER_INCLUDE_DFL; - break; - } - - ret = sudosrv_get_sudorules_query_cache(tmp_ctx, - cmd_ctx->domain, attrs, flags, - cmd_ctx->username, - cmd_ctx->uid, groupnames, - cmd_ctx->sudo_ctx->inverse_order, - &rules, &num_rules); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to retrieve sudo rules [%d]: %s\n", ret, strerror(ret)); - goto done; - } - - DEBUG(SSSDBG_TRACE_FUNC, "Returning %d rules for [%s@%s]\n", - num_rules, debug_name, cmd_ctx->domain->name); - - if (_rules != NULL) { - *_rules = talloc_steal(mem_ctx, rules); - } - - if (_num_rules != NULL) { - *_num_rules = num_rules; - } - - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} - -static errno_t -sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool higher_wins); - -static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - const char **attrs, - unsigned int flags, - const char *username, - uid_t uid, - char **groupnames, - bool inverse_order, - struct sysdb_attrs ***_rules, - uint32_t *_count) -{ - TALLOC_CTX *tmp_ctx; - char *filter; - errno_t ret; - size_t count; - struct sysdb_attrs **rules; - struct ldb_message **msgs; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) return ENOMEM; - - ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames, - flags, &filter); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not construct the search filter [%d]: %s\n", - ret, strerror(ret)); - goto done; - } - - DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter); - - if (IS_SUBDOMAIN(domain)) { - /* rules are stored inside parent domain tree */ - domain = domain->parent; - } - - ret = sysdb_search_custom(tmp_ctx, domain, filter, - SUDORULE_SUBDIR, attrs, - &count, &msgs); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n"); - goto done; - } if (ret == ENOENT) { - *_rules = NULL; - *_count = 0; - ret = EOK; - goto done; - } - - ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not convert ldb message to sysdb_attrs\n"); - goto done; - } - - ret = sort_sudo_rules(rules, count, inverse_order); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Could not sort rules by sudoOrder\n"); - goto done; - } - - *_rules = talloc_steal(mem_ctx, rules); - *_count = (uint32_t)count; - - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} - static int sudo_order_cmp(const void *a, const void *b, bool lower_wins) { @@ -521,3 +112,459 @@ sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins) return EOK; } + +static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char **attrs, + unsigned int flags, + const char *username, + uid_t uid, + char **groupnames, + bool inverse_order, + struct sysdb_attrs ***_rules, + uint32_t *_count) +{ + TALLOC_CTX *tmp_ctx; + char *filter; + errno_t ret; + size_t count; + struct sysdb_attrs **rules; + struct ldb_message **msgs; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames, + flags, &filter); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct the search filter " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter); + + if (IS_SUBDOMAIN(domain)) { + /* rules are stored inside parent domain tree */ + domain = domain->parent; + } + + ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR, + attrs, &count, &msgs); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n"); + goto done; + } if (ret == ENOENT) { + *_rules = NULL; + *_count = 0; + ret = EOK; + goto done; + } + + ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not convert ldb message to sysdb_attrs\n"); + goto done; + } + + ret = sort_sudo_rules(rules, count, inverse_order); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n"); + goto done; + } + + *_rules = talloc_steal(mem_ctx, rules); + *_count = (uint32_t)count; + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +static errno_t sudosrv_expired_rules(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + uid_t uid, + const char *username, + char **groups, + struct sysdb_attrs ***_rules, + uint32_t *_num_rules) +{ + unsigned int flags = SYSDB_SUDO_FILTER_NONE; + const char *attrs[] = {SYSDB_NAME, NULL}; + errno_t ret; + + flags = SYSDB_SUDO_FILTER_INCLUDE_ALL + | SYSDB_SUDO_FILTER_INCLUDE_DFL + | SYSDB_SUDO_FILTER_ONLY_EXPIRED + | SYSDB_SUDO_FILTER_USERINFO; + + ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags, + username, uid, groups, false, + _rules, _num_rules); + + return ret; +} + +static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx, + enum sss_sudo_type type, + struct sss_domain_info *domain, + uid_t uid, + const char *username, + char **groups, + bool inverse_order, + struct sysdb_attrs ***_rules, + uint32_t *_num_rules) +{ + unsigned int flags = SYSDB_SUDO_FILTER_NONE; + struct sysdb_attrs **rules; + const char *debug_name; + uint32_t num_rules; + errno_t ret; + const char *attrs[] = {SYSDB_OBJECTCLASS, + SYSDB_SUDO_CACHE_AT_CN, + SYSDB_SUDO_CACHE_AT_USER, + SYSDB_SUDO_CACHE_AT_HOST, + SYSDB_SUDO_CACHE_AT_COMMAND, + SYSDB_SUDO_CACHE_AT_OPTION, + SYSDB_SUDO_CACHE_AT_RUNAS, + SYSDB_SUDO_CACHE_AT_RUNASUSER, + SYSDB_SUDO_CACHE_AT_RUNASGROUP, + SYSDB_SUDO_CACHE_AT_NOTBEFORE, + SYSDB_SUDO_CACHE_AT_NOTAFTER, + SYSDB_SUDO_CACHE_AT_ORDER, + NULL }; + + + switch (type) { + case SSS_SUDO_USER: + DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules for [%s@%s]\n", + username, domain->name); + debug_name = "rules"; + flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL; + break; + case SSS_SUDO_DEFAULTS: + debug_name = "default options"; + DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options for [%s@%s]\n", + username, domain->name); + flags = SYSDB_SUDO_FILTER_INCLUDE_DFL; + break; + } + + ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags, + username, uid, groups, + inverse_order, &rules, &num_rules); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to retrieve sudo rules [%d]: %s\n", ret, strerror(ret)); + return ret; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Returning %d %s for [%s@%s]\n", + num_rules, debug_name, username, domain->name); + + *_rules = rules; + *_num_rules = num_rules; + + return EOK; +} + +static void +sudosrv_dp_oob_req_done(struct tevent_req *req) +{ + DEBUG(SSSDBG_TRACE_FUNC, "Out of band refresh finished\n"); + talloc_free(req); +} + +struct sudosrv_refresh_rules_state { + struct resp_ctx *rctx; + struct sss_domain_info *domain; + const char *username; +}; + +static void sudosrv_refresh_rules_done(struct tevent_req *subreq); + +static struct tevent_req * +sudosrv_refresh_rules_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_domain_info *domain, + uid_t uid, + const char *username, + char **groups) +{ + struct sudosrv_refresh_rules_state *state; + struct tevent_req *req; + struct tevent_req *subreq; + struct sysdb_attrs **rules; + uint32_t num_rules; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, + struct sudosrv_refresh_rules_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); + return NULL; + } + + state->rctx = rctx; + state->domain = domain; + state->username = username; + + ret = sudosrv_expired_rules(state, domain, uid, username, groups, + &rules, &num_rules); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve expired sudo rules " + "[%d]: %s\n", ret, strerror(ret)); + goto immediately; + } + + if (num_rules == 0) { + DEBUG(SSSDBG_TRACE_FUNC, "No expired rules were found for [%s@%s].\n", + username, domain->name); + ret = EOK; + goto immediately; + } + + DEBUG(SSSDBG_TRACE_INTERNAL, "Refreshing %d expired rules of [%s@%s]\n", + num_rules, username, domain->name); + + subreq = sss_dp_get_sudoers_send(state, rctx, domain, false, + SSS_DP_SUDO_REFRESH_RULES, + username, num_rules, rules); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; + } + + tevent_req_set_callback(subreq, sudosrv_refresh_rules_done, req); + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, ev); + + return req; +} + +static void sudosrv_refresh_rules_done(struct tevent_req *subreq) +{ + struct sudosrv_refresh_rules_state *state; + struct tevent_req *req; + dbus_uint16_t err_maj; + dbus_uint32_t err_min; + char *err_msg; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct sudosrv_refresh_rules_state); + + ret = sss_dp_get_sudoers_recv(state, subreq, &err_maj, &err_min, &err_msg); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unable to get information from Data Provider, " + "Error: %u, %u, %s\n", + (unsigned int)err_maj, (unsigned int)err_min, err_msg); + goto done; + } + + if (err_min == ENOENT) { + DEBUG(SSSDBG_TRACE_INTERNAL, "Some expired rules were removed from " + "the server, scheduling full refresh out of band\n"); + subreq = sss_dp_get_sudoers_send(state->rctx, state->rctx, + state->domain, false, + SSS_DP_SUDO_FULL_REFRESH, + state->username, 0, NULL); + if (subreq == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, "Cannot issue DP request.\n"); + ret = EOK; /* We don't care. */ + goto done; + } + + tevent_req_set_callback(subreq, sudosrv_dp_oob_req_done, NULL); + } + + ret = EOK; + +done: + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +static errno_t sudosrv_refresh_rules_recv(struct tevent_req *req) +{ + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +struct sudosrv_get_rules_state { + struct tevent_context *ev; + struct resp_ctx *rctx; + enum sss_sudo_type type; + uid_t uid; + char *username; + struct sss_domain_info *domain; + char **groups; + bool inverse_order; + + struct sysdb_attrs **rules; + uint32_t num_rules; +}; + +static void sudosrv_get_rules_initgr_done(struct tevent_req *subreq); +static void sudosrv_get_rules_done(struct tevent_req *subreq); + +struct tevent_req *sudosrv_get_rules_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sudo_ctx *sudo_ctx, + enum sss_sudo_type type, + uid_t uid, + const char *username) +{ + struct sudosrv_get_rules_state *state; + struct tevent_req *req; + struct tevent_req *subreq; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, struct sudosrv_get_rules_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); + return NULL; + } + + state->ev = ev; + state->rctx = sudo_ctx->rctx; + state->type = type; + state->uid = uid; + state->inverse_order = sudo_ctx->inverse_order; + + DEBUG(SSSDBG_TRACE_FUNC, "Running initgroups for [%s]\n", username); + + subreq = cache_req_initgr_by_name_send(state, ev, sudo_ctx->rctx, + sudo_ctx->ncache, + sudo_ctx->neg_timeout, + 0, NULL, username); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; + } + + tevent_req_set_callback(subreq, sudosrv_get_rules_initgr_done, req); + + return req; + +immediately: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, ev); + + return req; +} + +static void sudosrv_get_rules_initgr_done(struct tevent_req *subreq) +{ + struct sudosrv_get_rules_state *state; + struct tevent_req *req; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct sudosrv_get_rules_state); + + ret = cache_req_initgr_by_name_recv(state, subreq, NULL, + &state->domain, &state->username); + talloc_zfree(subreq); + if (ret != EOK) { + goto done; + } + + ret = sysdb_get_sudo_user_info(state, state->domain, state->username, + NULL, &state->groups); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain user groups [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + subreq = sudosrv_refresh_rules_send(state, state->ev, state->rctx, + state->domain, state->uid, + state->username, state->groups); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + + tevent_req_set_callback(subreq, sudosrv_get_rules_done, req); + + ret = EAGAIN; + +done: + if (ret != EOK && ret != EAGAIN) { + tevent_req_error(req, ret); + return; + } else if (ret != EAGAIN) { + tevent_req_done(req); + } +} + +static void sudosrv_get_rules_done(struct tevent_req *subreq) +{ + struct sudosrv_get_rules_state *state = NULL; + struct tevent_req *req = NULL; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct sudosrv_get_rules_state); + + ret = sudosrv_refresh_rules_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh expired rules, " + "we will return what is in cache.\n"); + } + + ret = sudosrv_cached_rules(state, state->type, state->domain, state->uid, + state->username, state->groups, + state->inverse_order, + &state->rules, &state->num_rules); + + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +errno_t sudosrv_get_rules_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct sysdb_attrs ***_rules, + uint32_t *_num_rules) +{ + struct sudosrv_get_rules_state *state = NULL; + state = tevent_req_data(req, struct sudosrv_get_rules_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *_rules = talloc_steal(mem_ctx, state->rules); + *_num_rules = state->num_rules; + + return EOK; +} diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 38de16960d9eaff38b92cddb859fcb8ef2c90c5d..99eef03e950f88d9296dbf33e66c68f100523cc9 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -61,10 +61,6 @@ struct sudo_cmd_ctx { /* input data */ uid_t uid; char *rawname; - char *username; - struct sss_domain_info *domain; - - uint32_t expired_rules_num; /* output data */ struct sysdb_attrs **rules; @@ -73,11 +69,17 @@ struct sudo_cmd_ctx { struct sss_cmd_table *get_sudo_cmds(void); -errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret); +struct tevent_req *sudosrv_get_rules_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sudo_ctx *sudo_ctx, + enum sss_sudo_type type, + uid_t uid, + const char *username); -errno_t sudosrv_get_sudorules(struct sudo_cmd_ctx *cmd_ctx); - -errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx); +errno_t sudosrv_get_rules_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct sysdb_attrs ***_rules, + uint32_t *_num_rules); errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx, uint8_t *query_body, -- 2.1.0
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org