summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-04-23 13:22:25 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-06-29 11:37:16 -0400
commit751a7930d5af7c1a3c36936e3c5b9205189c6b92 (patch)
tree046dc858e08c25e1d5e5dce4a7ff99e4b1ca0d09
parent0ca19d792b717456f334abdf35279acddf6d71c2 (diff)
downloadsssd-751a7930d5af7c1a3c36936e3c5b9205189c6b92.tar.gz
sssd-751a7930d5af7c1a3c36936e3c5b9205189c6b92.tar.xz
sssd-751a7930d5af7c1a3c36936e3c5b9205189c6b92.zip
sudo ldap provider: give sdap_sudo_refresh_send() search and purge filters
-rw-r--r--src/providers/ldap/sdap_async_sudo.c357
-rw-r--r--src/providers/ldap/sdap_sudo.c4
-rw-r--r--src/providers/ldap/sdap_sudo.h5
-rw-r--r--src/providers/ldap/sdap_sudo_timer.c5
4 files changed, 93 insertions, 278 deletions
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index d24420a23..5051110d6 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -34,13 +34,25 @@
#include "providers/ldap/sdap_sudo_cache.h"
#include "db/sysdb_sudo.h"
+struct sdap_sudo_refresh_state {
+ struct be_ctx *be_ctx;
+ struct sdap_options *opts;
+ struct sdap_id_op *sdap_op;
+ struct sdap_id_conn_cache *sdap_conn_cache;
+
+ const char *ldap_filter; /* search */
+ const char *sysdb_filter; /* delete */
+
+ int dp_error;
+ int error;
+};
+
struct sdap_sudo_load_sudoers_state {
struct tevent_context *ev;
- struct sdap_sudo_ctx *sudo_ctx;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sysdb_attrs **ldap_rules; /* search result will be stored here */
- size_t ldap_rules_count; /* search result will be stored here */
+ size_t ldap_rules_count; /* search result will be stored here */
const char **attrs;
const char *filter;
@@ -49,26 +61,15 @@ struct sdap_sudo_load_sudoers_state {
int timeout;
};
-struct sdap_sudo_refresh_state {
- 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;
+static int sdap_sudo_refresh_retry(struct tevent_req *req);
- 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 void sdap_sudo_refresh_connect_done(struct tevent_req *subreq);
static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
- struct be_sudo_req *sudo_req,
struct sdap_options *opts,
- struct sdap_handle *sh);
+ struct sdap_handle *sh,
+ const char *ldap_filter);
static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req);
@@ -79,32 +80,19 @@ static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
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 sysdb_ctx *sysdb_ctx,
- struct sss_domain_info *domain,
- struct be_sudo_req *sudo_req);
+static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq);
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);
-
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
- struct be_sudo_req *sudo_req,
struct sdap_options *opts,
- struct sdap_id_conn_cache *conn_cache)
+ struct sdap_id_conn_cache *conn_cache,
+ const char *ldap_filter,
+ const char *sysdb_filter)
{
struct tevent_req *req = NULL;
struct sdap_sudo_refresh_state *state = NULL;
@@ -115,32 +103,32 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
+ /* if we don't have a search filter, this request is meaningless */
+ if (ldap_filter == NULL) {
+ ret = EINVAL;
+ goto immediately;
+ }
+
state->be_ctx = be_ctx;
- state->sudo_req = sudo_req;
state->opts = opts;
state->sdap_op = NULL;
state->sdap_conn_cache = conn_cache;
+ state->ldap_filter = talloc_strdup(state, ldap_filter);
+ state->sysdb_filter = talloc_strdup(state, sysdb_filter);
state->dp_error = DP_ERR_OK;
state->error = EOK;
- 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;
+ if (state->ldap_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ if (sysdb_filter != NULL && state->sysdb_filter == NULL) {
+ ret = ENOMEM;
goto immediately;
}
- ret = sdap_sudo_connect(req);
+ ret = sdap_sudo_refresh_retry(req);
if (ret == EAGAIN) {
/* asynchronous processing */
return req;
@@ -173,7 +161,7 @@ int sdap_sudo_refresh_recv(struct tevent_req *req,
return EOK;
}
-int sdap_sudo_connect(struct tevent_req *req)
+static int sdap_sudo_refresh_retry(struct tevent_req *req)
{
struct tevent_req *subreq = NULL;
struct sdap_sudo_refresh_state *state = NULL;
@@ -207,12 +195,12 @@ int sdap_sudo_connect(struct tevent_req *req)
return ret;
}
- tevent_req_set_callback(subreq, sdap_sudo_connect_done, req);
+ tevent_req_set_callback(subreq, sdap_sudo_refresh_connect_done, req);
return EAGAIN;
}
-void sdap_sudo_connect_done(struct tevent_req *subreq)
+static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req = NULL; /* req from sdap_sudo_refresh_send() */
struct sdap_sudo_refresh_state *state = NULL;
@@ -240,8 +228,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(state, state->be_ctx->ev,
- state->sudo_req, state->opts,
- sdap_id_op_handle(state->sdap_op));
+ state->opts,
+ sdap_id_op_handle(state->sdap_op),
+ state->ldap_filter);
if (subreq == NULL) {
ret = EFAULT;
goto fail;
@@ -257,11 +246,11 @@ fail:
tevent_req_error(req, ret);
}
-struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct be_sudo_req *sudo_req,
- struct sdap_options *opts,
- struct sdap_handle *sh)
+static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sdap_handle *sh,
+ const char *ldap_filter)
@@ -280,6 +269,7 @@ struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
state->sh = sh;
state->base_iter = 0;
state->search_bases = opts->sudo_search_bases;
+ state->filter = ldap_filter;
state->timeout = dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT);
state->ldap_rules = NULL;
state->ldap_rules_count = 0;
@@ -291,12 +281,6 @@ struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
goto done;
}
- /* create filter */
- 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, opts->sudorule_map, SDAP_OPTS_SUDO,
NULL, &state->attrs, NULL);
@@ -426,10 +410,10 @@ static void sdap_sudo_load_sudoers_process(struct tevent_req *subreq)
tevent_req_done(req);
}
-int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- size_t *rules_count,
- struct sysdb_attrs ***rules)
+static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *rules_count,
+ struct sysdb_attrs ***rules)
{
struct sdap_sudo_load_sudoers_state *state = NULL;
@@ -443,13 +427,15 @@ int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
return EOK;
}
-void sdap_sudo_load_sudoers_done(struct tevent_req *subreq)
+static 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 sysdb_attrs **rules = NULL;
size_t rules_count;
int ret;
+ errno_t sret;
+ bool in_transaction = false;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_refresh_state);
@@ -462,131 +448,61 @@ 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(state->be_ctx->sysdb, state->be_ctx->domain,
- state->sudo_req);
- if (ret != EOK) {
- goto done;
- }
-
- /* store rules */
- ret = sdap_sudo_store_sudoers(state->be_ctx->sysdb, state->opts,
- rules_count, rules);
- if (ret != EOK) {
- goto done;
- }
-
- DEBUG(SSSDBG_TRACE_FUNC, ("Sudoers is successfuly stored in cache\n"));
-
- ret = EOK;
-
-done:
- state->error = ret;
- if (ret == EOK) {
- state->dp_error = DP_ERR_OK;
- tevent_req_done(req);
- } else {
- state->dp_error = DP_ERR_FATAL;
- tevent_req_error(req, ret);
- }
-}
-
-int sdap_sudo_purge_sudoers(struct sysdb_ctx *sysdb_ctx,
- struct sss_domain_info *domain,
- struct be_sudo_req *sudo_req)
-{
- TALLOC_CTX *tmp_ctx;
- char *filter = NULL;
- char **sudouser = NULL;
- int ret = EOK;
- errno_t sret;
- bool in_transaction = false;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
- return ENOMEM;
- }
-
- ret = sysdb_transaction_start(sysdb_ctx);
+ /* start transaction */
+ ret = sysdb_transaction_start(state->be_ctx->sysdb);
if (ret != EOK) {
goto done;
}
in_transaction = true;
- switch (sudo_req->type) {
- case BE_REQ_SUDO_ALL:
- DEBUG(SSSDBG_TRACE_FUNC, ("Purging SUDOers cache of all rules\n"));
- ret = sysdb_sudo_purge_all(sysdb_ctx);
- break;
- case BE_REQ_SUDO_DEFAULTS:
- DEBUG(SSSDBG_TRACE_FUNC, ("Purging SUDOers cache of default options\n"));
- ret = sysdb_sudo_purge_byname(sysdb_ctx, SDAP_SUDO_DEFAULTS);
- break;
- case BE_REQ_SUDO_USER:
- DEBUG(SSSDBG_TRACE_FUNC, ("Purging SUDOers cache of user's [%s] rules\n",
- sudo_req->username));
-
- /* netgroups */
- ret = sysdb_get_sudo_filter(tmp_ctx, NULL, 0, NULL,
- SYSDB_SUDO_FILTER_NGRS, &filter);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create filter to purge "
- "SUDOers cache [%d]: %s\n", ret, strerror(ret)));
- goto done;
- }
-
- ret = sysdb_sudo_purge_byfilter(sysdb_ctx, filter);
+ /* purge cache */
+ if (state->sysdb_filter != NULL) {
+ ret = sysdb_sudo_purge_byfilter(state->be_ctx->sysdb,
+ state->sysdb_filter);
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to purge SUDOers cache "
- "(netgroups) [%d]: %s\n", ret, strerror(ret)));
goto done;
}
-
- /* user, uid, groups */
- sudouser = sysdb_sudo_build_sudouser(tmp_ctx, sudo_req->username,
- sudo_req->uid, sudo_req->groups,
- true);
- if (sudouser == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to create sudoUser to purge "
- "SUDOers cache [%d]: %s\n", ret, strerror(ret)));
- goto done;
- }
-
- ret = sysdb_sudo_purge_bysudouser(sysdb_ctx, sudouser);
- break;
- default:
- DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid request type %d\n", sudo_req->type));
- return EINVAL;
}
+ /* store rules */
+ ret = sdap_sudo_store_sudoers(state->be_ctx->sysdb, state->opts,
+ rules_count, rules);
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to purge SUDOers cache [%d]: %s\n",
- ret, strerror(ret)));
goto done;
}
- ret = sysdb_transaction_commit(sysdb_ctx);
+ /* commit transaction */
+ ret = sysdb_transaction_commit(state->be_ctx->sysdb);
if (ret == EOK) {
in_transaction = false;
}
+ DEBUG(SSSDBG_TRACE_FUNC, ("Sudoers is successfuly stored in cache\n"));
+
+ ret = EOK;
+
done:
if (in_transaction) {
- sret = sysdb_transaction_cancel(sysdb_ctx);
+ sret = sysdb_transaction_cancel(state->be_ctx->sysdb);
if (sret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not cancel transaction\n"));
}
}
- talloc_free(tmp_ctx);
- return ret;
+ state->error = ret;
+ if (ret == EOK) {
+ state->dp_error = DP_ERR_OK;
+ tevent_req_done(req);
+ } else {
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ }
}
-int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx,
- struct sdap_options *opts,
- size_t rules_count,
- struct sysdb_attrs **rules)
+static int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx,
+ struct sdap_options *opts,
+ size_t rules_count,
+ struct sysdb_attrs **rules)
{
errno_t ret;
@@ -605,106 +521,3 @@ int sdap_sudo_store_sudoers(struct sysdb_ctx *sysdb_ctx,
return EOK;
}
-
-const char *sdap_sudo_build_filter(TALLOC_CTX *mem_ctx,
- struct sdap_attr_map *map,
- 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;
- char *sanitized = NULL;
- char **group = NULL;
- int ret;
-
- /* user name */
- ret = sss_filter_sanitize(filter, username, &sanitized);
- if (ret != EOK) {
- goto fail;
- }
- filter = talloc_asprintf_append(filter, SDAP_SUDO_FILTER_USERNAME,
- map[SDAP_AT_SUDO_USER].name,
- sanitized);
- if (filter == NULL) {
- goto fail;
- }
-
- /* user uid */
- filter = talloc_asprintf_append(filter, SDAP_SUDO_FILTER_UID,
- map[SDAP_AT_SUDO_USER].name,
- uid);
- if (filter == NULL) {
- goto fail;
- }
-
- /* groups */
- if (groups != NULL) {
- for (group = groups; *group != NULL; group++) {
- ret = sss_filter_sanitize(filter, *group, &sanitized);
- if (ret != EOK) {
- goto fail;
- }
- filter = talloc_asprintf_append(filter, SDAP_SUDO_FILTER_GROUP,
- map[SDAP_AT_SUDO_USER].name,
- sanitized);
- if (filter == NULL) {
- goto fail;
- }
- }
- }
-
- /* netgroups */
- /*
- * FIXME: load only netgroups user is member of
- * FIXME: add option to disable this filter
- */
- filter = talloc_asprintf_append(filter, SDAP_SUDO_FILTER_NETGROUP,
- map[SDAP_AT_SUDO_USER].name,
- "*");
- if (filter == NULL) {
- goto fail;
- }
-
-
- output = talloc_asprintf(mem_ctx, SDAP_SUDO_FILTER_USER,
- map[SDAP_OC_SUDORULE].name,
- map[SDAP_AT_SUDO_NAME].name,
- SDAP_SUDO_DEFAULTS, /* FIXME: add option for this */
- map[SDAP_AT_SUDO_USER].name,
- filter);
-
- talloc_free(filter);
- return output;
-
-fail:
- talloc_free(filter);
- return NULL;
-}
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 3bef454a1..c7e76729a 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -176,8 +176,8 @@ void sdap_sudo_handler(struct be_req *be_req)
sudo_req->groups = NULL;
}
- req = sdap_sudo_refresh_send(be_req, id_ctx->be, sudo_req, id_ctx->opts,
- id_ctx->conn_cache);
+ req = sdap_sudo_refresh_send(be_req, id_ctx->be, id_ctx->opts,
+ id_ctx->conn_cache, NULL, NULL);
if (req == NULL) {
ret = ENOMEM;
goto fail;
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index dd42f368e..6d3954960 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -31,9 +31,10 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
/* sdap async interface */
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
- struct be_sudo_req *sudo_req,
struct sdap_options *opts,
- struct sdap_id_conn_cache *conn_cache);
+ struct sdap_id_conn_cache *conn_cache,
+ const char *ldap_filter,
+ const char *sysdb_filter);
int sdap_sudo_refresh_recv(struct tevent_req *req,
int *dp_error,
diff --git a/src/providers/ldap/sdap_sudo_timer.c b/src/providers/ldap/sdap_sudo_timer.c
index 9996aae88..56386f42b 100644
--- a/src/providers/ldap/sdap_sudo_timer.c
+++ b/src/providers/ldap/sdap_sudo_timer.c
@@ -129,9 +129,10 @@ static void sdap_sudo_refresh_timer(struct tevent_context *ev,
sudo_req->username = NULL;
/* send request */
- req = sdap_sudo_refresh_send(refresh_ctx, refresh_ctx->id_ctx->be, sudo_req,
+ req = sdap_sudo_refresh_send(refresh_ctx, refresh_ctx->id_ctx->be,
refresh_ctx->id_ctx->opts,
- refresh_ctx->id_ctx->conn_cache);
+ refresh_ctx->id_ctx->conn_cache,
+ NULL, NULL);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to schedule refresh of SUDO rules, "
"retrying later!\n"));