summaryrefslogtreecommitdiffstats
path: root/src/responder/sudo/sudosrv_dp.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
commit74aa0bc6779af38018a03fd2cf4419fe85917904 (patch)
tree9cb0681aac9a94a49c153d5823e7a55d1513d91f /src/responder/sudo/sudosrv_dp.c
parentInitial commit. (diff)
downloadsssd-74aa0bc6779af38018a03fd2cf4419fe85917904.tar.xz
sssd-74aa0bc6779af38018a03fd2cf4419fe85917904.zip
Adding upstream version 2.9.4.upstream/2.9.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/responder/sudo/sudosrv_dp.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c
new file mode 100644
index 0000000..465c0f2
--- /dev/null
+++ b/src/responder/sudo/sudosrv_dp.c
@@ -0,0 +1,265 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+ Jakub Hrozek <jhrozek@redhat.com>
+
+ Copyright (C) 2011 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <tevent.h>
+#include <dbus/dbus.h>
+
+#include "util/util.h"
+#include "providers/data_provider.h"
+#include "providers/data_provider_req.h"
+#include "responder/common/responder.h"
+#include "responder/sudo/sudosrv_private.h"
+#include "db/sysdb.h"
+#include "sss_iface/sss_iface_async.h"
+
+static DBusMessage *
+sss_dp_get_sudoers_msg(TALLOC_CTX *mem_ctx,
+ const char *bus_name,
+ struct sss_domain_info *dom,
+ bool fast_reply,
+ enum sss_dp_sudo_type type,
+ const char *name,
+ uint32_t num_rules,
+ struct sysdb_attrs **rules)
+{
+ DBusMessage *msg;
+ DBusMessageIter iter;
+ DBusMessageIter array_iter;
+ dbus_bool_t dbret;
+ errno_t ret;
+ uint32_t be_type = 0;
+ uint32_t dp_flags = 0;
+ const char *rule_name = NULL;
+ uint32_t i;
+
+ switch (type) {
+ case SSS_DP_SUDO_REFRESH_RULES:
+ be_type = BE_REQ_SUDO_RULES;
+ break;
+ case SSS_DP_SUDO_FULL_REFRESH:
+ be_type = BE_REQ_SUDO_FULL;
+ break;
+ }
+
+ if (fast_reply) {
+ dp_flags |= DP_FAST_REPLY;
+ }
+
+ msg = dbus_message_new_method_call(bus_name,
+ SSS_BUS_PATH,
+ "sssd.dataprovider",
+ "sudoHandler");
+ if (msg == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n");
+ return NULL;
+ }
+
+ /* create the message */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Creating SUDOers request for [%s][%u][%s][%u]\n",
+ dom->name, be_type, name, num_rules);
+
+ dbus_message_iter_init_append(msg, &iter);
+
+ dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &dp_flags);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+
+ /* BE TYPE */
+ dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &be_type);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+
+ /* BE TYPE SPECIFIC */
+ if (be_type & BE_REQ_SUDO_RULES) {
+ dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32,
+ &num_rules);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+
+ dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING,
+ &array_iter);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+
+ for (i = 0; i < num_rules; i++) {
+ ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &rule_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not get rule name [%d]: %s\n",
+ ret, strerror(ret));
+ goto fail;
+ }
+
+ dbret = dbus_message_iter_append_basic(&array_iter,
+ DBUS_TYPE_STRING,
+ &rule_name);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+ }
+
+ dbret = dbus_message_iter_close_container(&iter, &array_iter);
+ if (dbret == FALSE) {
+ goto fail;
+ }
+ }
+
+ return msg;
+
+fail:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n");
+ dbus_message_unref(msg);
+ return NULL;
+}
+
+struct sss_dp_get_sudoers_state {
+ uint16_t dp_error;
+ uint32_t error;
+ const char *error_message;
+};
+
+static void sss_dp_get_sudoers_done(struct tevent_req *subreq);
+
+struct tevent_req *
+sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx,
+ struct resp_ctx *rctx,
+ struct sss_domain_info *dom,
+ bool fast_reply,
+ enum sss_dp_sudo_type type,
+ const char *name,
+ uint32_t num_rules,
+ struct sysdb_attrs **rules)
+{
+ struct sss_dp_get_sudoers_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+ struct be_conn *be_conn;
+ DBusMessage *msg;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct sss_dp_get_sudoers_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
+ return NULL;
+ }
+
+ if (is_files_provider(dom)) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Domain %s does not check DP\n",
+ dom->name);
+ state->dp_error = DP_ERR_OK;
+ state->error = EOK;
+ state->error_message = talloc_strdup(state, "Success");
+ if (state->error_message == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = EOK;
+ goto done;
+ }
+
+ ret = sss_dp_get_domain_conn(rctx, dom->conn_name, &be_conn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "BUG: The Data Provider connection for %s is not available!\n",
+ dom->name);
+ ret = EIO;
+ goto done;
+ }
+
+ msg = sss_dp_get_sudoers_msg(state, be_conn->bus_name, dom, fast_reply,
+ type, name, num_rules, rules);
+ if (msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ subreq = sbus_call_dp_dp_sudoHandler_send(state, be_conn->conn, msg);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create subrequest!\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ tevent_req_set_callback(subreq, sss_dp_get_sudoers_done, req);
+
+ ret = EAGAIN;
+
+done:
+#ifdef BUILD_FILES_PROVIDER
+ if (ret == EOK) {
+ tevent_req_done(req);
+ tevent_req_post(req, rctx->ev);
+ } else
+#endif
+ if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, rctx->ev);
+ }
+
+ return req;
+}
+
+static void sss_dp_get_sudoers_done(struct tevent_req *subreq)
+{
+ struct sss_dp_get_sudoers_state *state;
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sss_dp_get_sudoers_state);
+
+ ret = sbus_call_dp_dp_sudoHandler_recv(state, subreq, &state->dp_error,
+ &state->error,
+ &state->error_message);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+ return;
+}
+
+errno_t
+sss_dp_get_sudoers_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ uint16_t *_dp_error,
+ uint32_t *_error,
+ const char ** _error_message)
+{
+ struct sss_dp_get_sudoers_state *state;
+ state = tevent_req_data(req, struct sss_dp_get_sudoers_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *_dp_error = state->dp_error;
+ *_error = state->error;
+ *_error_message = talloc_steal(mem_ctx, state->error_message);
+
+ return EOK;
+}