sudosrv_get_sudorules.c revision 76db25eab9010a33657f35e5afc8477c996df7a3
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Pavel Březina <pbrezina@redhat.com>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Jakub Hrozek <jhrozek@redhat.com>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Copyright (C) 2011 Red Hat
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina This program is free software; you can redistribute it and/or modify
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina it under the terms of the GNU General Public License as published by
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina the Free Software Foundation; either version 3 of the License, or
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina (at your option) any later version.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina This program is distributed in the hope that it will be useful,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina GNU General Public License for more details.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina You should have received a copy of the GNU General Public License
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaerrno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Looking up the user info from Data Provider\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error looking up user information [%d]: %s\n", ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* OK, got the user from cache. Try to get the rules. */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Looking up the sudo rules from Data Provider\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error looking up sudo rules [%d]: %s\n", ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_dp_send_acct_req_done(struct tevent_req *req);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx;
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* if it is a domainless search, skip domains that require fully
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * qualified names instead */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek while (dom && cmd_ctx->check_next && dom->fqnames) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (!dom) break;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* make sure to update the dctx if we changed domain */
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina name = sss_get_cased_name(tmp_ctx, cmd_ctx->username,
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_FUNC_DATA, ("Requesting info about [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("sysdb context not found for this domain!\n"));
744dff21cc626efdc646dd293c97c6a19a9f6ed5Pavel Březina ret = sysdb_getpwnam(dctx, sysdb, name, &user);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Failed to make request to our cache!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("getpwnam call returned more than one result !?!\n"));
744dff21cc626efdc646dd293c97c6a19a9f6ed5Pavel Březina if (user->count == 0 && !dctx->check_provider) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* if a multidomain search, try with next */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dom) continue;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No results for getpwnam call\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* One result found, check cache expiry */
744dff21cc626efdc646dd293c97c6a19a9f6ed5Pavel Březina cache_expire = ldb_msg_find_attr_as_uint64(user->msgs[0],
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* If cache miss and we haven't checked DP yet OR the entry is
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * outdated, go to DP */
744dff21cc626efdc646dd293c97c6a19a9f6ed5Pavel Březina if ((user->count == 0 || cache_expire < time(NULL))
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dpreq = sss_dp_get_account_send(cli_ctx, cli_ctx->rctx,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Out of memory sending data provider request\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->callback = sudosrv_check_user_dp_callback;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* tell caller we are in an async call */
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina /* check uid */
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina uid = ldb_msg_find_attr_as_int(user->msgs[0], SYSDB_UIDNUM, 0);
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina /* if a multidomain search, try with next */
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina if (dom) continue;
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina DEBUG(SSSDBG_MINOR_FAILURE, ("UID does not match\n"));
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina /* user is stored in cache, remember cased and original name */
744dff21cc626efdc646dd293c97c6a19a9f6ed5Pavel Březina original_name = ldb_msg_find_attr_as_string(user->msgs[0],
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina cmd_ctx->cased_username = talloc_move(cmd_ctx, &name);
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina cmd_ctx->orig_username = talloc_strdup(cmd_ctx, original_name);
278284224aa10805d58c978977e43b1d1126f9b1Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina /* and set domain */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Returning info for user [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_dp_send_acct_req_done(struct tevent_req *req)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tevent_req_callback_data(req, struct dp_callback_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Fatal error, killing connection!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sudo_dom_ctx *dctx = talloc_get_type(ptr, struct sudo_dom_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Unable to get information from Data Provider\n"
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek "Error: %u, %u, %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek (unsigned int)err_maj, (unsigned int)err_min, err_msg));
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek ("Data Provider returned, check the cache again\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not look up the user [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Looking up sudo rules..\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error getting sudo rules [%d]: %s\n",
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březinastatic errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozeksudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březinaerrno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx)
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, ("Retrieving default options "
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina "for [%s] from [%s]\n", cmd_ctx->orig_username,
46d3d2c731e8c7e138462e5b60a39a279dc77d81Pavel Březina "for [%s] from [%s]\n", cmd_ctx->orig_username,
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek dpreq = sss_dp_get_sudoers_send(cmd_ctx->cli_ctx,
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek ("Cannot issue DP request.\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina cb_ctx = talloc_zero(cmd_ctx, struct dp_callback_ctx);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek cb_ctx->callback = sudosrv_get_sudorules_dp_callback;
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek tevent_req_set_callback(dpreq, sudosrv_dp_req_done, cb_ctx);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek tevent_req_callback_data(req, struct dp_callback_ctx);
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina struct cli_ctx *cli_ctx = talloc_get_type(cb_ctx->cctx, struct cli_ctx);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek ret = sss_dp_get_sudoers_recv(cb_ctx->mem_ctx, req,
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Fatal error, killing connection!\n"));
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozeksudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min,
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina struct sudo_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct sudo_cmd_ctx);
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek ("Unable to get information from Data Provider\n"
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek "Error: %u, %u, %s\n"
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek "Will try to return what we have in cache\n",
3b121852048a7931f8a608527b760963e2ed2bb4Jakub Hrozek (unsigned int)err_maj, (unsigned int)err_min, err_msg));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina ret = sudosrv_get_sudorules_from_cache(cmd_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Failed to make a request to our cache [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březinastatic errno_t sudosrv_get_sudorules_from_cache(struct sudo_cmd_ctx *cmd_ctx)
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Domain is not set!\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("sysdb context not found for this domain!\n"));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->orig_username, sysdb,
c47e9d522f0d87259e5074ea643daaa3dfcb8d92Pavel Březina ("Unable to retrieve user info [%d]: %s\n", strerror(ret)));
b0abb3bfdfd95951a23c9fc223c735805ffd2969Pavel Březina ret = sudosrv_get_sudorules_query_cache(cmd_ctx, sysdb, cmd_ctx->type,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Unable to retrieve sudo rules [%d]: %s\n", strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Returning rules for [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksort_sudo_rules(struct sysdb_attrs **rules, size_t count);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
76db25eab9010a33657f35e5afc8477c996df7a3Pavel Březina flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not construct the search filter [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_FUNC_DATA, ("Searching sysdb with [%s]\n", filter));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_search_custom(tmp_ctx, sysdb, filter,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Error looking up SUDO rules"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not convert ldb message to sysdb_attrs\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not sort rules by sudoOrder\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksudo_order_cmp_fn(const void *a, const void *b)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("BUG: Wrong data?\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_attrs_get_uint32_t(r1, SYSDB_SUDO_CACHE_AT_ORDER, &o1);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* man sudoers-ldap: If the sudoOrder attribute is not present,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * a value of 0 is assumed */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot get sudoOrder value\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_attrs_get_uint32_t(r2, SYSDB_SUDO_CACHE_AT_ORDER, &o2);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* man sudoers-ldap: If the sudoOrder attribute is not present,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * a value of 0 is assumed */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot get sudoOrder value\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksort_sudo_rules(struct sysdb_attrs **rules, size_t count)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek qsort(rules, count, sizeof(struct sysdb_attrs *),