I'm sending three patches with the cache-cleaning utility and some updates in 
sysdb which this utility depends on.

Thanks
Jan
From 134dc1ce4ed714669f5a3e2e0550024ea1f4202a Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Mon, 11 Apr 2011 09:44:33 -0400
Subject: [PATCH 1/3] Some updates in sysdb for cache cleaning utility

---
 src/db/sysdb.c         |   41 +++++++++++++++++++++++++++++++++++++++++
 src/db/sysdb.h         |   13 ++++++++++++-
 src/db/sysdb_private.h |    7 -------
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index cd785219b10ece35adce1dad9a2012bfaf7b31ec..27bc863b565b6b3d79452327c82dda44a5adaf3e 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1874,6 +1874,47 @@ int sysdb_domain_init(TALLOC_CTX *mem_ctx,
                                       db_path, false, _ctx);
 }
 
+int sysdb_list_init(TALLOC_CTX *mem_ctx,
+                    const char *path,
+                    struct sysdb_ctx *ctx,
+                    struct sysdb_ctx_list **_list)
+{
+    struct sysdb_ctx_list *list;
+    int ret;
+
+    list = talloc_zero(mem_ctx, struct sysdb_ctx_list);
+    if (!list) {
+        DEBUG(1, ("talloc_zero failed\n"));
+        return ENOMEM;
+    }
+
+    list->db_path = talloc_strdup(list, path);
+    if (!list->db_path) {
+        DEBUG(1, ("talloc_strdup failed\n"));
+        ret = ENOMEM;
+        goto fail;
+    }
+
+    if (ctx) {
+        list->dbs = talloc_zero(list, struct sysdb_ctx *);
+        if (!list->dbs) {
+            DEBUG(1, ("talloc_zero failed\n"));
+            ret = ENOMEM;
+            goto fail;
+        }
+
+        list->dbs[0] = talloc_steal(list, ctx);
+        list->num_dbs = 1;
+    }
+
+    *_list = list;
+    return EOK;
+
+fail:
+    talloc_free(list);
+    return ret;
+}
+
 int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list,
                             struct sss_domain_info *domain,
                             struct sysdb_ctx **ctx)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index e6f9b4a7cdaf18a07eaa28a9387a2848e987d5f2..a7d3e7ea4663258558274bb83cbdef624974a63e 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -169,9 +169,15 @@
 #define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE
 
 struct confdb_ctx;
-struct sysdb_ctx_list;
 struct sysdb_ctx;
 
+struct sysdb_ctx_list {
+    struct sysdb_ctx **dbs;
+    size_t num_dbs;
+
+    char *db_path;
+};
+
 struct sysdb_attrs {
     int num;
     struct ldb_message_element *a;
@@ -282,6 +288,11 @@ int sysdb_domain_init(TALLOC_CTX *mem_ctx,
                       const char *db_path,
                       struct sysdb_ctx **_ctx);
 
+int sysdb_list_init(TALLOC_CTX *mem_ctx,
+                    const char *path,
+                    struct sysdb_ctx *ctx,
+                    struct sysdb_ctx_list **_list);
+
 int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list,
                             struct sss_domain_info *domain,
                             struct sysdb_ctx **_ctx);
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index f8e0a941fd23d99df05df8ac528b76de121970e9..06265a9a1e40a2d561cbc71645280f4e108d61ce 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -73,11 +73,4 @@ struct sysdb_ctx {
     char *ldb_file;
 };
 
-struct sysdb_ctx_list {
-    struct sysdb_ctx **dbs;
-    size_t num_dbs;
-
-    char *db_path;
-};
-
 #endif /* __INT_SYS_DB_H__ */
-- 
1.7.4.1

From 4c930bf99fe760c9ec4f2c7789a615a9c7bab5e9 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Mon, 11 Apr 2011 09:46:30 -0400
Subject: [PATCH 3/3] Some minor fixes and changes in sysdb_ops

---
 src/db/sysdb_ops.c |   49 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index ba1f6672c72afd78fdb818630f1e92caf9c2e3de..981f3526d89b71ce74d59d15d3f4c78653573cf7 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1383,6 +1383,18 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
+    if (!domain) {
+        domain = ctx->domain;
+    }
+
+    if (!attrs) {
+        attrs = sysdb_new_attrs(tmpctx);
+        if (!attrs) {
+            ret = ENOMEM;
+            goto done;
+        }
+    }
+
     if (pwd && (domain->legacy_passwords || !*pwd)) {
         ret = sysdb_attrs_add_string(attrs, SYSDB_PWD, pwd);
         if (ret) goto done;
@@ -1407,14 +1419,6 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx,
     }
 
     /* the user exists, let's just replace attributes when set */
-    if (!attrs) {
-        attrs = sysdb_new_attrs(tmpctx);
-        if (!attrs) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-
     if (uid) {
         ret = sysdb_attrs_add_uint32(attrs, SYSDB_UIDNUM, uid);
         if (ret) goto done;
@@ -1516,6 +1520,10 @@ int sysdb_store_group(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
+    if (!domain) {
+        domain = ctx->domain;
+    }
+
     ret = sysdb_search_group_by_name(tmpctx, ctx,
                                      domain, name, src_attrs, &msg);
     if (ret && ret != ENOENT) {
@@ -1525,6 +1533,14 @@ int sysdb_store_group(TALLOC_CTX *mem_ctx,
         new_group = true;
     }
 
+    if (!attrs) {
+        attrs = sysdb_new_attrs(tmpctx);
+        if (!attrs) {
+            ret = ENOMEM;
+            goto done;
+        }
+    }
+
     /* FIXME: use the remote modification timestamp to know if the
      * group needs any update */
 
@@ -1536,15 +1552,6 @@ int sysdb_store_group(TALLOC_CTX *mem_ctx,
     }
 
     /* the group exists, let's just replace attributes when set */
-
-    if (!attrs) {
-        attrs = sysdb_new_attrs(tmpctx);
-        if (!attrs) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-
     if (gid) {
         ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
         if (ret) goto done;
@@ -2088,6 +2095,10 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
+    if (!domain) {
+        domain = sysdb->domain;
+    }
+
     basedn = ldb_dn_new_fmt(tmpctx, sysdb->ldb,
                             SYSDB_TMPL_USER_BASE, domain->name);
     if (!basedn) {
@@ -2202,6 +2213,10 @@ int sysdb_search_groups(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
+    if (!domain) {
+        domain = sysdb->domain;
+    }
+
     basedn = ldb_dn_new_fmt(tmpctx, sysdb->ldb,
                             SYSDB_TMPL_GROUP_BASE, domain->name);
     if (!basedn) {
-- 
1.7.4.1

From 92aeafb093f3164ac2ca436452c20a7696595f5a Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Mon, 11 Apr 2011 09:45:27 -0400
Subject: [PATCH 2/3] Cache cleaning utility

---
 Makefile.am           |   10 ++-
 contrib/sssd.spec.in  |    1 +
 src/tools/sss_cache.c |  298 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 308 insertions(+), 1 deletions(-)
 create mode 100644 src/tools/sss_cache.c

diff --git a/Makefile.am b/Makefile.am
index b445f9c81dd66b9442e4163c7d76be40c7edf0be..201496628088cc89751d1d79111a159a6afe7c5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,7 +53,8 @@ sbin_PROGRAMS = \
     sss_groupdel \
     sss_usermod \
     sss_groupmod \
-    sss_groupshow
+    sss_groupshow \
+    sss_cache
 
 sssdlibexec_PROGRAMS = \
     sssd_nss \
@@ -475,6 +476,13 @@ sss_groupshow_SOURCES = \
 sss_groupshow_LDADD = \
     $(TOOLS_LIBS)
 
+sss_cache_SOURCES = \
+    src/tools/sss_cache.c \
+    $(SSSD_UTIL_OBJ) \
+    $(SSSD_TOOLS_OBJ)
+sss_cache_LDADD = \
+    $(TOOLS_LIBS)
+
 #################
 # Feature Tests #
 #################
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 338151ddb20a5258aa5a851cec7bf6b1546d6f69..56e36f4d5948043c70b144c38bd28010f4a5f7b7 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -249,6 +249,7 @@ rm -rf $RPM_BUILD_ROOT
 %{_sbindir}/sss_groupmod
 %{_sbindir}/sss_groupshow
 %{_sbindir}/sss_obfuscate
+%{_sbindir}/sss_cache
 %{_mandir}/man8/sss_groupadd.8*
 %{_mandir}/man8/sss_groupdel.8*
 %{_mandir}/man8/sss_groupmod.8*
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
new file mode 100644
index 0000000000000000000000000000000000000000..738b88b20d12f0b970f4bf852ad5e71e62d8acaa
--- /dev/null
+++ b/src/tools/sss_cache.c
@@ -0,0 +1,298 @@
+/*
+   SSSD
+
+   sss_cache
+
+   Copyright (C) Jan Zeleny <jzel...@redhat.com>        2011
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <talloc.h>
+#include <popt.h>
+#include <sys/types.h>
+
+#include "util/util.h"
+#include "tools/sss_sync_ops.h"
+#include "db/sysdb.h"
+
+enum invalidate_db {
+    INVALIDATE_NONE = 0,
+    INVALIDATE_USERS,
+    INVALIDATE_GROUPS,
+    INVALIDATE_ALL,
+};
+
+struct cache_tool_ctx {
+    struct confdb_ctx *confdb;
+    struct sss_domain_info *domains;
+    struct sysdb_ctx_list *sysdb_list;
+
+    char *user_filter;
+    char *group_filter;
+};
+
+errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain);
+errno_t init_context(struct cache_tool_ctx **tctx, int argc, const char *argv[]);
+
+int main(int argc, const char *argv[])
+{
+    errno_t ret;
+    struct cache_tool_ctx *tctx = NULL;
+    struct sysdb_ctx *sysdb;
+    int i, j;
+    const char *attrs[] = {SYSDB_NAME, NULL};
+    size_t msg_count;
+    struct ldb_message **msgs;
+    const char *c_name;
+
+    ret = init_context(&tctx, argc, argv);
+    if (ret != EOK) {
+        DEBUG(2, ("Error initializing context for the application\n"));
+        goto done;
+    }
+
+    for (i = 0; i<tctx->sysdb_list->num_dbs; i++) {
+        sysdb = tctx->sysdb_list->dbs[i];
+        ret = sysdb_transaction_start(sysdb);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not start the transaction!\n"));
+            goto done;
+        }
+
+        if (tctx->user_filter) {
+            ret = sysdb_search_users(tctx, sysdb, NULL, tctx->user_filter, attrs,
+                                     &msg_count, &msgs);
+            if (ret != EOK) {
+                DEBUG(3, ("Finding users with filter %s failed\n", tctx->user_filter));
+            }
+
+            for (j=0 ; j<msg_count ; j++) {
+                c_name = ldb_msg_find_attr_as_string(msgs[j], SYSDB_NAME, NULL);
+                if (c_name == NULL) {
+                    DEBUG(1, ("Something bad happenned, can't find attribute %s",
+                              SYSDB_NAME));
+                } else {
+                    ret = sysdb_store_user(tctx, sysdb, NULL, c_name, NULL, 0, 0,
+                                           NULL, NULL, NULL, NULL, NULL, 0);
+                    if (ret != EOK) {
+                        DEBUG(5, ("Couldn't invalidate user %s", c_name));
+                    }
+                }
+            }
+            talloc_free(msgs);
+        }
+
+        if (tctx->group_filter) {
+            ret = sysdb_search_groups(tctx, sysdb, NULL, tctx->group_filter,
+                                      attrs, &msg_count, &msgs);
+            if (ret != EOK) {
+                DEBUG(3, ("Finding users with filter %s failed\n", tctx->user_filter));
+            }
+
+            for (j=0 ; j<msg_count ; j++) {
+                c_name = ldb_msg_find_attr_as_string(msgs[j], SYSDB_NAME, NULL);
+                if (c_name == NULL) {
+                    DEBUG(1, ("Something bad happenned, can't find attribute %s",
+                              SYSDB_NAME));
+                } else {
+                    ret = sysdb_store_group(tctx, sysdb, NULL, c_name, 0, NULL, 0);
+                    if (ret != EOK) {
+                        DEBUG(5, ("Couldn't invalidate group %s", c_name));
+                    }
+                }
+            }
+            talloc_free(msgs);
+        }
+
+        ret = sysdb_transaction_commit(sysdb);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not commit the transaction!\n"));
+        }
+    }
+
+done:
+    if (tctx) talloc_free(tctx);
+    return ret;
+}
+
+
+errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain) {
+    char *confdb_path;
+    int ret;
+    struct sysdb_ctx *db_ctx = NULL;
+
+    confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
+    if (confdb_path == NULL) {
+        return ENOMEM;
+    }
+
+    /* Connect to the conf db */
+    ret = confdb_init(ctx, &ctx->confdb, confdb_path);
+    talloc_free(confdb_path);
+    if (ret != EOK) {
+        DEBUG(1, ("Could not initialize connection to the confdb\n"));
+        return ret;
+    }
+
+    if (domain) {
+        ret = confdb_get_domain(ctx->confdb, domain, &ctx->domains);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not get '%s' domain: [%d] [%s]\n",
+                      domain, ret, strerror(ret)));
+            goto fail;
+        }
+
+        ret = sysdb_domain_init(ctx, ctx->domains, DB_PATH, &db_ctx);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not initialize connection to the sysdb\n"));
+            goto fail;
+        }
+
+        ret = sysdb_list_init(ctx, DB_PATH, db_ctx, &ctx->sysdb_list);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not initialize the list of connections\n"));
+            goto fail;
+        }
+    } else {
+        ret = sysdb_init(ctx, ctx->confdb, NULL, false, &ctx->sysdb_list);
+        if (ret != EOK) {
+            DEBUG(1, ("Could not initialize connection to the sysdb\n"));
+            goto fail;
+        }
+    }
+
+    return EOK;
+fail:
+    if (ctx->confdb) talloc_zfree(ctx->confdb);
+    if (ctx->domains) talloc_zfree(ctx->domains);
+    if (ctx->sysdb_list) {
+        talloc_zfree(ctx->sysdb_list);
+    } else {
+        if (db_ctx) talloc_free(db_ctx);
+    }
+    return ret;
+}
+
+errno_t init_context(struct cache_tool_ctx **tctx, int argc, const char *argv[])
+{
+    struct cache_tool_ctx *ctx;
+    enum invalidate_db idb = INVALIDATE_NONE;
+    char *user = NULL;
+    char *group = NULL;
+    char *domain = NULL;
+    int debug;
+    errno_t ret;
+
+    poptContext pc = NULL;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &debug,
+            0, _("The debug level to run with"), NULL },
+        { "user", 'u', POPT_ARG_STRING, &user, 0,
+            _("Invalidate only particular user"), NULL },
+        { "users", 'U', POPT_ARG_NONE, NULL, 'u',
+            _("Only invalidate users"), NULL },
+        { "group", 'g', POPT_ARG_STRING, &group, 0,
+            _("Invalidate only particular group"), NULL },
+        { "groups", 'G', POPT_ARG_NONE, NULL, 'g',
+            _("Only invalidate groups"), NULL },
+        { "domain", 'd', POPT_ARG_STRING, &domain, 0,
+            _("Only invalidate entries from a particular domain"), NULL },
+        POPT_TABLEEND
+    };
+
+    ret = set_locale();
+    if (ret != EOK) {
+        DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
+        ERROR("Error setting the locale\n");
+        ret = EXIT_FAILURE;
+        goto fini;
+    }
+
+    pc = poptGetContext(NULL, argc, argv, long_options, 0);
+    while ((ret = poptGetNextOpt(pc)) > 0) {
+        switch (ret) {
+            case 'u':
+                if (idb == INVALIDATE_GROUPS) {
+                    idb = INVALIDATE_ALL;
+                } else {
+                    idb = INVALIDATE_USERS;
+                }
+                break;
+            case 'g':
+                if (idb == INVALIDATE_USERS) {
+                    idb = INVALIDATE_ALL;
+                } else {
+                    idb = INVALIDATE_GROUPS;
+                }
+                break;
+        }
+    }
+    if (ret != -1) {
+        BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
+    }
+
+    debug_level = debug;
+    debug_prg_name = argv[0];
+    CHECK_ROOT(ret, debug_prg_name);
+
+    ctx = talloc_zero(NULL, struct cache_tool_ctx);
+    if (ctx == NULL) {
+        DEBUG(1, ("Could not allocate memory for tools context\n"));
+        ret = ENOMEM;
+        goto fini;
+    }
+
+    if (idb == INVALIDATE_USERS || idb == INVALIDATE_ALL) {
+        ctx->user_filter = talloc_strdup(ctx, "");
+    } else if (user) {
+        ctx->user_filter = talloc_asprintf(ctx, "(%s=%s)", SYSDB_NAME, user);
+    }
+
+    if (idb == INVALIDATE_GROUPS || idb == INVALIDATE_ALL) {
+        ctx->group_filter = talloc_strdup(ctx, "");
+    } else if (group) {
+        ctx->group_filter = talloc_asprintf(ctx, "(%s=%s)", SYSDB_NAME, group);
+    }
+    if (((idb == INVALIDATE_USERS || idb == INVALIDATE_ALL || user) &&
+            !ctx->user_filter) ||
+        ((idb == INVALIDATE_GROUPS || idb == INVALIDATE_ALL || group) &&
+            !ctx->group_filter)) {
+        DEBUG(1, ("Construction of filters failed\n"));
+        ret = ENOMEM;
+        goto fini;
+    }
+
+    ret = init_domains(ctx, domain);
+    if (ret != EOK) {
+        DEBUG(3, ("Initialization of sysdb connections failed\n"));
+        goto fini;
+    }
+
+    ret = EOK;
+
+fini:
+    poptFreeContext(pc);
+    if (user) free(user);
+    if (group) free(group);
+    if (domain) free(domain);
+    if (ret != EOK && ctx) {
+        talloc_zfree(ctx);
+    }
+    *tctx = ctx;
+    return ret;
+}
-- 
1.7.4.1

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to