dp_targets.c revision d3dee2a07f1a8ee9ae6f94e149ced754ef76c248
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Pavel Březina <pbrezina@redhat.com>
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher Copyright (C) 2016 Red Hat
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher This program is free software; you can redistribute it and/or modify
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher it under the terms of the GNU General Public License as published by
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher the Free Software Foundation; either version 3 of the License, or
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher (at your option) any later version.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher This program is distributed in the hope that it will be useful,
ea929f1b022fc2cb77dec89b0e12accef983ec85Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
bf9abef629707167d39fcc92ec9c18a6244b27b8Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
bf9abef629707167d39fcc92ec9c18a6244b27b8Jakub Hrozek GNU General Public License for more details.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher You should have received a copy of the GNU General Public License
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher#define DP_TARGET_INIT_FN "sssm_%s_%s_init"
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagherbool _dp_target_enabled(struct data_provider *provider,
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher if (provider == NULL || provider->targets == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher while ((type = va_arg(ap, enum dp_targets)) != DP_TARGET_SENTINEL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (target == NULL || target->module_name == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE, "Uninitialized target %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcmp(target->module_name, module_name) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstruct dp_module *dp_target_module(struct data_provider *provider,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (provider == NULL || provider->targets == NULL) {
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher if (target >= DP_TARGET_SENTINEL || provider->targets[target] == NULL) {
ea929f1b022fc2cb77dec89b0e12accef983ec85Jakub Hrozekconst char *dp_target_to_string(enum dp_targets target)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "auth";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "access";
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher return "chpass";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "sudo";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "autofs";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "selinux";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return "hostid";
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher return "subdomains";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherbool dp_target_initialized(struct dp_target **targets, enum dp_targets type)
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher if (targets == NULL || targets[type] == NULL) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic bool dp_target_sudo_enabled(struct be_ctx *be_ctx)
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Do not disable it in case of error. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string_as_list(be_ctx->cdb, tmp_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_MONITOR_ACTIVE_SERVICES, &services);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to read from confdb [%d]: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher CONFDB_DOMAIN_SUDO_PROVIDER, NULL, &module);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to read from confdb [%d]: %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "SUDO is not listed in services, "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "disabling SUDO module.\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (strcmp(module, DP_NO_PROVIDER) != 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_MINOR_FAILURE, "SUDO provider is set, but it is not "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "listed in active services. SUDO support will not work!\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic const char *dp_target_module_name(struct dp_target **targets,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic const char *dp_target_default_module(struct dp_target **targets,
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher return "permit";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return dp_target_module_name(targets, DPT_AUTH);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return dp_target_module_name(targets, DPT_ID);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagherstatic errno_t dp_target_run_constructor(struct dp_target *target,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher fn_name = talloc_asprintf(target, DP_TARGET_INIT_FN,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher fn = (dp_target_init_fn)dlsym(target->module->libhandle, fn_name);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Executing target [%s] constructor\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = fn(target, be_ctx, target->module->module_data, target->methods);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Target [%s] constructor failed "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "[%d]: %s\n", target->name, ret, sss_strerror(ret));
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher if (error == NULL || !target->explicitly_configured) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Not found. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load target [%s] "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "constructor: %s\n", target->name, error);
bf9abef629707167d39fcc92ec9c18a6244b27b8Jakub Hrozekstatic errno_t dp_target_special(struct be_ctx *be_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcasecmp(module_name, DP_NO_PROVIDER) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Target [%s] is explicitly disabled.\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (strcmp(module_name, DP_ACCESS_PERMIT) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dp_set_method(target->methods, DPM_ACCESS_HANDLER,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dp_access_permit_handler_send, dp_access_permit_handler_recv, NULL,
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher void, struct pam_data, struct pam_data *);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher if (strcmp(module_name, DP_ACCESS_DENY) == 0) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dp_set_method(target->methods, DPM_ACCESS_HANDLER,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher dp_access_deny_handler_send, dp_access_deny_handler_recv, NULL,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher void, struct pam_data, struct pam_data *);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t dp_target_init(struct be_ctx *be_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "Initializing target [%s] with module [%s]\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* We have already name, module name and target set. We just load
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher * the module and initialize it. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher target->methods = talloc_zero_array(target, struct dp_method,
ea929f1b022fc2cb77dec89b0e12accef983ec85Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher /* Handle special cases that do not require opening a module. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = dp_target_special(be_ctx, target, target->module_name);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Load module first. Memory context is modules, not target here. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher target->module = dp_load_module(modules, be_ctx, provider, modules,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load module %s\n",
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Run constructor. */
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher ret = dp_target_run_constructor(target, be_ctx);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!target->explicitly_configured && (ret == ELIBBAD || ret == ENOTSUP)) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Target not found but it wasn't explicitly
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher * configured so we shall just continue. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Target [%s] is not supported by "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "module [%s].\n", target->name, target->module_name);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagherstatic char *dp_get_module_name(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher option = talloc_asprintf(mem_ctx, DP_PROVIDER_OPT, name);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = confdb_get_string(confdb_ctx, mem_ctx, conf_path,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read provider value "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher default_module = dp_target_default_module(targets, type);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher return talloc_strdup(mem_ctx, default_module);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t dp_load_configuration(struct confdb_ctx *cdb,
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher for (type = 0; type < DP_TARGET_SENTINEL; type++) {
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher module = dp_get_module_name(NULL, cdb, conf_path, targets,
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "No provider is specified for"
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher DEBUG(SSSDBG_CONF_SETTINGS, "Using [%s] provider for [%s]\n",
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher targets[type]->explicitly_configured = is_default == false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher targets[type]->module_name = talloc_steal(targets[type], module);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagherstatic errno_t dp_load_targets(struct be_ctx *be_ctx,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher /* We load the configuration first and store module name to each target.
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * This way we ensure that we have this information available during
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher * module initialization. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = dp_load_configuration(be_ctx->cdb, be_ctx->conf_path, targets);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Unable to load DP configuration "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher for (type = 0; type < DP_TARGET_SENTINEL; type++) {
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher ret = dp_target_init(be_ctx, provider, modules, targets[type]);
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE, "Unable to load target [%s] "
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher "[%d]: %s.\n", targets[type]->name, ret, sss_strerror(ret));
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallaghererrno_t dp_init_targets(TALLOC_CTX *mem_ctx,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher /* Even though we know the exact number of targets we will allocate
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher * them all dynamically so we can have correct talloc hierarchy where
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher * all private data are attached to the target they belong to. */
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher targets = talloc_zero_array(mem_ctx, struct dp_target *,
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher for (type = 0; type != DP_TARGET_SENTINEL; type++) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher targets[type] = talloc_zero(targets, struct dp_target);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher /* We want this to be already available. */