diff options
author | Pavel Březina <pbrezina@redhat.com> | 2015-07-29 14:51:30 +0200 |
---|---|---|
committer | Lukas Slebodnik <lslebodn@redhat.com> | 2016-02-16 11:48:28 +0100 |
commit | caa1686123b158c79349edd6916ca927f4522a88 (patch) | |
tree | 258d23e097eea578aeb8178b17e4a6e8e17e81df | |
parent | 5232e1e7e3267be04f9bdee614b5f81367050fbd (diff) | |
download | sssd-caa1686123b158c79349edd6916ca927f4522a88.tar.gz sssd-caa1686123b158c79349edd6916ca927f4522a88.tar.xz sssd-caa1686123b158c79349edd6916ca927f4522a88.zip |
sudo: use "higher value wins" when ordering rulessssd-1_11_8
This commit changes the default ordering logic (lower value wins) to
a correct one that is used by native ldap support. It also adds a new
option sudo_inverse_order to switch to the original SSSD (incorrect)
behaviour if needed.
Resolves:
https://fedorahosted.org/sssd/ticket/2682
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 52e3ee5c5ff2c5a4341041826a803ad42d2b2de7)
-rw-r--r-- | src/confdb/confdb.h | 2 | ||||
-rw-r--r-- | src/config/SSSDConfig/__init__.py.in | 1 | ||||
-rw-r--r-- | src/config/etc/sssd.api.conf | 1 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv.c | 11 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_get_sudorules.c | 54 | ||||
-rw-r--r-- | src/responder/sudo/sudosrv_private.h | 1 |
6 files changed, 60 insertions, 10 deletions
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 10ec13bf7..95711a557 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -117,6 +117,8 @@ #define CONFDB_DEFAULT_SUDO_CACHE_TIMEOUT 180 #define CONFDB_SUDO_TIMED "sudo_timed" #define CONFDB_DEFAULT_SUDO_TIMED false +#define CONFDB_SUDO_INVERSE_ORDER "sudo_inverse_order" +#define CONFDB_DEFAULT_SUDO_INVERSE_ORDER false /* autofs */ #define CONFDB_AUTOFS_CONF_ENTRY "config/autofs" diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index 4242df507..3814bb9a3 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -84,6 +84,7 @@ option_strings = { # [sudo] 'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'), + 'sudo_inverse_order' : _('If true, SSSD will switch back to lower-wins ordering logic'), # [autofs] 'autofs_negative_timeout' : _('Negative cache timeout length (seconds)'), diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index 0514d8609..ebdd21563 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -59,6 +59,7 @@ get_domains_timeout = int, None, false [sudo] # sudo service sudo_timed = bool, None, false +sudo_inverse_order = bool, None, false [autofs] # autofs service diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c index 25c9d585b..df8a1e321 100644 --- a/src/responder/sudo/sudosrv.c +++ b/src/responder/sudo/sudosrv.c @@ -167,6 +167,17 @@ int sudo_process_init(TALLOC_CTX *mem_ctx, goto fail; } + /* Get sudo_inverse_order option */ + ret = confdb_get_bool(sudo_ctx->rctx->cdb, + CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_INVERSE_ORDER, + CONFDB_DEFAULT_SUDO_INVERSE_ORDER, + &sudo_ctx->inverse_order); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", + ret, strerror(ret)); + goto fail; + } + ret = schedule_get_domains_task(rctx, rctx->ev, rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index 579874d13..b9ac80846 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -319,6 +319,7 @@ static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, const char *username, uid_t uid, char **groupnames, + bool inverse_order, struct sysdb_attrs ***_rules, uint32_t *_count); @@ -380,6 +381,7 @@ errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) cmd_ctx->domain, attrs, flags, cmd_ctx->orig_username, cmd_ctx->uid, groupnames, + cmd_ctx->sudo_ctx->inverse_order, &expired_rules, &expired_rules_num); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve expired sudo rules " @@ -591,6 +593,7 @@ static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, cmd_ctx->domain, attrs, flags, cmd_ctx->orig_username, cmd_ctx->uid, groupnames, + cmd_ctx->sudo_ctx->inverse_order, &rules, &num_rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -616,7 +619,7 @@ done: } static errno_t -sort_sudo_rules(struct sysdb_attrs **rules, size_t count); +sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool higher_wins); static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, @@ -626,6 +629,7 @@ static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, const char *username, uid_t uid, char **groupnames, + bool inverse_order, struct sysdb_attrs ***_rules, uint32_t *_count) { @@ -675,7 +679,7 @@ static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, goto done; } - ret = sort_sudo_rules(rules, count); + ret = sort_sudo_rules(rules, count, inverse_order); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n"); @@ -692,7 +696,7 @@ done: } static int -sudo_order_cmp_fn(const void *a, const void *b) +sudo_order_cmp(const void *a, const void *b, bool lower_wins) { struct sysdb_attrs *r1, *r2; uint32_t o1, o2; @@ -725,19 +729,49 @@ sudo_order_cmp_fn(const void *a, const void *b) return 0; } - if (o1 > o2) { - return 1; - } else if (o1 < o2) { - return -1; + if (lower_wins) { + /* The lowest value takes priority. Original wrong SSSD behaviour. */ + if (o1 > o2) { + return 1; + } else if (o1 < o2) { + return -1; + } + } else { + /* The higher value takes priority. Standard LDAP behaviour. */ + if (o1 < o2) { + return 1; + } else if (o1 > o2) { + return -1; + } } return 0; } +static int +sudo_order_low_cmp_fn(const void *a, const void *b) +{ + return sudo_order_cmp(a, b, true); +} + +static int +sudo_order_high_cmp_fn(const void *a, const void *b) +{ + return sudo_order_cmp(a, b, false); +} + static errno_t -sort_sudo_rules(struct sysdb_attrs **rules, size_t count) +sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins) { - qsort(rules, count, sizeof(struct sysdb_attrs *), - sudo_order_cmp_fn); + if (lower_wins) { + DEBUG(SSSDBG_TRACE_FUNC, "Sorting rules with lower-wins logic\n"); + qsort(rules, count, sizeof(struct sysdb_attrs *), + sudo_order_low_cmp_fn); + } else { + DEBUG(SSSDBG_TRACE_FUNC, "Sorting rules with higher-wins logic\n"); + qsort(rules, count, sizeof(struct sysdb_attrs *), + sudo_order_high_cmp_fn); + } + return EOK; } diff --git a/src/responder/sudo/sudosrv_private.h b/src/responder/sudo/sudosrv_private.h index 3c53755f9..186ed2cb5 100644 --- a/src/responder/sudo/sudosrv_private.h +++ b/src/responder/sudo/sudosrv_private.h @@ -50,6 +50,7 @@ struct sudo_ctx { * options */ bool timed; + bool inverse_order; }; struct sudo_cmd_ctx { |