dp_targets.c revision e98d085b529e0ae5e07a717ce3b30f3943be0ee0
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Authors:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Pavel Březina <pbrezina@redhat.com>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Copyright (C) 2016 Red Hat
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster This program is free software; you can redistribute it and/or modify
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster it under the terms of the GNU General Public License as published by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster the Free Software Foundation; either version 3 of the License, or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (at your option) any later version.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster This program is distributed in the hope that it will be useful,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster but WITHOUT ANY WARRANTY; without even the implied warranty of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster GNU General Public License for more details.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster You should have received a copy of the GNU General Public License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster along with this program. If not, see <http://www.gnu.org/licenses/>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster*/
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <talloc.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include <dlfcn.h>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "config.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "providers/data_provider/dp.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "providers/data_provider/dp_private.h"
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major#include "providers/data_provider/dp_builtin.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "providers/backend.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#include "util/util.h"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define DP_TARGET_INIT_FN "sssm_%s_%s_init"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define DP_PROVIDER_OPT "%s_provider"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define DP_ACCESS_PERMIT "permit"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define DP_ACCESS_DENY "deny"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster#define DP_NO_PROVIDER "none"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterbool _dp_target_enabled(struct data_provider *provider,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster const char *module_name,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ...)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster struct dp_target *target;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster enum dp_targets type;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster va_list ap;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster bool bret;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (provider == NULL || provider->targets == NULL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster bret = false;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major va_start(ap, module_name);
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major while ((type = va_arg(ap, enum dp_targets)) != DP_TARGET_SENTINEL) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major target = provider->targets[type];
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major if (target == NULL || target->module_name == NULL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DEBUG(SSSDBG_MINOR_FAILURE, "Uninitialized target %s\n",
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major dp_target_to_string(type));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster continue;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major if (module_name == NULL) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major bret = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster goto done;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major if (strcmp(target->module_name, module_name) == 0) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major bret = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster goto done;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Majordone:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster va_end(ap);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return bret;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstruct dp_module *dp_target_module(struct data_provider *provider,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster enum dp_targets target)
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (provider == NULL || provider->targets == NULL) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return NULL;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (target >= DP_TARGET_SENTINEL || provider->targets[target] == NULL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return provider->targets[target]->module;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fostervoid *dp_get_module_data(struct dp_module *dp_module)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return dp_module == NULL ? NULL : dp_module->module_data;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterconst char *dp_target_to_string(enum dp_targets target)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster switch (target) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major case DPT_ID:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "id";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_AUTH:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "auth";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_ACCESS:
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return "access";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_CHPASS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "chpass";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_SUDO:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "sudo";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_AUTOFS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "autofs";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_SELINUX:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "selinux";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_HOSTID:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "hostid";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_SUBDOMAINS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "subdomains";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DP_TARGET_SENTINEL:
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return NULL;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterbool dp_target_initialized(struct dp_target **targets, enum dp_targets type)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (targets == NULL || targets[type] == NULL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return targets[type]->initialized;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic const char *dp_target_module_name(struct dp_target **targets,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster enum dp_targets type)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (targets[type] == NULL) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return targets[type]->module_name;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic const char *dp_target_default_module(struct dp_target **targets,
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major enum dp_targets target)
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major{
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster switch (target) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major case DPT_ID:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_ACCESS:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "permit";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster case DPT_CHPASS:
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major return dp_target_module_name(targets, DPT_AUTH);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major case DP_TARGET_SENTINEL:
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major return NULL;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major default:
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major return dp_target_module_name(targets, DPT_ID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major }
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major}
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Majorstatic errno_t dp_target_run_constructor(struct dp_target *target,
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major struct be_ctx *be_ctx)
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major{
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major char *fn_name = NULL;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major dp_target_init_fn fn;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major char *error;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major errno_t ret;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major fn_name = talloc_asprintf(target, DP_TARGET_INIT_FN,
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major target->module->name, target->name);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (fn_name == NULL) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major return ENOMEM;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major }
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major dlerror(); /* clear any error */
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major fn = (dp_target_init_fn)dlsym(target->module->libhandle, fn_name);
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major if (fn != NULL) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major DEBUG(SSSDBG_TRACE_FUNC, "Executing target [%s] constructor\n",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target->name);
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major ret = fn(target, be_ctx, target->module->module_data, target->methods);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ret != EOK) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DEBUG(SSSDBG_FATAL_FAILURE, "Target [%s] constructor failed "
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major "[%d]: %s\n", target->name, ret, sss_strerror(ret));
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major goto done;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster error = dlerror();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (error == NULL || !target->explicitly_configured) {
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major /* Not found. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = ELIBBAD;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster goto done;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* Error. */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load target [%s] "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "constructor: %s\n", target->name, error);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = ELIBBAD;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major goto done;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target->initialized = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ret = EOK;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Majordone:
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major talloc_free(fn_name);
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major return ret;
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major}
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic errno_t dp_target_special(struct be_ctx *be_ctx,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster struct dp_target *target,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster const char *module_name)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster{
03796c5de88f33fc11651a032f0889c6c37d08f5Peter Major if (strcasecmp(module_name, DP_NO_PROVIDER) == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DEBUG(SSSDBG_TRACE_FUNC, "Target [%s] is explicitly disabled.\n",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target->name);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target->initialized = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster target->module = NULL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return EOK;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (target->target == DPT_ACCESS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (strcmp(module_name, DP_ACCESS_PERMIT) == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster dp_set_method(target->methods, DPM_ACCESS_HANDLER,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster dp_access_permit_handler_send, dp_access_permit_handler_recv, NULL,
void, struct pam_data, struct pam_data *);
target->module = NULL;
target->initialized = true;
return EOK;
}
if (strcmp(module_name, DP_ACCESS_DENY) == 0) {
dp_set_method(target->methods, DPM_ACCESS_HANDLER,
dp_access_deny_handler_send, dp_access_deny_handler_recv, NULL,
void, struct pam_data, struct pam_data *);
target->module = NULL;
target->initialized = true;
return EOK;
}
}
return EAGAIN;
}
static errno_t dp_target_init(struct be_ctx *be_ctx,
struct data_provider *provider,
struct dp_module **modules,
struct dp_target *target)
{
errno_t ret;
DEBUG(SSSDBG_TRACE_FUNC, "Initializing target [%s] with module [%s]\n",
target->name, target->module_name);
/* We have already name, module name and target set. We just load
* the module and initialize it. */
target->methods = talloc_zero_array(target, struct dp_method,
DP_METHOD_SENTINEL + 1);
if (target->methods == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
ret = ENOMEM;
goto done;
}
/* Handle special cases that do not require opening a module. */
ret = dp_target_special(be_ctx, target, target->module_name);
if (ret == EOK || ret != EAGAIN) {
goto done;
}
/* Load module first. Memory context is modules, not target here. */
target->module = dp_load_module(modules, be_ctx, provider, modules,
target->module_name);
if (target->module == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load module %s\n",
target->module_name);
ret = ELIBBAD;
goto done;
}
/* Run constructor. */
ret = dp_target_run_constructor(target, be_ctx);
if (!target->explicitly_configured && (ret == ELIBBAD || ret == ENOTSUP)) {
/* Target not found but it wasn't explicitly
* configured so we shall just continue. */
DEBUG(SSSDBG_CONF_SETTINGS, "Target [%s] is not supported by "
"module [%s].\n", target->name, target->module_name);
ret = EOK;
goto done;
} else if (ret != EOK) {
goto done;
}
ret = EOK;
done:
if (ret != EOK) {
talloc_free(target->methods);
}
return ret;
}
static char *dp_get_module_name(TALLOC_CTX *mem_ctx,
struct confdb_ctx *confdb_ctx,
const char *conf_path,
struct dp_target **targets,
enum dp_targets type,
bool *_is_default)
{
const char *name;
const char *default_module;
char *module;
char *option;
errno_t ret;
name = dp_target_to_string(type);
if (name == NULL) {
return NULL;
}
option = talloc_asprintf(mem_ctx, DP_PROVIDER_OPT, name);
if (option == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
return NULL;
}
ret = confdb_get_string(confdb_ctx, mem_ctx, conf_path,
option, NULL, &module);
talloc_free(option);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read provider value "
"[%d]: %s\n", ret, sss_strerror(ret));
return NULL;
}
if (module != NULL) {
*_is_default = false;
return module;
}
*_is_default = true;
default_module = dp_target_default_module(targets, type);
return talloc_strdup(mem_ctx, default_module);
}
static errno_t dp_load_configuration(struct confdb_ctx *cdb,
const char *conf_path,
struct dp_target **targets)
{
enum dp_targets type;
const char *name;
bool is_default;
char *module;
errno_t ret;
for (type = 0; type < DP_TARGET_SENTINEL; type++) {
name = dp_target_to_string(type);
if (name == NULL) {
ret = ERR_INTERNAL;
goto done;
}
module = dp_get_module_name(NULL, cdb, conf_path, targets,
type, &is_default);
if (module == NULL) {
DEBUG(SSSDBG_CONF_SETTINGS, "No provider is specified for"
" [%s]\n", name);
continue;
} else {
DEBUG(SSSDBG_CONF_SETTINGS, "Using [%s] provider for [%s]\n",
module, name);
}
targets[type]->explicitly_configured = is_default == false;
targets[type]->name = name;
targets[type]->target = type;
targets[type]->module_name = talloc_steal(targets[type], module);
}
ret = EOK;
done:
return ret;
}
static errno_t dp_load_targets(struct be_ctx *be_ctx,
struct data_provider *provider,
struct dp_target **targets,
struct dp_module **modules)
{
enum dp_targets type;
errno_t ret;
/* We load the configuration first and store module name to each target.
* This way we ensure that we have this information available during
* module initialization. */
ret = dp_load_configuration(be_ctx->cdb, be_ctx->conf_path, targets);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to load DP configuration "
"[%d]: %s\n", ret, sss_strerror(ret));
goto done;
}
for (type = 0; type < DP_TARGET_SENTINEL; type++) {
ret = dp_target_init(be_ctx, provider, modules, targets[type]);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to load target [%s] "
"[%d]: %s.\n", targets[type]->name, ret, sss_strerror(ret));
ret = ERR_INTERNAL;
goto done;
}
}
ret = EOK;
done:
return ret;
}
errno_t dp_init_targets(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
struct data_provider *provider,
struct dp_module **modules)
{
struct dp_target **targets;
enum dp_targets type;
errno_t ret;
/* Even though we know the exact number of targets we will allocate
* them all dynamically so we can have correct talloc hierarchy where
* all private data are attached to the target they belong to. */
targets = talloc_zero_array(mem_ctx, struct dp_target *,
DP_TARGET_SENTINEL + 1);
if (targets == NULL) {
ret = ENOMEM;
goto done;
}
for (type = 0; type != DP_TARGET_SENTINEL; type++) {
targets[type] = talloc_zero(targets, struct dp_target);
if (targets[type] == NULL) {
ret = ENOMEM;
goto done;
}
}
/* We want this to be already available. */
provider->targets = targets;
ret = dp_load_targets(be_ctx, provider, targets, modules);
done:
if (ret != EOK) {
provider->targets = NULL;
talloc_free(targets);
}
return ret;
}