summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-01-23 13:32:22 +0100
committerStephen Gallagher <sgallagh@redhat.com>2012-01-27 09:10:37 -0500
commit7a571a9d9be35360cc0f283fcd8124bda11ebf51 (patch)
treeba0c4e9d911b116521f90ffa4132a0a6dd5b94fd
parentf6171b2bc954a367f316853ab71090eb213bdee3 (diff)
downloadsssd-7a571a9d9be35360cc0f283fcd8124bda11ebf51.tar.gz
sssd-7a571a9d9be35360cc0f283fcd8124bda11ebf51.tar.bz2
sssd-7a571a9d9be35360cc0f283fcd8124bda11ebf51.zip
SUDO Integration - prepare data provider for new responder commands
https://fedorahosted.org/sssd/ticket/1143
-rw-r--r--src/providers/data_provider.h16
-rw-r--r--src/providers/data_provider_be.c143
-rw-r--r--src/providers/dp_backend.h3
-rw-r--r--src/providers/ldap/sdap_sudo.c278
-rw-r--r--src/providers/ldap/sdap_sudo.h19
-rw-r--r--src/providers/ldap/sdap_sudo_timer.c26
-rw-r--r--src/responder/sudo/sudosrv_dp.c2
7 files changed, 287 insertions, 200 deletions
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index eb4f98cf..627085b0 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -132,13 +132,15 @@
#define BE_FILTER_IDNUM 2
#define BE_FILTER_ENUM 3
-#define BE_REQ_USER 0x0001
-#define BE_REQ_GROUP 0x0002
-#define BE_REQ_INITGROUPS 0x0003
-#define BE_REQ_NETGROUP 0x0004
-#define BE_REQ_SERVICES 0x0005
-#define BE_REQ_SUDO 0x0006
-#define BE_REQ_FAST 0x1000
+#define BE_REQ_USER 0x0001
+#define BE_REQ_GROUP 0x0002
+#define BE_REQ_INITGROUPS 0x0003
+#define BE_REQ_NETGROUP 0x0004
+#define BE_REQ_SERVICES 0x0005
+#define BE_REQ_SUDO_ALL 0x0006
+#define BE_REQ_SUDO_DEFAULTS 0x0007
+#define BE_REQ_SUDO_USER 0x0008
+#define BE_REQ_FAST 0x1000
/* AUTH related common data and functions */
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 801dbd5f..9965e52f 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -633,45 +633,48 @@ done:
return EOK;
}
-static void be_sudo_handler_callback(struct be_req *req,
- int dp_err_type,
- int errnum,
- const char *errstr)
+static void be_sudo_handler_reply(struct sbus_connection *conn,
+ DBusMessage *reply,
+ dbus_uint16_t dp_err,
+ dbus_uint32_t dp_ret,
+ const char *errstr)
{
- DBusMessage *reply = NULL;
DBusConnection *dbus_conn = NULL;
dbus_bool_t dbret;
- dbus_uint16_t err_maj = 0;
- dbus_uint32_t err_min = 0;
const char *err_msg = NULL;
- reply = (DBusMessage*)(req->pvt);
-
- err_maj = dp_err_type;
- err_min = errnum;
- err_msg = errstr ? errstr : talloc_strdup(req, "No errmsg set\n");
- if (!err_msg) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to set err_msg\n"));
- err_msg = "OOM";
+ if (reply == NULL) {
+ return;
}
+ err_msg = errstr ? errstr : "No errmsg set\n";
dbret = dbus_message_append_args(reply,
- DBUS_TYPE_UINT16, &err_maj,
- DBUS_TYPE_UINT32, &err_min,
+ DBUS_TYPE_UINT16, &dp_err,
+ DBUS_TYPE_UINT32, &dp_ret,
DBUS_TYPE_STRING, &err_msg,
DBUS_TYPE_INVALID);
if (!dbret) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to generate dbus reply\n"));
- talloc_free(req);
return;
}
DEBUG(SSSDBG_FUNC_DATA, ("SUDO Backend returned: (%d, %d, %s)\n",
- dp_err_type, errnum, errstr ? errstr : "<NULL>"));
+ dp_err, dp_ret, errstr ? errstr : "<NULL>"));
- dbus_conn = sbus_get_connection(req->becli->conn);
+ dbus_conn = sbus_get_connection(conn);
dbus_connection_send(dbus_conn, reply, NULL);
dbus_message_unref(reply);
+}
+
+static void be_sudo_handler_callback(struct be_req *req,
+ int dp_err,
+ int dp_ret,
+ const char *errstr)
+{
+ DBusMessage *reply = NULL;
+ reply = (DBusMessage*)(req->pvt);
+
+ be_sudo_handler_reply(req->becli->conn, reply, dp_err, dp_ret, errstr);
talloc_free(req);
}
@@ -682,13 +685,12 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn)
DBusMessage *reply = NULL;
struct be_client *be_cli = NULL;
struct be_req *be_req = NULL;
- struct be_sudo_req *be_sudo_req = NULL;
+ struct be_sudo_req *sudo_req = NULL;
void *user_data = NULL;
int ret = 0;
uint32_t type;
char *filter;
const char *err_msg = NULL;
- char *filter_val;
DEBUG(SSSDBG_TRACE_FUNC, ("Entering be_sudo_handler()\n"));
@@ -709,19 +711,7 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn)
return ENOMEM;
}
- /* create be request */
- be_req = talloc_zero(be_cli, struct be_req);
- if (be_req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
- dbus_message_unref(reply);
- return ENOMEM;
- }
-
- be_req->becli = be_cli;
- be_req->be_ctx = be_cli->bectx;
- be_req->pvt = reply;
- be_req->fn = be_sudo_handler_callback;
-
+ /* get arguments */
dbus_error_init(&dbus_error);
ret = dbus_message_get_args(message, &dbus_error,
@@ -736,41 +726,78 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn)
goto fail;
}
- if (type != BE_REQ_SUDO) {
- /* No other are supported at the moment */
- ret = EINVAL;
- err_msg = "Invalid DP request type";
- goto fail;
+
+ /* If we are offline and fast reply was requested
+ * return offline immediately
+ */
+ if ((type & BE_REQ_FAST) && be_cli->bectx->offstat.offline) {
+ be_sudo_handler_reply(conn, reply, DP_ERR_OFFLINE, EAGAIN,
+ "Fast reply - offline");
+ reply = NULL;
+ /* This reply will be queued and sent
+ * when we reenter the mainloop.
+ *
+ * Continue processing in case we are
+ * going back online.
+ */
}
- if (filter) {
- if (strncmp(filter, "name=", 5) == 0) {
- filter_val = &filter[5];
- } else {
- ret = EINVAL;
- err_msg = "Invalid Filter";
- goto fail;
- }
- } else {
- ret = EINVAL;
- err_msg = "Missing Filter Parameter";
- goto fail;
+ /* create be request */
+ be_req = talloc_zero(be_cli, struct be_req);
+ if (be_req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
+ dbus_message_unref(reply);
+ return ENOMEM;
}
+ be_req->becli = be_cli;
+ be_req->be_ctx = be_cli->bectx;
+ be_req->pvt = reply;
+ be_req->fn = be_sudo_handler_callback;
+
/* get and set sudo request data */
- be_sudo_req = talloc_zero(be_req, struct be_sudo_req);
- if (be_sudo_req == NULL) {
+ sudo_req = talloc_zero(be_req, struct be_sudo_req);
+ if (sudo_req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
goto fail;
}
- be_sudo_req->username = talloc_strdup(be_sudo_req, filter_val);
- if (be_sudo_req->username == NULL) {
- ret = ENOMEM;
+ sudo_req->type = (~BE_REQ_FAST) & type;
+ sudo_req->uid = 0;
+ sudo_req->groups = NULL;
+
+ switch (sudo_req->type) {
+ case BE_REQ_SUDO_ALL:
+ case BE_REQ_SUDO_DEFAULTS:
+ sudo_req->username = NULL;
+ break;
+ case BE_REQ_SUDO_USER:
+ if (filter) {
+ if (strncmp(filter, "name=", 5) == 0) {
+ sudo_req->username = talloc_strdup(sudo_req, &filter[5]);
+ if (sudo_req->username == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ } else {
+ ret = EINVAL;
+ err_msg = "Invalid Filter";
+ goto fail;
+ }
+ } else {
+ ret = EINVAL;
+ err_msg = "Missing Filter Parameter";
+ goto fail;
+ }
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type %d\n", sudo_req->type));
+ ret = EINVAL;
+ err_msg = "Invalid DP request type";
goto fail;
}
- be_req->req_data = be_sudo_req;
+ be_req->req_data = sudo_req;
/* return an error if corresponding backend target is not configured */
if (!be_cli->bectx->bet_info[BET_SUDO].bet_ops) {
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 33ca37ce..0964110a 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -147,7 +147,10 @@ struct be_acct_req {
};
struct be_sudo_req {
+ uint32_t type;
char *username;
+ uid_t uid;
+ char **groups;
};
bool be_is_offline(struct be_ctx *ctx);
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index ea90bb7e..aed937f9 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -46,47 +46,66 @@ struct sdap_sudo_load_sudoers_state {
};
struct sdap_sudo_refresh_state {
- struct sdap_sudo_ctx *sudo_ctx;
+ struct be_ctx *be_ctx;
+ struct be_sudo_req *sudo_req;
+ struct sdap_options *opts;
+ struct sdap_id_op *sdap_op;
+ struct sdap_id_conn_cache *sdap_conn_cache;
+
int dp_error;
int error;
};
static int sdap_sudo_connect(struct tevent_req *req);
+
static void sdap_sudo_connect_done(struct tevent_req *subreq);
static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
- struct sdap_sudo_ctx *sudo_ctx);
+ struct tevent_context *ev,
+ struct be_sudo_req *sudo_req,
+ struct sdap_options *opts,
+ struct sdap_handle *sh);
+
static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req);
+
static void sdap_sudo_load_sudoers_process(struct tevent_req *subreq);
+
static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *rules_count,
struct sysdb_attrs ***rules);
+
static void sdap_sudo_load_sudoers_done(struct tevent_req *req);
-static int sdap_sudo_purge_sudoers(struct sdap_sudo_ctx *sudo_ctx);
-static int sdap_sudo_store_sudoers(struct sdap_sudo_ctx *sudo_ctx,
- size_t replies_count,
- struct sysdb_attrs **replies);
+static int sdap_sudo_purge_sudoers(struct sysdb_ctx *sysdb_ctx,
+ struct sss_domain_info *domain,
+ struct be_sudo_req *sudo_req);
-const char *sdap_sudo_build_filter(TALLOC_CTX *mem_ctx,
- struct sdap_attr_map *map,
- const char *username,
- uid_t uid,
- char **groups);
+static int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx,
+ struct sdap_options *opts,
+ size_t rules_count,
+ struct sysdb_attrs **rules);
+
+static const char *sdap_sudo_build_filter(TALLOC_CTX *mem_ctx,
+ struct sdap_attr_map *map,
+ struct be_sudo_req *sudo_req);
+
+static const char *sdap_sudo_build_user_filter(TALLOC_CTX *mem_ctx,
+ struct sdap_attr_map *map,
+ const char *username,
+ uid_t uid,
+ char **groups);
static void sdap_sudo_reply(struct tevent_req *req)
{
struct be_req *be_req = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
int dp_error;
int error;
int ret;
be_req = tevent_req_callback_data(req, struct be_req);
- ret = sdap_sudo_refresh_recv(req, &sudo_ctx, &dp_error, &error);
+ ret = sdap_sudo_refresh_recv(req, &dp_error, &error);
talloc_zfree(req);
- talloc_zfree(sudo_ctx);
if (ret != EOK) {
sdap_handler_done(be_req, DP_ERR_FATAL, ret, strerror(ret));
return;
@@ -98,7 +117,6 @@ static void sdap_sudo_reply(struct tevent_req *req)
void sdap_sudo_handler(struct be_req *be_req)
{
struct tevent_req *req = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
struct be_sudo_req *sudo_req = NULL;
struct sdap_id_ctx *id_ctx = NULL;
int ret = EOK;
@@ -108,35 +126,23 @@ void sdap_sudo_handler(struct be_req *be_req)
sudo_req = talloc_get_type(be_req->req_data, struct be_sudo_req);
- sudo_ctx = talloc_zero(be_req, struct sdap_sudo_ctx);
- if (!sudo_ctx) {
- ret = ENOMEM;
- goto fail;
- }
-
- sudo_ctx->be_ctx = id_ctx->be;
- sudo_ctx->be_req = be_req;
- sudo_ctx->sdap_ctx = id_ctx;
- sudo_ctx->sdap_op = NULL;
- sudo_ctx->sdap_conn_cache = id_ctx->conn_cache;
-
/* get user info */
- sudo_ctx->username = sudo_req->username;
- if (sudo_ctx->username != NULL) {
- ret = sysdb_get_sudo_user_info(sudo_ctx, sudo_ctx->username,
- sudo_ctx->be_ctx->sysdb,
- &sudo_ctx->uid, &sudo_ctx->groups);
+ if (sudo_req->username != NULL) {
+ ret = sysdb_get_sudo_user_info(sudo_req, sudo_req->username,
+ id_ctx->be->sysdb,
+ &sudo_req->uid, &sudo_req->groups);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to get uid and groups of %s\n",
- sudo_ctx->username));
+ sudo_req->username));
goto fail;
}
} else {
- sudo_ctx->uid = 0;
- sudo_ctx->groups = NULL;
+ sudo_req->uid = 0;
+ sudo_req->groups = NULL;
}
- req = sdap_sudo_refresh_send(sudo_ctx, sudo_ctx);
+ req = sdap_sudo_refresh_send(be_req, id_ctx->be, sudo_req, id_ctx->opts,
+ id_ctx->conn_cache);
if (req == NULL) {
ret = ENOMEM;
goto fail;
@@ -147,12 +153,14 @@ void sdap_sudo_handler(struct be_req *be_req)
return;
fail:
- talloc_free(sudo_ctx);
sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL);
}
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
- struct sdap_sudo_ctx *sudo_ctx)
+ struct be_ctx *be_ctx,
+ struct be_sudo_req *sudo_req,
+ struct sdap_options *opts,
+ struct sdap_id_conn_cache *conn_cache)
{
struct tevent_req *req = NULL;
struct sdap_sudo_refresh_state *state = NULL;
@@ -163,12 +171,30 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- state->sudo_ctx = sudo_ctx;
+ state->be_ctx = be_ctx;
+ state->sudo_req = sudo_req;
+ state->opts = opts;
+ state->sdap_op = NULL;
+ state->sdap_conn_cache = conn_cache;
state->dp_error = DP_ERR_OK;
state->error = EOK;
- DEBUG(SSSDBG_FUNC_DATA, ("Requested refresh for: %s\n",
- sudo_ctx->username ? sudo_ctx->username : "<ALL>\n"));
+ switch (sudo_req->type) {
+ case BE_REQ_SUDO_ALL:
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requested refresh for: <ALL>\n"));
+ break;
+ case BE_REQ_SUDO_DEFAULTS:
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requested refresh of cn=defaults\n"));
+ break;
+ case BE_REQ_SUDO_USER:
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requested refresh for: %s\n",
+ sudo_req->username));
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type %d\n", sudo_req->type));
+ ret = EINVAL;
+ goto immediately;
+ }
ret = sdap_sudo_connect(req);
if (ret == EAGAIN) {
@@ -176,18 +202,18 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
return req;
}
+immediately:
if (ret == EOK) {
tevent_req_done(req);
} else {
tevent_req_error(req, ret);
}
- tevent_req_post(req, sudo_ctx->be_ctx->ev);
+ tevent_req_post(req, be_ctx->ev);
return req;
}
int sdap_sudo_refresh_recv(struct tevent_req *req,
- struct sdap_sudo_ctx **sudo_ctx,
int *dp_error,
int *error)
{
@@ -197,7 +223,6 @@ int sdap_sudo_refresh_recv(struct tevent_req *req,
TEVENT_REQ_RETURN_ON_ERROR(req);
- *sudo_ctx = state->sudo_ctx;
*dp_error = state->dp_error;
*error = state->error;
@@ -208,22 +233,19 @@ int sdap_sudo_connect(struct tevent_req *req)
{
struct tevent_req *subreq = NULL;
struct sdap_sudo_refresh_state *state = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
int ret;
state = tevent_req_data(req, struct sdap_sudo_refresh_state);
- sudo_ctx = state->sudo_ctx;
- if (be_is_offline(sudo_ctx->be_ctx)) {
+ if (be_is_offline(state->be_ctx)) {
state->dp_error = DP_ERR_OFFLINE;
state->error = EAGAIN;
return EOK;
}
- if (sudo_ctx->sdap_op == NULL) {
- sudo_ctx->sdap_op = sdap_id_op_create(sudo_ctx,
- sudo_ctx->sdap_conn_cache);
- if (sudo_ctx->sdap_op == NULL) {
+ if (state->sdap_op == NULL) {
+ state->sdap_op = sdap_id_op_create(state, state->sdap_conn_cache);
+ if (state->sdap_op == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("sdap_id_op_create() failed\n"));
state->dp_error = DP_ERR_FATAL;
state->error = EIO;
@@ -231,11 +253,11 @@ int sdap_sudo_connect(struct tevent_req *req)
}
}
- subreq = sdap_id_op_connect_send(sudo_ctx->sdap_op, sudo_ctx, &ret);
+ subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
("sdap_id_op_connect_send() failed: %d(%s)\n", ret, strerror(ret)));
- talloc_zfree(sudo_ctx->sdap_op);
+ talloc_zfree(state->sdap_op);
state->dp_error = DP_ERR_FATAL;
state->error = ret;
return ret;
@@ -250,19 +272,17 @@ void sdap_sudo_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL; /* req from sdap_sudo_refresh_send() */
struct sdap_sudo_refresh_state *state = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
int dp_error;
int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_refresh_state);
- sudo_ctx = state->sudo_ctx;
ret = sdap_id_op_connect_recv(subreq, &dp_error);
talloc_zfree(subreq);
if (dp_error == DP_ERR_OFFLINE) {
- talloc_zfree(sudo_ctx->sdap_op);
+ talloc_zfree(state->sdap_op);
state->dp_error = DP_ERR_OFFLINE;
state->error = EAGAIN;
tevent_req_done(req);
@@ -275,7 +295,9 @@ void sdap_sudo_connect_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, ("SUDO LDAP connection successful\n"));
- subreq = sdap_sudo_load_sudoers_send(sudo_ctx, sudo_ctx);
+ subreq = sdap_sudo_load_sudoers_send(state, state->be_ctx->ev,
+ state->sudo_req, state->opts,
+ sdap_id_op_handle(state->sdap_op));
if (subreq == NULL) {
ret = EFAULT;
goto fail;
@@ -292,7 +314,13 @@ fail:
}
struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
- struct sdap_sudo_ctx *sudo_ctx)
+ struct tevent_context *ev,
+ struct be_sudo_req *sudo_req,
+ struct sdap_options *opts,
+ struct sdap_handle *sh)
+
+
+
{
struct tevent_req *req = NULL;
struct sdap_sudo_load_sudoers_state *state = NULL;
@@ -303,29 +331,24 @@ struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- state->ev = sudo_ctx->be_ctx->ev;
- state->sudo_ctx = sudo_ctx;
- state->opts = sudo_ctx->sdap_ctx->opts;
- state->sh = sdap_id_op_handle(sudo_ctx->sdap_op);
+ state->ev = ev;
+ state->opts = opts;
+ state->sh = sh;
state->base_iter = 0;
- state->search_bases = state->opts->sudo_search_bases;
- state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
+ state->search_bases = opts->sudo_search_bases;
+ state->timeout = dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT);
state->ldap_rules = NULL;
state->ldap_rules_count = 0;
/* create filter */
- state->filter = sdap_sudo_build_filter(state,
- state->opts->sudorule_map,
- sudo_ctx->username,
- sudo_ctx->uid,
- sudo_ctx->groups);
+ state->filter = sdap_sudo_build_filter(state, opts->sudorule_map, sudo_req);
if (state->filter == NULL) {
goto fail;
}
/* create attrs from map */
- ret = build_attrs_from_map(state, state->opts->sudorule_map,
- SDAP_OPTS_SUDO, &state->attrs);
+ ret = build_attrs_from_map(state, opts->sudorule_map, SDAP_OPTS_SUDO,
+ &state->attrs);
if (ret != EOK) {
goto fail;
}
@@ -334,7 +357,7 @@ struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
ret = sdap_sudo_load_sudoers_next_base(req);
if (ret != EOK) {
tevent_req_error(req, ret);
- tevent_req_post(req, sudo_ctx->be_ctx->ev);
+ tevent_req_post(req, ev);
}
return req;
@@ -470,16 +493,14 @@ void sdap_sudo_load_sudoers_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL; /* req from sdap_sudo_refresh_send() */
struct sdap_sudo_refresh_state *state = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
struct sysdb_attrs **rules = NULL;
size_t rules_count;
int ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_refresh_state);
- sudo_ctx = state->sudo_ctx;
- ret = sdap_sudo_load_sudoers_recv(subreq, sudo_ctx, &rules_count, &rules);
+ ret = sdap_sudo_load_sudoers_recv(subreq, state, &rules_count, &rules);
talloc_zfree(subreq);
if (ret != EOK) {
goto done;
@@ -488,13 +509,15 @@ void sdap_sudo_load_sudoers_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, ("Received %d rules\n", rules_count));
/* purge cache */
- ret = sdap_sudo_purge_sudoers(sudo_ctx);
+ ret = sdap_sudo_purge_sudoers(state->be_ctx->sysdb, state->be_ctx->domain,
+ state->sudo_req);
if (ret != EOK) {
goto done;
}
/* store rules */
- ret = sdap_sudo_store_sudoers(sudo_ctx, rules_count, rules);
+ ret = sdap_sudo_store_sudoers(state->be_ctx->sysdb, state->opts,
+ rules_count, rules);
if (ret != EOK) {
goto done;
}
@@ -514,42 +537,67 @@ done:
}
}
-int sdap_sudo_purge_sudoers(struct sdap_sudo_ctx *sudo_ctx)
+int sdap_sudo_purge_sudoers(struct sysdb_ctx *sysdb_ctx,
+ struct sss_domain_info *domain,
+ struct be_sudo_req *sudo_req)
{
- struct sysdb_ctx *sysdb_ctx = sudo_ctx->be_ctx->sysdb;
+ TALLOC_CTX *tmp_ctx;
char *filter = NULL;
- int ret;
+ int ret = EOK;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
+ return ENOMEM;
+ }
- if (sudo_ctx->username != NULL) {
- ret = sysdb_get_sudo_filter(sudo_ctx, sudo_ctx->username, sudo_ctx->uid,
- sudo_ctx->groups, SYSDB_SUDO_FILTER_NGRS
+ switch (sudo_req->type) {
+ case BE_REQ_SUDO_ALL:
+ filter = NULL;
+ break;
+ case BE_REQ_SUDO_DEFAULTS:
+ ret = sysdb_get_sudo_filter(tmp_ctx, NULL, 0, NULL,
+ SYSDB_SUDO_FILTER_INCLUDE_DFL, &filter);
+ break;
+ case BE_REQ_SUDO_USER:
+ ret = sysdb_get_sudo_filter(tmp_ctx, sudo_req->username, sudo_req->uid,
+ sudo_req->groups,
+ SYSDB_SUDO_FILTER_USERINFO
| SYSDB_SUDO_FILTER_INCLUDE_ALL
| SYSDB_SUDO_FILTER_INCLUDE_DFL, &filter);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create filter to purge "
- "sudoers cache [%d]: %s\n", ret, strerror(ret)));
- return ret;
- }
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type %d\n", sudo_req->type));
+ return EINVAL;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create filter to purge "
+ "sudoers cache [%d]: %s\n", ret, strerror(ret)));
+ goto done;
}
/* Purge rules */
DEBUG(SSSDBG_TRACE_FUNC, ("Purging sudo cache with filter [%s]\n", filter));
- ret = sysdb_purge_sudorule_subtree(sysdb_ctx, sudo_ctx->be_ctx->domain,
- filter);
+ ret = sysdb_purge_sudorule_subtree(sysdb_ctx, domain, filter);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to purge sudoers cache [%d]: %s\n",
ret, strerror(ret)));
- return ret;
+ goto done;
}
- return EOK;
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
}
-int sdap_sudo_store_sudoers(struct sdap_sudo_ctx *sudo_ctx,
+int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx,
+ struct sdap_options *opts,
size_t rules_count,
struct sysdb_attrs **rules)
{
- struct sysdb_ctx *sysdb_ctx = sudo_ctx->be_ctx->sysdb;
errno_t ret;
/* Empty sudoers? Done. */
@@ -557,8 +605,7 @@ int sdap_sudo_store_sudoers(struct sdap_sudo_ctx *sudo_ctx,
return EOK;
}
- ret = sdap_save_native_sudorule_list(sysdb_ctx,
- sudo_ctx->sdap_ctx->opts->sudorule_map,
+ ret = sdap_save_native_sudorule_list(sysdb_ctx, opts->sudorule_map,
rules, rules_count);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("failed to save sudo rules [%d]: %s\n",
@@ -569,12 +616,38 @@ int sdap_sudo_store_sudoers(struct sdap_sudo_ctx *sudo_ctx,
return EOK;
}
-/* alway update cn=defaults and sudoUser=ALL */
const char *sdap_sudo_build_filter(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map,
- const char *username,
- uid_t uid,
- char **groups)
+ struct be_sudo_req *sudo_req)
+{
+ switch (sudo_req->type) {
+ case BE_REQ_SUDO_ALL:
+ return talloc_asprintf(mem_ctx, SDAP_SUDO_FILTER_ALL,
+ map[SDAP_OC_SUDORULE].name);
+ break;
+ case BE_REQ_SUDO_DEFAULTS:
+ return talloc_asprintf(mem_ctx, SDAP_SUDO_FILTER_DEFAULTS,
+ map[SDAP_OC_SUDORULE].name,
+ map[SDAP_AT_SUDO_NAME].name,
+ SDAP_SUDO_DEFAULTS); /* FIXME: add option for this */
+ break;
+ case BE_REQ_SUDO_USER:
+ return sdap_sudo_build_user_filter(mem_ctx, map, sudo_req->username,
+ sudo_req->uid, sudo_req->groups);
+
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type %d\n", sudo_req->type));
+ return NULL;
+ }
+}
+
+/* alway update cn=defaults and sudoUser=ALL */
+const char *sdap_sudo_build_user_filter(TALLOC_CTX *mem_ctx,
+ struct sdap_attr_map *map,
+ const char *username,
+ uid_t uid,
+ char **groups)
{
char *filter = NULL;
char *output = NULL;
@@ -582,11 +655,6 @@ const char *sdap_sudo_build_filter(TALLOC_CTX *mem_ctx,
char **group = NULL;
int ret;
- if (username == NULL) {
- return talloc_asprintf(mem_ctx, SDAP_SUDO_FILTER_ALL,
- map[SDAP_OC_SUDORULE].name);
- }
-
/* user name */
ret = sss_filter_sanitize(filter, username, &sanitized);
if (ret != EOK) {
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index 1e53c117..b0e66089 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -21,29 +21,20 @@
#ifndef _SDAP_SUDO_H_
#define _SDAP_SUDO_H_
-struct sdap_sudo_ctx {
- struct be_ctx *be_ctx;
- struct be_req *be_req;
- struct sdap_id_ctx *sdap_ctx;
- struct sdap_id_op *sdap_op;
- struct sdap_id_conn_cache *sdap_conn_cache;
-
- const char *username;
- uint_t uid;
- char **groups;
-};
-
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
- struct sdap_sudo_ctx *sudo_ctx);
+ struct be_ctx *be_ctx,
+ struct be_sudo_req *sudo_req,
+ struct sdap_options *opts,
+ struct sdap_id_conn_cache *conn_cache);
int sdap_sudo_refresh_recv(struct tevent_req *req,
- struct sdap_sudo_ctx **sudo_ctx,
int *dp_error,
int *error);
/* (&(objectClass=sudoRole)(|(cn=defaults)(sudoUser=ALL)%s)) */
#define SDAP_SUDO_FILTER_USER "(&(objectClass=%s)(|(%s=%s)(%s=ALL)%s))"
#define SDAP_SUDO_FILTER_ALL "(objectClass=%s)"
+#define SDAP_SUDO_FILTER_DEFAULTS "(&(objectClass=%s)(%s=%s))"
#define SDAP_SUDO_DEFAULTS "defaults"
#define SDAP_SUDO_FILTER_USERNAME "(%s=%s)"
diff --git a/src/providers/ldap/sdap_sudo_timer.c b/src/providers/ldap/sdap_sudo_timer.c
index cc664abf..81b6ae88 100644
--- a/src/providers/ldap/sdap_sudo_timer.c
+++ b/src/providers/ldap/sdap_sudo_timer.c
@@ -92,7 +92,7 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
struct timeval tv, void *pvt)
{
struct sdap_sudo_refresh_ctx *refresh_ctx = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
+ struct be_sudo_req *sudo_req = NULL;
struct tevent_timer *timeout = NULL;
struct tevent_req *req = NULL;
int delay = 0;
@@ -113,8 +113,8 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
}
/* create sudo context */
- sudo_ctx = talloc_zero(refresh_ctx, struct sdap_sudo_ctx);
- if (sudo_ctx == NULL) {
+ sudo_req = talloc_zero(refresh_ctx, struct be_sudo_req);
+ if (sudo_req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero() failed!\n"));
tv = tevent_timeval_current_ofs(delay, 0);
ret = sdap_sudo_refresh_set_timer(refresh_ctx, tv);
@@ -125,17 +125,13 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
return;
}
- sudo_ctx->be_ctx = refresh_ctx->be_ctx;
- sudo_ctx->be_req = NULL;
- sudo_ctx->sdap_ctx = refresh_ctx->id_ctx;
- sudo_ctx->sdap_op = NULL;
- sudo_ctx->sdap_conn_cache = refresh_ctx->id_ctx->conn_cache;
- sudo_ctx->username = NULL; /* download all rules */
- sudo_ctx->uid = 0;
- sudo_ctx->groups = NULL;
+ sudo_req->type = BE_REQ_SUDO_ALL;
+ sudo_req->username = NULL;
/* send request */
- req = sdap_sudo_refresh_send(sudo_ctx, sudo_ctx);
+ req = sdap_sudo_refresh_send(refresh_ctx, refresh_ctx->id_ctx->be, sudo_req,
+ refresh_ctx->id_ctx->opts,
+ refresh_ctx->id_ctx->conn_cache);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to schedule refresh of SUDO rules, "
"retrying later!\n"));
@@ -145,9 +141,11 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
DEBUG(SSSDBG_CRIT_FAILURE, ("Error setting up SUDO refresh timer\n"));
}
+ talloc_free(sudo_req);
return;
}
refresh_ctx->last_refresh = tevent_timeval_current();
+ talloc_steal(req, sudo_req); /* make it free with req */
tevent_req_set_callback(req, sdap_sudo_refresh_reschedule, refresh_ctx);
@@ -178,7 +176,6 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
static void sdap_sudo_refresh_reschedule(struct tevent_req *req)
{
struct sdap_sudo_refresh_ctx *refresh_ctx = NULL;
- struct sdap_sudo_ctx *sudo_ctx = NULL;
struct timeval tv;
int delay;
int dp_error;
@@ -186,9 +183,8 @@ static void sdap_sudo_refresh_reschedule(struct tevent_req *req)
int ret;
refresh_ctx = tevent_req_callback_data(req, struct sdap_sudo_refresh_ctx);
- ret = sdap_sudo_refresh_recv(req, &sudo_ctx, &dp_error, &error);
+ ret = sdap_sudo_refresh_recv(req, &dp_error, &error);
talloc_zfree(req);
- talloc_zfree(sudo_ctx);
if (ret != EOK) {
tv = tevent_timeval_current();
} else {
diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c
index fd6ce4e5..4002955b 100644
--- a/src/responder/sudo/sudosrv_dp.c
+++ b/src/responder/sudo/sudosrv_dp.c
@@ -102,7 +102,7 @@ sss_dp_get_sudoers_msg(void *pvt)
DBusMessage *msg;
dbus_bool_t dbret;
struct sss_dp_get_sudoers_info *info;
- uint32_t be_type = BE_REQ_SUDO;
+ uint32_t be_type = BE_REQ_SUDO_USER;
char *filter;
info = talloc_get_type(pvt, struct sss_dp_get_sudoers_info);