summaryrefslogtreecommitdiffstats
path: root/src/providers/ldap/sdap_sudo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers/ldap/sdap_sudo.c')
-rw-r--r--src/providers/ldap/sdap_sudo.c233
1 files changed, 128 insertions, 105 deletions
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 2ed97b9aa..bf73f7b45 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -29,13 +29,118 @@
#include "providers/ldap/sdap_sudo.h"
#include "db/sysdb_sudo.h"
-static void sdap_sudo_handler(struct be_req *breq);
-
-struct bet_ops sdap_sudo_ops = {
- .handler = sdap_sudo_handler,
- .finalize = NULL
+struct sdap_sudo_handler_state {
+ uint32_t type;
+ struct dp_reply_std reply;
};
+static void sdap_sudo_handler_done(struct tevent_req *subreq);
+
+static struct tevent_req *
+sdap_sudo_handler_send(TALLOC_CTX *mem_ctx,
+ struct sdap_sudo_ctx *sudo_ctx,
+ struct dp_sudo_data *data,
+ struct dp_req_params *params)
+{
+ struct sdap_sudo_handler_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_handler_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ state->type = data->type;
+
+ switch (data->type) {
+ case BE_REQ_SUDO_FULL:
+ DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
+ subreq = sdap_sudo_full_refresh_send(state, sudo_ctx);
+ break;
+ case BE_REQ_SUDO_RULES:
+ DEBUG(SSSDBG_TRACE_FUNC, "Issuing a refresh of specific sudo rules\n");
+ subreq = sdap_sudo_rules_refresh_send(state, sudo_ctx, data->rules);
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", data->type);
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request: %d\n", data->type);
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, sdap_sudo_handler_done, req);
+
+ return req;
+
+immediately:
+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
+
+ /* TODO For backward compatibility we always return EOK to DP now. */
+ tevent_req_done(req);
+ tevent_req_post(req, params->ev);
+
+ return req;
+}
+
+static void sdap_sudo_handler_done(struct tevent_req *subreq)
+{
+ struct sdap_sudo_handler_state *state;
+ struct tevent_req *req;
+ int dp_error;
+ bool deleted;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_sudo_handler_state);
+
+ switch (state->type) {
+ case BE_REQ_SUDO_FULL:
+ ret = sdap_sudo_full_refresh_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+ break;
+ case BE_REQ_SUDO_RULES:
+ ret = sdap_sudo_rules_refresh_recv(subreq, &dp_error, &deleted);
+ talloc_zfree(subreq);
+ if (ret == EOK && deleted == true) {
+ ret = ENOENT;
+ }
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", state->type);
+ dp_error = DP_ERR_FATAL;
+ ret = ERR_INTERNAL;
+ break;
+ }
+
+ /* TODO For backward compatibility we always return EOK to DP now. */
+ dp_reply_std_set(&state->reply, dp_error, ret, NULL);
+ tevent_req_done(req);
+}
+
+static errno_t
+sdap_sudo_handler_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ struct dp_reply_std *data)
+{
+ struct sdap_sudo_handler_state *state = NULL;
+
+ state = tevent_req_data(req, struct sdap_sudo_handler_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *data = state->reply;
+
+ return EOK;
+}
+
static void sdap_sudo_online_cb(void *pvt)
{
struct sdap_sudo_ctx *sudo_ctx;
@@ -51,43 +156,40 @@ static void sdap_sudo_online_cb(void *pvt)
sudo_ctx->run_hostinfo = true;
}
-int sdap_sudo_init(struct be_ctx *be_ctx,
- struct sdap_id_ctx *id_ctx,
- struct bet_ops **ops,
- void **pvt_data)
+errno_t sdap_sudo_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct sdap_id_ctx *id_ctx,
+ struct dp_method *dp_methods)
{
- struct sdap_sudo_ctx *sudo_ctx = NULL;
+ struct sdap_sudo_ctx *sudo_ctx;
int ret;
DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing sudo LDAP back end\n");
- sudo_ctx = talloc_zero(be_ctx, struct sdap_sudo_ctx);
+ sudo_ctx = talloc_zero(mem_ctx, struct sdap_sudo_ctx);
if (sudo_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc() failed\n");
return ENOMEM;
}
sudo_ctx->id_ctx = id_ctx;
- *ops = &sdap_sudo_ops;
- *pvt_data = sudo_ctx;
- ret = ldap_get_sudo_options(be_ctx->cdb,
- be_ctx->conf_path, id_ctx->opts,
+ ret = ldap_get_sudo_options(be_ctx->cdb, be_ctx->conf_path, id_ctx->opts,
&sudo_ctx->use_host_filter,
&sudo_ctx->include_regexp,
&sudo_ctx->include_netgroups);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot get SUDO options [%d]: %s\n",
- ret, strerror(ret));
+ ret, sss_strerror(ret));
goto done;
}
if (sudo_ctx->use_host_filter) {
- ret = be_add_online_cb(sudo_ctx, sudo_ctx->id_ctx->be,
- sdap_sudo_online_cb, sudo_ctx, NULL);
+ ret = be_add_online_cb(sudo_ctx, be_ctx, sdap_sudo_online_cb,
+ sudo_ctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Unable to install online callback "
- "[%d]: %s\n", ret, sss_strerror(ret));
+ "[%d]: %s\n", ret, sss_strerror(ret));
goto done;
}
@@ -95,15 +197,18 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
sudo_ctx->run_hostinfo = true;
}
- ret = sdap_sudo_ptask_setup(sudo_ctx->id_ctx->be, sudo_ctx);
+ ret = sdap_sudo_ptask_setup(be_ctx, sudo_ctx);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Unable to setup periodical refresh of sudo rules [%d]: %s\n",
- ret, strerror(ret));
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to setup periodical refresh of "
+ "sudo rules [%d]: %s\n", ret, sss_strerror(ret));
/* periodical updates will not work, but specific-rule update
* is no affected by this, therefore we don't have to fail here */
}
+ dp_set_method(dp_methods, DPM_SUDO_HANDLER,
+ sdap_sudo_handler_send, sdap_sudo_handler_recv, sudo_ctx,
+ struct sdap_sudo_ctx, struct dp_sudo_data, struct dp_reply_std);
+
ret = EOK;
done:
@@ -113,85 +218,3 @@ done:
return ret;
}
-
-static void sdap_sudo_reply(struct tevent_req *req)
-{
- struct be_req *be_req = NULL;
- struct be_sudo_req *sudo_req = NULL;
- int dp_error;
- bool deleted;
- int ret;
-
- be_req = tevent_req_callback_data(req, struct be_req);
- sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req);
-
- switch (sudo_req->type) {
- case BE_REQ_SUDO_FULL:
- ret = sdap_sudo_full_refresh_recv(req, &dp_error);
- break;
- case BE_REQ_SUDO_RULES:
- ret = sdap_sudo_rules_refresh_recv(req, &dp_error, &deleted);
- if (ret == EOK && deleted == true) {
- ret = ENOENT;
- }
- break;
- default:
- DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n",
- sudo_req->type);
- dp_error = DP_ERR_FATAL;
- ret = ERR_INTERNAL;
- break;
- }
-
- talloc_zfree(req);
- sdap_handler_done(be_req, dp_error, ret, strerror(ret));
-}
-
-static void sdap_sudo_handler(struct be_req *be_req)
-{
- struct be_ctx *be_ctx = be_req_get_be_ctx(be_req);
- struct tevent_req *req = NULL;
- struct be_sudo_req *sudo_req = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
- int ret = EOK;
-
- if (be_is_offline(be_ctx)) {
- sdap_handler_done(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline");
- return;
- }
-
- sudo_ctx = talloc_get_type(be_ctx->bet_info[BET_SUDO].pvt_bet_data,
- struct sdap_sudo_ctx);
-
- sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req);
-
- switch (sudo_req->type) {
- case BE_REQ_SUDO_FULL:
- DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
- req = sdap_sudo_full_refresh_send(be_req, sudo_ctx);
- break;
- case BE_REQ_SUDO_RULES:
- DEBUG(SSSDBG_TRACE_FUNC, "Issuing a refresh of specific sudo rules\n");
- req = sdap_sudo_rules_refresh_send(be_req, sudo_ctx, sudo_req->rules);
- break;
- default:
- DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n",
- sudo_req->type);
- ret = EINVAL;
- goto fail;
- }
-
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request: %d\n",
- sudo_req->type);
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(req, sdap_sudo_reply, be_req);
-
- return;
-
-fail:
- sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL);
-}