sudosrv_get_sudorules.c revision 0c7aa697991ea9df960fae14fd567ebdda3b4ff4
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/*
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Authors:
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Pavel Březina <pbrezina@redhat.com>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Jakub Hrozek <jhrozek@redhat.com>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina Copyright (C) 2011 Red Hat
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
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
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
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/>.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina*/
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <stdint.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <string.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include <talloc.h>
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "util/util.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "db/sysdb_sudo.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina#include "responder/sudo/sudosrv_private.h"
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaerrno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->check_provider = true;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_user(dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == EAGAIN) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Looking up the user info from Data Provider\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EAGAIN;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error looking up user information [%d]: %s\n", ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* OK, got the user from cache. Try to get the rules. */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_rules(dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == EAGAIN) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Looking up the sudo rules from Data Provider\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EAGAIN;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error looking up sudo rules [%d]: %s\n", ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EOK;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
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 Hrozek const char *err_msg, void *ptr);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sss_domain_info *dom = dctx->domain;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_ctx *sysdb;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek time_t cache_expire = 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct tevent_req *dpreq;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct dp_callback_ctx *cb_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek while (dom) {
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 dom = dom->next;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (!dom) break;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* make sure to update the dctx if we changed domain */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->domain = dom;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_FUNC_DATA, ("Requesting info about [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cmd_ctx->username, dom->name));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_get_ctx_from_list(cli_ctx->rctx->db_list,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->domain, &sysdb);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("sysdb context not found for this domain!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EIO;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_getpwnam(dctx, sysdb, cmd_ctx->username, &dctx->user);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Failed to make request to our cache!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EIO;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dctx->user->count > 1) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("getpwnam call returned more than one result !?!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EIO;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dctx->user->count == 0 && !dctx->check_provider) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* if a multidomain search, try with next */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (cmd_ctx->check_next) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->check_provider = true;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dom = dom->next;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dom) continue;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, ("No results for getpwnam call\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ENOENT;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* One result found, check cache expiry */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dctx->user->count == 1) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cache_expire = ldb_msg_find_attr_as_uint64(dctx->user->msgs[0],
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_CACHE_EXPIRE, 0);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* If cache miss and we haven't checked DP yet OR the entry is
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * outdated, go to DP */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if ((dctx->user->count == 0 && dctx->check_provider) ||
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cache_expire < time(NULL)) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dpreq = sss_dp_get_account_send(cli_ctx, cli_ctx->rctx,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dom, false, SSS_DP_INITGROUPS,
0c7aa697991ea9df960fae14fd567ebdda3b4ff4Stephen Gallagher cmd_ctx->username, 0, NULL);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (!dpreq) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Out of memory sending data provider request\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ENOMEM;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if(!cb_ctx) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek talloc_zfree(dpreq);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ENOMEM;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->callback = sudosrv_check_user_dp_callback;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->ptr = dctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->cctx = cli_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->mem_ctx = cli_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* tell caller we are in an async call */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EAGAIN;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Returning info for user [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cmd_ctx->username, dctx->domain->name));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EOK;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ENOENT;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_dp_send_acct_req_done(struct tevent_req *req)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct dp_callback_ctx *cb_ctx =
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tevent_req_callback_data(req, struct dp_callback_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dbus_uint16_t err_maj;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dbus_uint32_t err_min;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char *err_msg;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek &err_maj, &err_min,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek &err_msg);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Fatal error, killing connection!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek talloc_free(cb_ctx->cctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const char *err_msg, void *ptr)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sudo_dom_ctx *dctx = talloc_get_type(ptr, struct sudo_dom_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (err_maj) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
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));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Data Provider returned, check the cache again\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->check_provider = false;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_user(dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* FIXME - set entry into cache so that we don't perform initgroups too often */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == EAGAIN) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not look up the user [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, EIO);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Looking up sudo rules..\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_rules(dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == EAGAIN) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Error getting sudo rules [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, EIO);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekdone:
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, ret);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_get_sudorules_dp_callback(struct tevent_req *req);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_rules(struct sudo_dom_ctx *dctx)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct tevent_req *dpreq;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* FIXME - cache logic will be here. For now, just refresh
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * the cache unconditionally */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dpreq = sudosrv_dp_refresh_send(cmd_ctx->cli_ctx->rctx,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->domain, cmd_ctx->username);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (dpreq == NULL) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Fatal: Sysdb CTX not found for this domain!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EIO;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tevent_req_set_callback(dpreq, sudosrv_get_sudorules_dp_callback, dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return EAGAIN;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic void sudosrv_get_sudorules_dp_callback(struct tevent_req *req)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sudo_dom_ctx *dctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dbus_uint16_t err_maj;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dbus_uint32_t err_min;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx = tevent_req_callback_data(req, struct sudo_dom_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_dp_refresh_recv(req, &err_maj, &err_min);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek talloc_zfree(req);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Data provider returned an error [%d]: %s "
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek "DBus error min: %d maj %d\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret, strerror(ret), err_maj, err_min));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, EIO);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("About to get sudo rules from cache\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_sudorules_from_cache(dctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Failed to make a request to our cache [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, EIO);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudosrv_cmd_done(dctx, ret);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_ctx *sysdb,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const char *username,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek uid_t uid,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char **groupnames,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_attrs ***_rules,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek size_t *_count);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_from_cache(struct sudo_dom_ctx *dctx)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek TALLOC_CTX *tmp_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_ctx *sysdb;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek uid_t uid;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char **groupnames;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tmp_ctx = talloc_new(NULL);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (tmp_ctx == NULL) return ENOMEM;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_get_ctx_from_list(cli_ctx->rctx->db_list,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->domain, &sysdb);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("sysdb context not found for this domain!\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = EIO;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_get_sudo_user_info(tmp_ctx, dctx->cmd_ctx->username,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sysdb, &uid, &groupnames);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Unable to retrieve user info [%d]: %s\n", strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sudosrv_get_sudorules_query_cache(dctx, sysdb,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->cmd_ctx->username,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek uid, groupnames,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek &dctx->res, &dctx->res_count);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Unable to retrieve sudo rules [%d]: %s\n", strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Returning rules for [%s@%s]\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek dctx->cmd_ctx->username, dctx->domain->name));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = EOK;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekdone:
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek talloc_free(tmp_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksort_sudo_rules(struct sysdb_attrs **rules, size_t count);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_ctx *sysdb,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const char *username,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek uid_t uid,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char **groupnames,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_attrs ***_rules,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek size_t *_count)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek TALLOC_CTX *tmp_ctx;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek char *filter;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek errno_t ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek size_t count;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_attrs **rules;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct ldb_message **msgs;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek const char *attrs[] = { SYSDB_OBJECTCLASS
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_OC,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_CN,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_USER,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_HOST,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_COMMAND,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_OPTION,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_RUNASUSER,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_RUNASGROUP,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_NOTBEFORE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_NOTAFTER,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_CACHE_AT_ORDER,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek NULL };
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek tmp_ctx = talloc_new(NULL);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (tmp_ctx == NULL) return ENOMEM;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek (SYSDB_SUDO_FILTER_NGRS | SYSDB_SUDO_FILTER_INCLUDE_ALL |
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SYSDB_SUDO_FILTER_INCLUDE_DFL), &filter);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not construct the search filter [%d]: %s\n",
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret, strerror(ret)));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_FUNC_DATA, ("Searching sysdb with [%s]\n", filter));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_search_custom(tmp_ctx, sysdb, filter,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek SUDORULE_SUBDIR, attrs,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek &count, &msgs);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK && ret != ENOENT) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("Error looking up SUDO rules"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } if (ret == ENOENT) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek *_rules = NULL;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek *_count = 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = EOK;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not convert ldb message to sysdb_attrs\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sort_sudo_rules(rules, count);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ("Could not sort rules by sudoOrder\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek goto done;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek *_rules = talloc_steal(mem_ctx, rules);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek *_count = count;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = EOK;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekdone:
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek talloc_free(tmp_ctx);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic int
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksudo_order_cmp_fn(const void *a, const void *b)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek struct sysdb_attrs *r1, *r2;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek uint32_t o1, o2;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek int ret;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek r1 = * (struct sysdb_attrs * const *) a;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek r2 = * (struct sysdb_attrs * const *) b;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (!r1 || !r2) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, ("BUG: Wrong data?\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_attrs_get_uint32_t(r1, SYSDB_SUDO_CACHE_AT_ORDER, &o1);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == ENOENT) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* man sudoers-ldap: If the sudoOrder attribute is not present,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * a value of 0 is assumed */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek o1 = 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot get sudoOrder value\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek ret = sysdb_attrs_get_uint32_t(r2, SYSDB_SUDO_CACHE_AT_ORDER, &o2);
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (ret == ENOENT) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek /* man sudoers-ldap: If the sudoOrder attribute is not present,
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek * a value of 0 is assumed */
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek o2 = 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (ret != EOK) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek DEBUG(SSSDBG_OP_FAILURE, ("Cannot get sudoOrder value\n"));
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek if (o1 > o2) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 1;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek } else if (o1 < o2) {
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return -1;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek }
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek return 0;
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek}
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozekstatic errno_t
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozeksort_sudo_rules(struct sysdb_attrs **rules, size_t count)
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek{
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek qsort(rules, count, sizeof(struct sysdb_attrs *),
20e310e32a47e861ce0c11bcd1dcf89dc78d8abaJakub Hrozek sudo_order_cmp_fn);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return EOK;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinachar * sudosrv_get_sudorules_parse_query(TALLOC_CTX *mem_ctx,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina const char *query_body,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int query_len)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
f643754db81eeade60485bbe3d80324d889cc4f3Pavel Březina /* empty string or not NULL terminated */
f643754db81eeade60485bbe3d80324d889cc4f3Pavel Březina if (query_len < 2 || strnlen(query_body, query_len) == query_len) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid query.\n"));
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return talloc_strdup(mem_ctx, query_body);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina/*
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * Response format:
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * <error_code(uint32_t)><num_entries(uint32_t)><rule1><rule2>...
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * <ruleN> = <num_attrs(uint32_t)><attr1><attr2>...
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * <attrN> = <name(char*)>\0<num_values(uint32_t)><value1(char*)>\0<value2(char*)>\0...
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina * if <error_code> is not SSS_SUDO_ERROR_OK, the rest of the data is skipped.
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinaint sudosrv_get_sudorules_build_response(TALLOC_CTX *mem_ctx,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint32_t error,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int rules_num,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina struct sysdb_attrs **rules,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint8_t **_response_body,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina size_t *_response_len)
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina{
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina uint8_t *response_body = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina size_t response_len = 0;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina TALLOC_CTX *tmp_ctx = NULL;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int i = 0;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina int ret = EOK;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina tmp_ctx = talloc_new(NULL);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (tmp_ctx == NULL) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ENOMEM;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* error code */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sudosrv_response_append_uint32(tmp_ctx, error,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina &response_body, &response_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret != EOK) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto fail;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (error != SSS_SUDO_ERROR_OK) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto done;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* rules count */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sudosrv_response_append_uint32(tmp_ctx, (uint32_t)rules_num,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina &response_body, &response_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret != EOK) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto fail;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina /* rules */
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina for (i = 0; i < rules_num; i++) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = sudosrv_response_append_rule(tmp_ctx, rules[i]->num, rules[i]->a,
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina &response_body, &response_len);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina if (ret != EOK) {
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina goto fail;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina }
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinadone:
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *_response_body = talloc_steal(mem_ctx, response_body);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina *_response_len = response_len;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina ret = EOK;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březinafail:
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina talloc_free(tmp_ctx);
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina return ret;
2827b0d03f7b6bafa504d22a5d7ca39cbda048b3Pavel Březina}