summaryrefslogtreecommitdiffstats
path: root/src/responder/sudo/sudosrv_get_sudorules.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder/sudo/sudosrv_get_sudorules.c')
-rw-r--r--src/responder/sudo/sudosrv_get_sudorules.c269
1 files changed, 227 insertions, 42 deletions
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index 0cf8c9be3..0608888ff 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -116,16 +116,11 @@ sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins)
static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char **attrs,
- unsigned int flags,
- const char *username,
- uid_t uid,
- char **groupnames,
- bool inverse_order,
+ const char *filter,
struct sysdb_attrs ***_rules,
uint32_t *_count)
{
TALLOC_CTX *tmp_ctx;
- char *filter;
errno_t ret;
size_t count;
struct sysdb_attrs **rules;
@@ -136,14 +131,6 @@ static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames,
- flags, &filter);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct the search filter "
- "[%d]: %s\n", ret, sss_strerror(ret));
- goto done;
- }
-
DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter);
if (IS_SUBDOMAIN(domain)) {
@@ -170,12 +157,6 @@ static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sort_sudo_rules(rules, count, inverse_order);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n");
- goto done;
- }
-
*_rules = talloc_steal(mem_ctx, rules);
*_count = (uint32_t)count;
@@ -194,24 +175,131 @@ static errno_t sudosrv_expired_rules(TALLOC_CTX *mem_ctx,
struct sysdb_attrs ***_rules,
uint32_t *_num_rules)
{
- unsigned int flags = SYSDB_SUDO_FILTER_NONE;
const char *attrs[] = { SYSDB_NAME, NULL };
+ char *filter;
errno_t ret;
- flags = SYSDB_SUDO_FILTER_INCLUDE_ALL
- | SYSDB_SUDO_FILTER_INCLUDE_DFL
- | SYSDB_SUDO_FILTER_ONLY_EXPIRED
- | SYSDB_SUDO_FILTER_USERINFO;
+ filter = sysdb_sudo_filter_expired(NULL, username, groups, uid);
+ if (filter == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
+ _rules, _num_rules);
+ talloc_free(filter);
+
+ return ret;
+}
+
+static errno_t sudosrv_cached_rules_by_user(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ const char *username,
+ char **groupnames,
+ struct sysdb_attrs ***_rules,
+ uint32_t *_num_rules)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct sysdb_attrs **rules;
+ uint32_t num_rules;
+ uint32_t i;
+ const char *filter;
+ const char *val;
+ errno_t ret;
+ const char *attrs[] = { SYSDB_OBJECTCLASS,
+ SYSDB_SUDO_CACHE_AT_CN,
+ SYSDB_SUDO_CACHE_AT_HOST,
+ SYSDB_SUDO_CACHE_AT_COMMAND,
+ SYSDB_SUDO_CACHE_AT_OPTION,
+ SYSDB_SUDO_CACHE_AT_RUNAS,
+ SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ SYSDB_SUDO_CACHE_AT_RUNASGROUP,
+ SYSDB_SUDO_CACHE_AT_NOTBEFORE,
+ SYSDB_SUDO_CACHE_AT_NOTAFTER,
+ SYSDB_SUDO_CACHE_AT_ORDER,
+ NULL };
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ filter = sysdb_sudo_filter_user(tmp_ctx, username, groupnames, uid);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sudosrv_query_cache(tmp_ctx, domain, attrs, filter,
+ &rules, &num_rules);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ val = talloc_asprintf(tmp_ctx, "#%"SPRIuid, uid);
+ if (val == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* Add sudoUser: #uid to prevent conflicts with fqnames. */
+ DEBUG(SSSDBG_TRACE_FUNC, "Replacing sudoUser attribute with "
+ "sudoUser: %s\n", val);
+ for (i = 0; i < num_rules; i++) {
+ ret = sysdb_attrs_add_string(rules[i], SYSDB_SUDO_CACHE_AT_USER, val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to alter sudoUser attribute "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ }
+ }
+
+ *_rules = talloc_steal(mem_ctx, rules);
+ *_num_rules = num_rules;
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t sudosrv_cached_rules_by_ng(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ const char *username,
+ char **groupnames,
+ struct sysdb_attrs ***_rules,
+ uint32_t *_num_rules)
+{
+ char *filter;
+ errno_t ret;
+ const char *attrs[] = { SYSDB_OBJECTCLASS,
+ SYSDB_SUDO_CACHE_AT_CN,
+ SYSDB_SUDO_CACHE_AT_USER,
+ SYSDB_SUDO_CACHE_AT_HOST,
+ SYSDB_SUDO_CACHE_AT_COMMAND,
+ SYSDB_SUDO_CACHE_AT_OPTION,
+ SYSDB_SUDO_CACHE_AT_RUNAS,
+ SYSDB_SUDO_CACHE_AT_RUNASUSER,
+ SYSDB_SUDO_CACHE_AT_RUNASGROUP,
+ SYSDB_SUDO_CACHE_AT_NOTBEFORE,
+ SYSDB_SUDO_CACHE_AT_NOTAFTER,
+ SYSDB_SUDO_CACHE_AT_ORDER,
+ NULL };
+
+ filter = sysdb_sudo_filter_netgroups(NULL, username, groupnames, uid);
+ if (filter == NULL) {
+ return ENOMEM;
+ }
- ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags,
- username, uid, groups, false,
+ ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
_rules, _num_rules);
+ talloc_free(filter);
return ret;
}
static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
- enum sss_sudo_type type,
struct sss_domain_info *domain,
uid_t uid,
const char *username,
@@ -220,10 +308,78 @@ static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
struct sysdb_attrs ***_rules,
uint32_t *_num_rules)
{
- unsigned int flags = SYSDB_SUDO_FILTER_NONE;
+ TALLOC_CTX *tmp_ctx;
+ struct sysdb_attrs **user_rules;
+ struct sysdb_attrs **ng_rules;
struct sysdb_attrs **rules;
- const char *debug_name = "unknown";
+ uint32_t num_user_rules;
+ uint32_t num_ng_rules;
uint32_t num_rules;
+ uint32_t rule_iter, i;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sudosrv_cached_rules_by_user(tmp_ctx, domain, uid, username, groups,
+ &user_rules, &num_user_rules);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sudosrv_cached_rules_by_ng(tmp_ctx, domain, uid, username, groups,
+ &ng_rules, &num_ng_rules);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ num_rules = num_user_rules + num_ng_rules;
+ if (num_rules == 0) {
+ *_rules = NULL;
+ *_num_rules = 0;
+ ret = EOK;
+ goto done;
+ }
+
+ rules = talloc_array(tmp_ctx, struct sysdb_attrs *, num_rules);
+ if (rules == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ rule_iter = 0;
+ for (i = 0; i < num_user_rules; rule_iter++, i++) {
+ rules[rule_iter] = talloc_steal(rules, user_rules[i]);
+ }
+
+ for (i = 0; i < num_ng_rules; rule_iter++, i++) {
+ rules[rule_iter] = talloc_steal(rules, ng_rules[i]);
+ }
+
+ ret = sort_sudo_rules(rules, num_rules, inverse_order);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n");
+ goto done;
+ }
+
+ *_rules = talloc_steal(mem_ctx, rules);
+ *_num_rules = num_rules;
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t sudosrv_cached_defaults(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct sysdb_attrs ***_rules,
+ uint32_t *_num_rules)
+{
+ char *filter;
errno_t ret;
const char *attrs[] = { SYSDB_OBJECTCLASS,
SYSDB_SUDO_CACHE_AT_CN,
@@ -239,31 +395,60 @@ static errno_t sudosrv_cached_rules(TALLOC_CTX *mem_ctx,
SYSDB_SUDO_CACHE_AT_ORDER,
NULL };
+ filter = sysdb_sudo_filter_defaults(NULL);
+ if (filter == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sudosrv_query_cache(mem_ctx, domain, attrs, filter,
+ _rules, _num_rules);
+ talloc_free(filter);
+
+ return ret;
+}
+
+static errno_t sudosrv_fetch_rules(TALLOC_CTX *mem_ctx,
+ enum sss_sudo_type type,
+ struct sss_domain_info *domain,
+ uid_t uid,
+ const char *username,
+ char **groups,
+ bool inverse_order,
+ struct sysdb_attrs ***_rules,
+ uint32_t *_num_rules)
+{
+ struct sysdb_attrs **rules;
+ const char *debug_name = "unknown";
+ uint32_t num_rules;
+ errno_t ret;
+
switch (type) {
case SSS_SUDO_USER:
DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules for [%s@%s]\n",
username, domain->name);
debug_name = "rules";
- flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL;
+
+ ret = sudosrv_cached_rules(mem_ctx, domain, uid, username, groups,
+ inverse_order, &rules, &num_rules);
+
break;
case SSS_SUDO_DEFAULTS:
debug_name = "default options";
DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options for [%s@%s]\n",
username, domain->name);
- flags = SYSDB_SUDO_FILTER_INCLUDE_DFL;
+
+ ret = sudosrv_cached_defaults(mem_ctx, domain, &rules, &num_rules);
+
break;
}
- ret = sudosrv_query_cache(mem_ctx, domain, attrs, flags,
- username, uid, groups,
- inverse_order, &rules, &num_rules);
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Unable to retrieve sudo rules [%d]: %s\n", ret, strerror(ret));
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve %s [%d]: %s\n",
+ debug_name, ret, sss_strerror(ret));
return ret;
}
- DEBUG(SSSDBG_TRACE_FUNC, "Returning %d %s for [%s@%s]\n",
+ DEBUG(SSSDBG_TRACE_FUNC, "Returning %u %s for [%s@%s]\n",
num_rules, debug_name, username, domain->name);
*_rules = rules;
@@ -541,10 +726,10 @@ static void sudosrv_get_rules_done(struct tevent_req *subreq)
"in cache.\n");
}
- ret = sudosrv_cached_rules(state, state->type, state->domain, state->uid,
- state->username, state->groups,
- state->inverse_order,
- &state->rules, &state->num_rules);
+ ret = sudosrv_fetch_rules(state, state->type, state->domain, state->uid,
+ state->username, state->groups,
+ state->inverse_order,
+ &state->rules, &state->num_rules);
if (ret != EOK) {
tevent_req_error(req, ret);