/* SSSD sss_cache Copyright (C) Jan Zeleny 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 . */ #include #include #include #include #include #include "util/util.h" #include "tools/sss_sync_ops.h" #include "db/sysdb.h" #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 #define INVALIDATE_GROUPS 2 #define INVALIDATE_NETGROUPS 4 #define INVALIDATE_SERVICES 8 #define INVALIDATE_AUTOFSMAPS 16 #define INVALIDATE_SSH_HOSTS 32 #define INVALIDATE_SUDO_RULES 64 #ifdef BUILD_AUTOFS #ifdef BUILD_SSH #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_AUTOFSMAPS | INVALIDATE_SSH_HOSTS ) #else /* BUILD_SSH */ #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_AUTOFSMAPS ) #endif /* BUILD_SSH */ #else /* BUILD_AUTOFS */ #ifdef BUILD_SSH #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_SSH_HOSTS ) #else /* BUILD_SSH */ #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES ) #endif /* BUILD_SSH */ #endif /* BUILD_AUTOFS */ enum sss_cache_entry { TYPE_USER=0, TYPE_GROUP, TYPE_NETGROUP, TYPE_SERVICE, TYPE_AUTOFSMAP, TYPE_SSH_HOST, TYPE_SUDO_RULE }; static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); struct input_values { char *domain; char *group; char *map; char *netgroup; char *service; char *ssh_host; char *sudo_rule; char *user; }; struct cache_tool_ctx { struct confdb_ctx *confdb; struct sss_domain_info *domains; char *user_filter; char *group_filter; char *netgroup_filter; char *service_filter; char *autofs_filter; char *ssh_host_filter; char *sudo_rule_filter; char *user_name; char *group_name; char *netgroup_name; char *service_name; char *autofs_name; char *ssh_host_name; char *sudo_rule_name; bool update_user_filter; bool update_group_filter; bool update_netgroup_filter; bool update_service_filter; bool update_autofs_filter; bool update_ssh_host_filter; bool update_sudo_rule_filter; }; static void free_input_values(struct input_values *values); static bool is_filter_valid(struct cache_tool_ctx *ctx, struct input_values *values, int idb); static errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain); static errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx); static errno_t invalidate_entry(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name, int entry_type); static bool invalidate_entries(TALLOC_CTX *ctx, struct sss_domain_info *dinfo, enum sss_cache_entry entry_type, const char *filter, const char *name); static errno_t update_all_filters(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo); int main(int argc, const char *argv[]) { errno_t ret; struct cache_tool_ctx *tctx = NULL; struct sysdb_ctx *sysdb; bool skipped = true; struct sss_domain_info *dinfo; ret = init_context(argc, argv, &tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error initializing context for the application\n"); goto done; } for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, SSS_GND_DESCEND)) { if (!IS_SUBDOMAIN(dinfo)) { /* Update list of subdomains for this domain */ ret = sysdb_update_subdomains(dinfo); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update subdomains for domain %s.\n", dinfo->name); } } sysdb = dinfo->sysdb; /* Update filters for each domain */ ret = update_all_filters(tctx, dinfo); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update filters.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not start the transaction!\n"); goto done; } skipped &= !invalidate_entries(tctx, dinfo, TYPE_USER, tctx->user_filter, tctx->user_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_GROUP, tctx->group_filter, tctx->group_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_NETGROUP, tctx->netgroup_filter, tctx->netgroup_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_SERVICE, tctx->service_filter, tctx->service_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP, tctx->autofs_filter, tctx->autofs_name); 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) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit the transaction!\n"); ret = sysdb_transaction_cancel(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } } if (skipped == true) { ERROR("No cache object matched the specified search\n"); ret = ENOENT; goto done; } else { ret = sss_memcache_clear_all(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear memory cache.\n"); goto done; } } ret = EOK; done: if (tctx) talloc_free(tctx); return ret; } static void free_input_values(struct input_values *values) { free(values->domain); free(values->group); free(values->map); free(values->netgroup); free(values->service); free(values->ssh_host); free(values->sudo_rule); free(values->user); } static errno_t update_filter(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo, char *name, bool update, const char *fmt, enum sss_cache_entry entry_type, bool force_case_sensitivity, char **_filter) { errno_t ret; char *parsed_domain = NULL; char *parsed_name = NULL; TALLOC_CTX *tmp_ctx = NULL; char *use_name = NULL; char *filter; char *sanitized; char *lc_sanitized; if (!name || !update) { /* Nothing to do */ return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return ENOMEM; } ret = sss_parse_name(tmp_ctx, dinfo->names, name, &parsed_domain, &parsed_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_name failed\n"); goto done; } if (parsed_domain != NULL && strcasecmp(dinfo->name, parsed_domain) != 0) { /* We were able to parse the domain from given fqdn, but it * does not match with currently processed domain. */ filter = NULL; ret = EOK; goto done; } if (!dinfo->case_sensitive && !force_case_sensitivity) { use_name = sss_tc_utf8_str_tolower(tmp_ctx, parsed_name); if (!use_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } } else { use_name = parsed_name; } switch (entry_type) { case TYPE_USER: case TYPE_GROUP: use_name = sss_create_internal_fqname(tmp_ctx, use_name, dinfo->name); default: break; } if (!use_name) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, use_name, dinfo, &sanitized, &lc_sanitized); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to sanitize the given name.\n"); goto done; } if (fmt) { if (!dinfo->case_sensitive && !force_case_sensitivity) { filter = talloc_asprintf(tmp_ctx, "(|(%s=%s)(%s=%s))", SYSDB_NAME_ALIAS, lc_sanitized, SYSDB_NAME_ALIAS, sanitized); } else { filter = talloc_asprintf(tmp_ctx, fmt, SYSDB_NAME, sanitized); } } else { filter = talloc_strdup(tmp_ctx, sanitized); } if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { talloc_free(*_filter); *_filter = talloc_steal(tctx, filter); } talloc_free(tmp_ctx); return ret; } /* This function updates all filters for specified domain using this * domains regex to parse string into domain and name (if exists). */ static errno_t update_all_filters(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo) { errno_t ret; /* Update user filter */ ret = update_filter(tctx, dinfo, tctx->user_name, tctx->update_user_filter, "(%s=%s)", TYPE_USER, false, &tctx->user_filter); if (ret != EOK) { return ret; } /* Update group filter */ ret = update_filter(tctx, dinfo, tctx->group_name, tctx->update_group_filter, "(%s=%s)", TYPE_GROUP, false, &tctx->group_filter); if (ret != EOK) { return ret; } /* Update netgroup filter */ ret = update_filter(tctx, dinfo, tctx->netgroup_name, tctx->update_netgroup_filter, "(%s=%s)", TYPE_NETGROUP, false, &tctx->netgroup_filter); if (ret != EOK) { return ret; } /* Update service filter */ ret = update_filter(tctx, dinfo, tctx->service_name, tctx->update_service_filter, "(%s=%s)", TYPE_SERVICE, false, &tctx->service_filter); if (ret != EOK) { return ret; } /* Update autofs filter */ ret = update_filter(tctx, dinfo, tctx->autofs_name, tctx->update_autofs_filter, "(&(objectclass="SYSDB_AUTOFS_MAP_OC")(%s=%s))", TYPE_AUTOFSMAP, true, &tctx->autofs_filter); if (ret != EOK) { return ret; } /* Update ssh host filter */ ret = update_filter(tctx, dinfo, tctx->ssh_host_name, tctx->update_ssh_host_filter, "(%s=%s)", TYPE_SSH_HOST, false, &tctx->ssh_host_filter); if (ret != EOK) { return ret; } /* Update sudo rule filter */ ret = update_filter(tctx, dinfo, tctx->sudo_rule_name, tctx->update_sudo_rule_filter, "(%s=%s)", TYPE_SUDO_RULE, false, &tctx->sudo_rule_filter); if (ret != EOK) { return ret; } return EOK; } static bool invalidate_entries(TALLOC_CTX *ctx, struct sss_domain_info *dinfo, enum sss_cache_entry entry_type, const char *filter, const char *name) { const char *attrs[] = {SYSDB_NAME, NULL}; size_t msg_count; struct ldb_message **msgs; const char *type_string = "unknown"; errno_t ret = EINVAL; int i; const char *c_name; bool iret; if (!filter) return false; switch (entry_type) { case TYPE_USER: type_string = "user"; ret = sysdb_search_users(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_GROUP: type_string = "group"; ret = sysdb_search_groups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_NETGROUP: type_string = "netgroup"; ret = sysdb_search_netgroups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_SERVICE: type_string = "service"; ret = sysdb_search_services(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_AUTOFSMAP: type_string = "autofs map"; ret = search_autofsmaps(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_SSH_HOST: type_string = "ssh_host"; #ifdef BUILD_SSH ret = sysdb_search_ssh_hosts(ctx, dinfo, filter, attrs, &msg_count, &msgs); #else /* BUILD_SSH */ 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) { if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "'%s' %s: Not found in domain '%s'\n", type_string, name ? name : "", dinfo->name); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Searching for %s in domain %s with filter %s failed\n", type_string, dinfo->name, filter); } return false; } iret = true; for (i = 0; i < msg_count; i++) { c_name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (c_name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Something bad happened, can't find attribute %s\n", SYSDB_NAME); ERROR("Couldn't invalidate %1$s\n", type_string); iret = false; } else { ret = invalidate_entry(ctx, dinfo, c_name, entry_type); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't invalidate %s %s\n", type_string, c_name); ERROR("Couldn't invalidate %1$s %2$s\n", type_string, c_name); iret = false; } } } talloc_zfree(msgs); return iret; } static errno_t invalidate_entry(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name, int entry_type) { struct sysdb_attrs *sys_attrs = NULL; errno_t ret; sys_attrs = sysdb_new_attrs(ctx); if (sys_attrs) { ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1); if (ret == EOK) { switch (entry_type) { case TYPE_USER: /* For users, we also need to reset the initgroups * cache expiry */ ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_INITGR_EXPIRE, 1); if (ret != EOK) return ret; ret = sysdb_set_user_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_GROUP: ret = sysdb_set_group_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_NETGROUP: ret = sysdb_set_netgroup_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_SERVICE: ret = sysdb_set_service_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_AUTOFSMAP: ret = sysdb_set_autofsmap_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_SSH_HOST: #ifdef BUILD_SSH ret = sysdb_set_ssh_host_attr(domain, name, sys_attrs, SYSDB_MOD_REP); #else /* BUILD_SSH */ 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; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not set entry attributes\n"); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add expiration time to attributes\n"); } talloc_zfree(sys_attrs); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n"); ret = ENOMEM; } return ret; } static errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain) { char *confdb_path; int ret; struct sss_domain_info *dinfo; 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(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); return ret; } if (domain) { ret = sssd_domain_init(ctx, ctx->confdb, domain, DB_PATH, &ctx->domains); if (ret != EOK) { SYSDB_VERSION_ERROR(ret); DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } } else { ret = confdb_get_domains(ctx->confdb, &ctx->domains); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize domains\n"); return ret; } ret = sysdb_init(ctx, ctx->domains); SYSDB_VERSION_ERROR(ret); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } } for (dinfo = ctx->domains; dinfo; dinfo = get_next_domain(dinfo, 0)) { ret = sss_names_init(ctx, ctx->confdb, dinfo->name, &dinfo->names); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n"); return ret; } } return EOK; } static errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx) { struct cache_tool_ctx *ctx = NULL; int idb = INVALIDATE_NONE; struct input_values values = { 0 }; int debug = SSSDBG_DEFAULT; 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 }, { "everything", 'E', POPT_ARG_NONE, NULL, 'e', _("Invalidate all cached entries"), NULL }, { "user", 'u', POPT_ARG_STRING, &(values.user), 0, _("Invalidate particular user"), NULL }, { "users", 'U', POPT_ARG_NONE, NULL, 'u', _("Invalidate all users"), NULL }, { "group", 'g', POPT_ARG_STRING, &(values.group), 0, _("Invalidate particular group"), NULL }, { "groups", 'G', POPT_ARG_NONE, NULL, 'g', _("Invalidate all groups"), NULL }, { "netgroup", 'n', POPT_ARG_STRING, &(values.netgroup), 0, _("Invalidate particular netgroup"), NULL }, { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n', _("Invalidate all netgroups"), NULL }, { "service", 's', POPT_ARG_STRING, &(values.service), 0, _("Invalidate particular service"), NULL }, { "services", 'S', POPT_ARG_NONE, NULL, 's', _("Invalidate all services"), NULL }, #ifdef BUILD_AUTOFS { "autofs-map", 'a', POPT_ARG_STRING, &(values.map), 0, _("Invalidate particular autofs map"), NULL }, { "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a', _("Invalidate all autofs maps"), NULL }, #endif /* BUILD_AUTOFS */ #ifdef BUILD_SSH { "ssh-host", 'h', POPT_ARG_STRING, &(values.ssh_host), 0, _("Invalidate particular SSH host"), NULL }, { "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, &(values.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, &(values.domain), 0, _("Only invalidate entries from a particular domain"), NULL }, POPT_TABLEEND }; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "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; case 's': idb |= INVALIDATE_SERVICES; break; case 'a': idb |= INVALIDATE_AUTOFSMAPS; break; case 'h': idb |= INVALIDATE_SSH_HOSTS; break; case 'r': idb |= INVALIDATE_SUDO_RULES; break; case 'e': idb = INVALIDATE_EVERYTHING; #ifdef BUILD_SUDO idb |= INVALIDATE_SUDO_RULES; #endif /* BUILD_SUDO */ break; } } DEBUG_CLI_INIT(debug); debug_prg_name = argv[0]; if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } if (poptGetArg(pc)) { BAD_POPT_PARAMS(pc, _("Unexpected argument(s) provided, options that " "invalidate a single object only accept a single " "provided argument.\n"), ret, fini); } if (idb == INVALIDATE_NONE && !values.user && !values.group && !values.netgroup && !values.service && !values.map && !values.ssh_host && !values.sudo_rule) { BAD_POPT_PARAMS(pc, _("Please select at least one object to invalidate\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ctx = talloc_zero(NULL, struct cache_tool_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "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); ctx->update_user_filter = false; } else if (values.user) { ctx->user_name = talloc_strdup(ctx, values.user); ctx->update_user_filter = true; } if (idb & INVALIDATE_GROUPS) { ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_group_filter = false; } else if (values.group) { ctx->group_name = talloc_strdup(ctx, values.group); ctx->update_group_filter = true; } if (idb & INVALIDATE_NETGROUPS) { ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_netgroup_filter = false; } else if (values.netgroup) { ctx->netgroup_name = talloc_strdup(ctx, values.netgroup); ctx->update_netgroup_filter = true; } if (idb & INVALIDATE_SERVICES) { ctx->service_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_service_filter = false; } else if (values.service) { ctx->service_name = talloc_strdup(ctx, values.service); ctx->update_service_filter = true; } if (idb & INVALIDATE_AUTOFSMAPS) { ctx->autofs_filter = talloc_asprintf(ctx, "(&(objectclass=%s)(%s=*))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME); ctx->update_autofs_filter = false; } else if (values.map) { ctx->autofs_name = talloc_strdup(ctx, values.map); ctx->update_autofs_filter = true; } if (idb & INVALIDATE_SSH_HOSTS) { ctx->ssh_host_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_ssh_host_filter = false; } else if (values.ssh_host) { ctx->ssh_host_name = talloc_strdup(ctx, values.ssh_host); 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 (values.sudo_rule) { ctx->sudo_rule_name = talloc_strdup(ctx, values.sudo_rule); ctx->update_sudo_rule_filter = true; } if (is_filter_valid(ctx, &values, idb) == false) { DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n"); ret = ENOMEM; goto fini; } ret = init_domains(ctx, values.domain); if (ret != EOK) { if (values.domain) { ERROR("Could not open domain %1$s. If the domain is a subdomain " "(trusted domain), use fully qualified name instead of " "--domain/-d parameter.\n", values.domain); } else { ERROR("Could not open available domains\n"); } DEBUG(SSSDBG_OP_FAILURE, "Initialization of sysdb connections failed\n"); goto fini; } ret = EOK; fini: poptFreeContext(pc); free_input_values(&values); if (ret != EOK && ctx) { talloc_zfree(ctx); } if (ret == EOK) { *tctx = ctx; } return ret; } static bool is_filter_valid(struct cache_tool_ctx *ctx, struct input_values *values, int idb) { if ((idb & INVALIDATE_USERS) && ctx->user_filter == NULL) { return false; } if ((idb & INVALIDATE_GROUPS) && ctx->group_filter == NULL) { return false; } if ((idb & INVALIDATE_NETGROUPS) && ctx->netgroup_filter == NULL) { return false; } if ((idb & INVALIDATE_SERVICES) && ctx->service_filter == NULL) { return false; } if ((idb & INVALIDATE_AUTOFSMAPS) && ctx->autofs_filter == NULL) { return false; } if ((idb & INVALIDATE_SSH_HOSTS) && ctx->ssh_host_filter == NULL) { return false; } if (values->user && ctx->user_name == NULL) { return false; } if (values->group && ctx->group_name == NULL) { return false; } if (values->netgroup && ctx->netgroup_name == NULL) { return false; } if (values->service && ctx->service_name == NULL) { return false; } if (values->map && ctx->autofs_name == NULL) { return false; } if (values->ssh_host && ctx->ssh_host_name == NULL) { return false; } if (values->sudo_rule && ctx->sudo_rule_name == NULL) { return false; } return true; } static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { #ifdef BUILD_AUTOFS return sysdb_search_custom(mem_ctx, domain, sub_filter, AUTOFS_MAP_SUBDIR, attrs, msgs_count, msgs); #else return ENOSYS; #endif /* BUILD_AUTOFS */ }