I'm sending corrected patch. I have one comment though.

Jakub Hrozek <jhro...@redhat.com> wrote:
> Allocation error is a serious one and should be handled.
> 

I don't think we should handle it differently (how?). After all it is handled 
the same way like if allocation error occurred let's say in 
sysdb_search_netgroups().

Jan
From 6f59aa750766c214955a3775585f080714fee889 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Wed, 13 Apr 2011 08:16:37 -0400
Subject: [PATCH 1/2] Cache cleaning tool

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

diff --git a/Makefile.am b/Makefile.am
index d8eb28d3ef507bc72439ae95dfc335d60139fc5d..014293dfd4d07ca1f1cf383307b1350a29bbbffb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -54,7 +54,8 @@ sbin_PROGRAMS = \
     sss_groupdel \
     sss_usermod \
     sss_groupmod \
-    sss_groupshow
+    sss_groupshow \
+    sss_cache
 
 sssdlibexec_PROGRAMS = \
     sssd_nss \
@@ -476,6 +477,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..54523dd07bf20576091a684a79fd047b7ed8b0aa
--- /dev/null
+++ b/src/tools/sss_cache.c
@@ -0,0 +1,354 @@
+/*
+   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"
+
+#define INVALIDATE_NONE 0
+#define INVALIDATE_USERS 1
+#define INVALIDATE_GROUPS 2
+#define INVALIDATE_NETGROUPS 4
+
+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;
+    char *netgroup_filter;
+};
+
+errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain);
+errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx);
+
+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};
+    struct sysdb_attrs *sys_attrs = NULL;
+    size_t msg_count;
+    struct ldb_message **msgs;
+    const char *c_name;
+
+    ret = init_context(argc, argv, &tctx);
+    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, ("Searching for 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(3, ("Something bad happened, 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(3, ("Couldn't invalidate user %s", c_name));
+                        ERROR("Couldn't invalidate user %s", c_name);
+                    }
+                }
+            }
+            talloc_zfree(msgs);
+        }
+
+        if (tctx->group_filter) {
+            ret = sysdb_search_groups(tctx, sysdb, NULL, tctx->group_filter,
+                                      attrs, &msg_count, &msgs);
+            if (ret != EOK) {
+                DEBUG(3, ("Searching for groups with filter %s failed\n",
+                          tctx->group_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(3, ("Something bad happened, can't find attribute %s",
+                          SYSDB_NAME));
+                } else {
+                    ret = sysdb_store_group(tctx, sysdb, NULL, c_name, 0, NULL, 0);
+                    if (ret != EOK) {
+                        DEBUG(3, ("Couldn't invalidate group %s", c_name));
+                        ERROR("Couldn't invalidate group %s", c_name);
+                    }
+                }
+            }
+            talloc_zfree(msgs);
+        }
+
+        if (tctx->netgroup_filter) {
+            ret = sysdb_search_netgroups(tctx, sysdb, NULL, tctx->netgroup_filter,
+                                         attrs, &msg_count, &msgs);
+            if (ret != EOK) {
+                DEBUG(3, ("Searching for netgroups with filter %s failed\n",
+                          tctx->netgroup_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 happened, can't find attribute %s",
+                              SYSDB_NAME));
+                } else {
+
+                    sys_attrs = sysdb_new_attrs(tctx);
+                    if (sys_attrs) {
+                        ret = sysdb_attrs_add_time_t(sys_attrs,
+                                                     SYSDB_CACHE_EXPIRE, 0);
+                        if (ret == EOK) {
+                            ret = sysdb_set_netgroup_attr(sysdb, NULL, c_name,
+                                                          sys_attrs,
+                                                          SYSDB_MOD_REP);
+                            if (ret != EOK) {
+                                DEBUG(3, ("Could not invalidate netgroup %s\n",
+                                          c_name));
+                                ERROR("Could not invalidate netgroup %s\n",
+                                      c_name);
+                            }
+                        } else {
+                            DEBUG(3, ("Could not add expiration time to "
+                                      "netgroup attributes\n"));
+                            ERROR("Could not invalidate netgroup %s\n",
+                                  c_name);
+                        }
+                        talloc_zfree(sys_attrs);
+                    } else {
+                        DEBUG(1, ("Could not create sysdb attributes\n"));
+                    }
+                }
+            }
+            talloc_zfree(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(int argc, const char *argv[], struct cache_tool_ctx **tctx)
+{
+    struct cache_tool_ctx *ctx = NULL;
+    int idb = INVALIDATE_NONE;
+    char *user = NULL;
+    char *group = NULL;
+    char *netgroup = NULL;
+    char *domain = NULL;
+    int debug = 0;
+    errno_t ret = EOK;
+
+    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 particular user"), NULL },
+        { "users", 'U', POPT_ARG_NONE, NULL, 'u',
+            _("Invalidate all users"), NULL },
+        { "group", 'g', POPT_ARG_STRING, &group, 0,
+            _("Invalidate particular group"), NULL },
+        { "groups", 'G', POPT_ARG_NONE, NULL, 'g',
+            _("Invalidate all groups"), NULL },
+        { "netgroup", 'n', POPT_ARG_STRING, &netgroup, 0,
+            _("Invalidate particular netgroup"), NULL },
+        { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n',
+            _("Invalidate all netgroups"), 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");
+        goto fini;
+    }
+
+    pc = poptGetContext(NULL, argc, argv, long_options, 0);
+    while ((ret = poptGetNextOpt(pc)) > 0) {
+        switch (ret) {
+            case 'u':
+                idb |= INVALIDATE_USERS;
+                break;
+            case 'g':
+                idb |= INVALIDATE_GROUPS;
+                break;
+            case 'n':
+                idb |= INVALIDATE_NETGROUPS;
+                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) {
+        ctx->user_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
+    } else if (user) {
+        ctx->user_filter = talloc_asprintf(ctx, "(%s=%s)", SYSDB_NAME, user);
+    }
+
+    if (idb & INVALIDATE_GROUPS) {
+        ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
+    } else if (group) {
+        ctx->group_filter = talloc_asprintf(ctx, "(%s=%s)", SYSDB_NAME, group);
+    }
+
+    if (idb & INVALIDATE_NETGROUPS) {
+        ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
+    } else if (netgroup) {
+        ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=%s)", SYSDB_NAME,
+                                               netgroup);
+    }
+    if (((idb & INVALIDATE_USERS || user) && !ctx->user_filter) ||
+        ((idb & INVALIDATE_GROUPS || group) && !ctx->group_filter) ||
+        ((idb & INVALIDATE_NETGROUPS || netgroup) && !ctx->netgroup_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);
+    free(user);
+    free(group);
+    free(netgroup);
+    free(domain);
+    if (ret != EOK && ctx) {
+        talloc_zfree(ctx);
+    }
+    if (ret == EOK) {
+        *tctx = ctx;
+    }
+    return ret;
+}
-- 
1.7.4.1

From f9269410afbd111a7fa32b53a4402d773530e1f8 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzel...@redhat.com>
Date: Fri, 15 Apr 2011 12:57:04 -0400
Subject: [PATCH 2/2] Man page for sss_cache

---
 src/man/Makefile.am     |    2 +-
 src/man/sss_cache.8.xml |  122 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletions(-)
 create mode 100644 src/man/sss_cache.8.xml

diff --git a/src/man/Makefile.am b/src/man/Makefile.am
index f84cc2f461f083914e8431e7e779bc12949b357d..24acb06f470a326aeeac000eb965e3c53b2020d2 100644
--- a/src/man/Makefile.am
+++ b/src/man/Makefile.am
@@ -17,7 +17,7 @@ man_MANS = \
     sssd.8 sssd.conf.5 sssd-ldap.5 \
     sssd-krb5.5 sssd-ipa.5 sssd-simple.5 \
     sssd_krb5_locator_plugin.8 sss_groupshow.8 \
-    pam_sss.8 sss_obfuscate.8
+    pam_sss.8 sss_obfuscate.8 sss_cache.8
 EXTRA_DIST = $(man_MANS:%=%.xml) $(wildcard $(srcdir)/include/*.xml)
 
 SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8
diff --git a/src/man/sss_cache.8.xml b/src/man/sss_cache.8.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f30d00d6c808ea2f866c2f2225079027b1e15c6c
--- /dev/null
+++ b/src/man/sss_cache.8.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd";>
+<reference>
+<title>SSSD Manual pages</title>
+<refentry>
+    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"; href="include/upstream.xml" />
+
+    <refmeta>
+        <refentrytitle>sss_cache</refentrytitle>
+        <manvolnum>8</manvolnum>
+    </refmeta>
+
+    <refnamediv id='name'>
+        <refname>sss_cache</refname>
+        <refpurpose>perform cache cleanup</refpurpose>
+    </refnamediv>
+
+    <refsynopsisdiv id='synopsis'>
+        <cmdsynopsis>
+            <command>sss_cache</command>
+            <arg choice='opt'>
+                <replaceable>options</replaceable>
+            </arg>
+        </cmdsynopsis>
+    </refsynopsisdiv>
+
+    <refsect1 id='description'>
+        <title>DESCRIPTION</title>
+        <para>
+            <command>sss_cache</command> invalidates records in SSSD cache.
+            Invalidated records are forced to be reloaded from server as soon
+            as related SSSD backend is online.
+        </para>
+    </refsect1>
+
+    <refsect1 id='options'>
+        <title>OPTIONS</title>
+        <variablelist remap='IP'>
+            <varlistentry>
+                <term>
+                    <option>-u</option>,<option>--user</option>
+                    <replaceable>login</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate specific user.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-U</option>,<option>--users</option>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate all user records. This option overrides
+                        invalidation of specific user if it was also set.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-g</option>,<option>--group</option>
+                    <replaceable>group</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate specific group.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-G</option>,<option>--groups</option>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate all group records. This option overrides
+                        invalidation of specific group if it was also set.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-n</option>,<option>--netgroup</option>
+                    <replaceable>netgroup</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate specific netgroup.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-N</option>,<option>--netgroups</option>
+                </term>
+                <listitem>
+                    <para>
+                        Invalidate all netgroup records. This option overrides
+                        invalidation of specific netgroup if it was also set.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <varlistentry>
+                <term>
+                    <option>-d</option>,<option>--domain</option>
+                    <replaceable>domain</replaceable>
+                </term>
+                <listitem>
+                    <para>
+                        Restrict invalidation process only to a particular
+                        domain.
+                    </para>
+                </listitem>
+            </varlistentry>
+            <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"; href="include/param_help.xml" />
+        </variablelist>
+    </refsect1>
+</refentry>
+</reference>
-- 
1.7.4.1

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

Reply via email to