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

Reply via email to