Hi all,
attached two patches resolve [1]. This ticket has design page [2].
In my opinion it could be fine to have tests on sysdb_sudo. I have
started write some, but there were troubles with memory leak. Maybe I
haven't understood necessary logic properly.
However I could continue with tests or create new ticket for it.
And little question. Is the name of sudo rule case sensitive? If yes, I
have to do one little change.
[1] https://fedorahosted.org/sssd/ticket/2081
[2] https://fedorahosted.org/sssd/wiki/DesignDocs/SUDOCachingRulesInvalidate
Regards
--
Petr^4 Čech
>From 46f42e8e342b9da0a7a61e897eb0e7c119b1f452 Mon Sep 17 00:00:00 2001
From: Petr Cech <pc...@redhat.com>
Date: Wed, 24 Feb 2016 09:12:41 -0500
Subject: [PATCH 1/2] SYSDB: Add new funtions into sysdb_sudo
This patch adds two new functions into public
API of sysdb_sudo:
* sysdb_search_sudo_rules
* sysdb_set_sudo_rule_attr
Resolves:
https://fedorahosted.org/sssd/ticket/2081
---
src/db/sysdb_sudo.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/db/sysdb_sudo.h | 15 +++++++++
2 files changed, 107 insertions(+)
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 76116abacb20219f0c1dcdde755e8268e10fd293..c38f21bbca36b86af00e616b87810314be7583bb 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -889,3 +889,95 @@ done:
return ret;
}
+
+errno_t sysdb_search_sudo_rules(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *sub_filter,
+ const char **attrs,
+ size_t *msgs_count,
+ struct ldb_message ***msgs)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *dn;
+ char *filter;
+ int ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
+ SUDORULE_SUBDIR, domain->name);
+ if (!dn) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(&%s%s)", SUDO_ALL_FILTER, sub_filter);
+ if (!filter) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Search services with filter: %s\n", filter);
+
+ ret = sysdb_search_entry(mem_ctx, domain->sysdb, dn,
+ LDB_SCOPE_SUBTREE, filter, attrs,
+ msgs_count, msgs);
+ if (ret) {
+ goto fail;
+ }
+
+ talloc_zfree(tmp_ctx);
+ return EOK;
+
+fail:
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_INTERNAL, "No such entry\n");
+ }
+ else if (ret) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+ }
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
+static struct ldb_dn *
+sysdb_sudo_rule_dn(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name)
+{
+ return sysdb_custom_dn(mem_ctx, domain, name, SUDORULE_SUBDIR);
+}
+
+errno_t
+sysdb_set_sudo_rule_attr(struct sss_domain_info *domain,
+ const char *name,
+ struct sysdb_attrs *attrs,
+ int mod_op)
+{
+ errno_t ret;
+ struct ldb_dn *dn;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ dn = sysdb_sudo_rule_dn(tmp_ctx, domain, name);
+ if (!dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op);
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
\ No newline at end of file
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index ba90a68512c6c29134ab2f746220db9533a93dda..fd85afee02bebfb57634f81984ba217c3bed44fd 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -121,4 +121,19 @@ sysdb_sudo_store(struct sss_domain_info *domain,
struct sysdb_attrs **rules,
size_t num_rules);
+
+errno_t
+sysdb_search_sudo_rules(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *sub_filter,
+ const char **attrs,
+ size_t *msgs_count,
+ struct ldb_message ***msgs);
+
+errno_t
+sysdb_set_sudo_rule_attr(struct sss_domain_info *domain,
+ const char *name,
+ struct sysdb_attrs *attrs,
+ int mod_op);
+
#endif /* _SYSDB_SUDO_H_ */
--
2.5.0
>From dd6be5acaa4fff4b0b010638207947f584c8e335 Mon Sep 17 00:00:00 2001
From: Petr Cech <pc...@redhat.com>
Date: Tue, 23 Feb 2016 10:11:15 -0500
Subject: [PATCH 2/2] TOOL: Invalidation of sudo rules at sss_cache
This patch adds new functionality to sss_cach for invalidation of given
sudo rule or all sudo rules.
Resolves:
https://fedorahosted.org/sssd/ticket/2081
---
src/man/sss_cache.8.xml | 23 ++++++++++++++++++
src/tools/sss_cache.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/src/man/sss_cache.8.xml b/src/man/sss_cache.8.xml
index 1bc3633d9daa69ea59ba7ada0b6e180ece6e508a..81489288ced92ee5d4e7608ac092924369292bca 100644
--- a/src/man/sss_cache.8.xml
+++ b/src/man/sss_cache.8.xml
@@ -180,6 +180,29 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry condition="with_sudo">
+ <term>
+ <option>-r</option>,<option>--sudo-rule</option>
+ <replaceable>rule</replaceable>
+ </term>
+ <listitem>
+ <para>
+ Invalidate particular sudo rule.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_sudo">
+ <term>
+ <option>-R</option>,<option>--sudo-rules</option>
+ </term>
+ <listitem>
+ <para>
+ Invalidate all cached sudo rules. This option
+ overrides invalidation of specific sudo rule
+ if it was also set.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>
<option>-d</option>,<option>--domain</option>
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index 88895e8de374ed3fe16cbc92125ee3b91172e39e..4722d0b108a7214e2af647429281fd57ce18a097 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -31,6 +31,7 @@
#include "db/sysdb_services.h"
#include "db/sysdb_autofs.h"
#include "db/sysdb_ssh.h"
+#include "db/sysdb_sudo.h"
#define INVALIDATE_NONE 0
#define INVALIDATE_USERS 1
@@ -39,6 +40,7 @@
#define INVALIDATE_SERVICES 8
#define INVALIDATE_AUTOFSMAPS 16
#define INVALIDATE_SSH_HOSTS 32
+#define INVALIDATE_SUDO_RULES 64
#ifdef BUILD_AUTOFS
#ifdef BUILD_SSH
@@ -67,7 +69,8 @@ enum sss_cache_entry {
TYPE_NETGROUP,
TYPE_SERVICE,
TYPE_AUTOFSMAP,
- TYPE_SSH_HOST
+ TYPE_SSH_HOST,
+ TYPE_SUDO_RULE
};
static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx,
@@ -85,6 +88,7 @@ struct cache_tool_ctx {
char *service_filter;
char *autofs_filter;
char *ssh_host_filter;
+ char *sudo_rule_filter;
char *user_name;
char *group_name;
@@ -92,6 +96,7 @@ struct cache_tool_ctx {
char *service_name;
char *autofs_name;
char *ssh_host_name;
+ char *sudo_rule_name;
bool update_user_filter;
bool update_group_filter;
@@ -99,6 +104,7 @@ struct cache_tool_ctx {
bool update_service_filter;
bool update_autofs_filter;
bool update_ssh_host_filter;
+ bool update_sudo_rule_filter;
};
errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain);
@@ -172,6 +178,9 @@ int main(int argc, const char *argv[])
skipped &= !invalidate_entries(tctx, dinfo, TYPE_SSH_HOST,
tctx->ssh_host_filter,
tctx->ssh_host_name);
+ skipped &= !invalidate_entries(tctx, dinfo, TYPE_SUDO_RULE,
+ tctx->sudo_rule_filter,
+ tctx->sudo_rule_name);
ret = sysdb_transaction_commit(sysdb);
if (ret != EOK) {
@@ -356,6 +365,14 @@ static errno_t update_all_filters(struct cache_tool_ctx *tctx,
return ret;
}
+ /* Update sudo rule filter */
+ ret = update_filter(tctx, dinfo, tctx->sudo_rule_name,
+ tctx->update_sudo_rule_filter, "(%s=%s)", false,
+ &tctx->sudo_rule_filter);
+ if (ret != EOK) {
+ return ret;
+ }
+
return EOK;
}
@@ -408,6 +425,15 @@ static bool invalidate_entries(TALLOC_CTX *ctx,
ret = ENOSYS;
#endif /* BUILD_SSH */
break;
+ case TYPE_SUDO_RULE:
+ type_string = "sudo_rule";
+#ifdef BUILD_SUDO
+ ret = sysdb_search_sudo_rules(ctx, dinfo,
+ filter, attrs, &msg_count, &msgs);
+#else /* BUILD_SUDO */
+ ret = ENOSYS;
+#endif /* BUILD_SUDO */
+ break;
}
if (ret != EOK) {
@@ -492,6 +518,14 @@ static errno_t invalidate_entry(TALLOC_CTX *ctx,
ret = ENOSYS;
#endif /* BUILD_SSH */
break;
+ case TYPE_SUDO_RULE:
+#ifdef BUILD_SUDO
+ ret = sysdb_set_sudo_rule_attr(domain, name,
+ sys_attrs, SYSDB_MOD_REP);
+#else /* BUILD_SUDO */
+ ret = ENOSYS;
+#endif /* BUILD_SUDO */
+ break;
default:
return EINVAL;
}
@@ -577,6 +611,7 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
char *service = NULL;
char *map = NULL;
char *ssh_host = NULL;
+ char *sudo_rule = NULL;
char *domain = NULL;
int debug = SSSDBG_DEFAULT;
errno_t ret = EOK;
@@ -616,6 +651,12 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
{ "ssh-hosts", 'H', POPT_ARG_NONE, NULL, 'h',
_("Invalidate all SSH hosts"), NULL },
#endif /* BUILD_SSH */
+#ifdef BUILD_SUDO
+ { "sudo-rule", 'r', POPT_ARG_STRING, &sudo_rule, 0,
+ _("Invalidate particular sudo rule"), NULL },
+ { "sudo-rules", 'R', POPT_ARG_NONE, NULL, 'r',
+ _("Invalidate all cached sudo rules"), NULL },
+#endif /* BUILD_SUDO */
{ "domain", 'd', POPT_ARG_STRING, &domain, 0,
_("Only invalidate entries from a particular domain"), NULL },
POPT_TABLEEND
@@ -650,6 +691,9 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
case 'h':
idb |= INVALIDATE_SSH_HOSTS;
break;
+ case 'r':
+ idb |= INVALIDATE_SUDO_RULES;
+ break;
case 'e':
idb = INVALIDATE_EVERYTHING;
break;
@@ -664,7 +708,7 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
}
if (idb == INVALIDATE_NONE && !user && !group &&
- !netgroup && !service && !map && !ssh_host) {
+ !netgroup && !service && !map && !ssh_host && !sudo_rule) {
BAD_POPT_PARAMS(pc,
_("Please select at least one object to invalidate\n"),
ret, fini);
@@ -729,18 +773,28 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
ctx->update_ssh_host_filter = true;
}
+ if (idb & INVALIDATE_SUDO_RULES) {
+ ctx->sudo_rule_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
+ ctx->update_sudo_rule_filter = false;
+ } else if (sudo_rule) {
+ ctx->sudo_rule_name = talloc_strdup(ctx, sudo_rule);
+ ctx->update_sudo_rule_filter = true;
+ }
+
if (((idb & INVALIDATE_USERS) && !ctx->user_filter) ||
((idb & INVALIDATE_GROUPS) && !ctx->group_filter) ||
((idb & INVALIDATE_NETGROUPS) && !ctx->netgroup_filter) ||
((idb & INVALIDATE_SERVICES) && !ctx->service_filter) ||
((idb & INVALIDATE_AUTOFSMAPS) && !ctx->autofs_filter) ||
((idb & INVALIDATE_SSH_HOSTS) && !ctx->ssh_host_filter) ||
+ ((idb & INVALIDATE_SUDO_RULES) && !ctx->sudo_rule_filter) ||
(user && !ctx->user_name) ||
(group && !ctx->group_name) ||
(netgroup && !ctx->netgroup_name) ||
(service && !ctx->service_name) ||
(map && !ctx->autofs_name) ||
- (ssh_host && !ctx->ssh_host_name)) {
+ (ssh_host && !ctx->ssh_host_name) ||
+ (sudo_rule && !ctx->sudo_rule_name)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n");
ret = ENOMEM;
goto fini;
@@ -768,6 +822,10 @@ fini:
free(group);
free(netgroup);
free(domain);
+ free(service);
+ free(map);
+ free(ssh_host);
+ free(sudo_rule);
if (ret != EOK && ctx) {
talloc_zfree(ctx);
}
--
2.5.0
_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/sssd-devel@lists.fedorahosted.org