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