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