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