data_provider_be.c revision 9db5a5140356479a58f2e7212fc5c4ad6135bb7f
/*
SSSD
Data Provider Process
Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
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 <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <dlfcn.h>
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#include "popt.h"
#include "sbus/sssd_dbus.h"
#include "providers/dp_backend.h"
#include "providers/fail_over.h"
#include "resolv/async_resolv.h"
#include "monitor/monitor_interfaces.h"
#define MSG_TARGET_NO_CONFIGURED "sssd_be: The requested target is not configured"
#define ACCESS_PERMIT "permit"
#define ACCESS_DENY "deny"
#define NO_PROVIDER "none"
struct sbus_connection *conn);
struct sbus_connection *conn);
struct sbus_method monitor_be_methods[] = {
};
struct sbus_interface monitor_be_interface = {
};
struct sbus_method be_methods[] = {
};
struct sbus_interface be_interface = {
};
};
struct be_async_req {
};
struct tevent_timer *te,
{
struct be_async_req *async_req;
}
{
struct be_async_req *areq;
struct tevent_timer *te;
if (!areq) {
return ENOMEM;
}
/* fire immediately */
return EIO;
}
return EOK;
}
{
/* check if we are past the offline blackout timeout */
/* FIXME: get offline_timeout from configuration */
}
}
{
}
{
void *user_data;
dbus_uint16_t err_maj = 0;
dbus_uint32_t err_min = 0;
static const char *err_msg = "Success";
} else {
online = MOD_ONLINE;
}
if (!dbret) {
return EIO;
}
return EOK;
}
{
switch (dp_err_type) {
case DP_ERR_OK:
break;
case DP_ERR_OFFLINE:
return talloc_asprintf(memctx,
"Provider is Offline (%s)",
break;
case DP_ERR_TIMEOUT:
return talloc_asprintf(memctx,
"Request timed out (%s)",
break;
case DP_ERR_FATAL:
default:
return talloc_asprintf(memctx,
"Internal Error (%s)",
break;
}
return NULL;
}
int dp_err_type,
int errnum,
const char *errstr)
{
dbus_uint16_t err_maj = 0;
dbus_uint32_t err_min = 0;
if (reply) {
/* Return a reply if one was requested
* There may not be one if this request began
* while we were offline
*/
if (errstr) {
} else {
}
if (!err_msg) {
err_msg = "OOM";
}
if (!dbret) {
return;
}
}
/* finally free the request */
}
{
struct be_acct_req *req;
void *user_data;
char *filter;
int filter_type;
char *filter_val;
int ret;
const char *err_msg;
if (!ret) {
return EIO;
}
/* If we are offline and fast reply was requested
* return offline immediately
*/
/* Send back an immediate reply */
err_msg = "Fast reply - offline";
/* This reply will be queued and sent
* when we reenter the mainloop.
*
* Continue processing in case we are
* going back online.
*/
}
if ((attr_type != BE_ATTR_CORE) &&
(attr_type != BE_ATTR_MEM) &&
(attr_type != BE_ATTR_ALL)) {
/* Unrecognized attr type */
err_msg = "Invalid Attrs Parameter";
goto done;
}
if (filter) {
} else {
err_msg = "Invalid Filter";
goto done;
}
} else {
err_msg = "Missing Filter Parameter";
goto done;
}
/* process request */
if (!be_req) {
err_msg = "Out of memory";
goto done;
}
if (!req) {
err_msg = "Out of memory";
goto done;
}
be_req);
err_msg = "Failed to file request";
goto done;
}
return EOK;
done:
if (be_req) {
}
if (reply) {
/* send reply back */
}
return EOK;
}
int dp_err_type,
int errnum,
const char *errstr)
{
if (!dbret) {
return;
}
}
{
void *user_data;
if (!reply) {
return ENOMEM;
}
if (!be_req) {
goto done;
}
if (!pd) {
return ENOMEM;
}
return ENOMEM;
}
if (!ret) {
return EIO;
}
case SSS_PAM_AUTHENTICATE:
break;
case SSS_PAM_ACCT_MGMT:
target = BET_ACCESS;
break;
case SSS_PAM_CHAUTHTOK:
case SSS_PAM_CHAUTHTOK_PRELIM:
target = BET_CHPASS;
break;
case SSS_PAM_SETCRED:
case SSS_PAM_OPEN_SESSION:
case SSS_PAM_CLOSE_SESSION:
goto done;
break;
default:
goto done;
}
/* return an error if corresponding backend target is not configured */
sizeof(MSG_TARGET_NO_CONFIGURED),
(const uint8_t *) MSG_TARGET_NO_CONFIGURED);
}
goto done;
}
be_req);
goto done;
}
return EOK;
done:
if (!ret) {
return EIO;
}
/* send reply back immediately */
return EOK;
}
static int be_client_destructor(void *ctx)
{
} else {
}
}
return 0;
}
struct sbus_connection *conn)
{
char *cli_name;
void *data;
if (!becli) {
DEBUG(0, ("Connection holds no valid init data\n"));
return EINVAL;
}
/* First thing, cancel the timeout */
if (!dbret) {
/* FIXME: should we just talloc_zfree(conn) ? */
return EIO;
}
} else {
}
/* reply that all is ok */
if (!reply) {
DEBUG(0, ("Dbus Out of memory!\n"));
return ENOMEM;
}
if (!dbret) {
DEBUG(0, ("Failed to build dbus reply\n"));
return EIO;
}
/* send reply back */
becli->initialized = true;
return EOK;
}
struct tevent_timer *te,
{
}
{
/* hang off this memory to the connection so that when the connection
* is freed we can potentially call a destructor */
if (!becli) {
DEBUG(0,("Out of memory?!\n"));
return ENOMEM;
}
becli->initialized = false;
/* 5 seconds should be plenty */
DEBUG(0,("Out of memory?!\n"));
return ENOMEM;
}
/* Attach the client context to the connection context, so that it is
* always available when we need to manage the connection. */
return EOK;
}
/* be_srv_init
* set up per-domain sbus channel */
{
char *sbus_address;
int ret;
/* Set up SBUS connection to the monitor */
DEBUG(0, ("Could not get sbus backend address.\n"));
return ret;
}
DEBUG(0, ("Could not set up sbus server.\n"));
return ret;
}
return EOK;
}
/* mon_cli_init
* sbus channel to the monitor daemon */
{
char *sbus_address;
int ret;
/* Set up SBUS connection to the monitor */
DEBUG(0, ("Could not locate monitor address.\n"));
return ret;
}
DEBUG(0, ("Failed to connect to monitor services.\n"));
return ret;
}
/* Identify ourselves to the monitor */
DEBUG(0, ("Failed to identify to the monitor!\n"));
return ret;
}
return EOK;
}
{
}
static struct bet_ops be_target_access_permit_ops = {
.check_online = NULL,
};
{
}
static struct bet_ops be_target_access_deny_ops = {
.check_online = NULL,
};
const char *default_mod_name)
{
bool already_loaded = false;
int lb=0;
void *handle;
char *mod_init_fn_name = NULL;
return EINVAL;
}
if (!tmp_ctx) {
return ENOMEM;
}
&mod_name);
goto done;
}
if (!mod_name) {
if (default_mod_name != NULL) {
} else {
goto done;
}
}
goto done;
}
if (bet_type == BET_ACCESS) {
goto done;
}
goto done;
}
}
mod_name);
if (mod_init_fn_name == NULL) {
goto done;
}
lb = 0;
already_loaded = true;
break;
}
++lb;
goto done;
}
}
if (!already_loaded) {
if (!path) {
goto done;
}
if (!handle) {
DEBUG(0, ("Unable to load %s module with path (%s), error: %s\n",
goto done;
}
}
if (mod_init_fn == NULL) {
if (default_mod_name != NULL &&
/* If the default is used and fails we indicate this to the caller
* by returning ENOENT. Ths way the caller can decide how to
* handle the different types of error conditions. */
} else {
DEBUG(0, ("Unable to load init fn %s from module %s, error: %s\n",
}
goto done;
}
DEBUG(0, ("Error (%d) in module (%s) initialization (%s)!\n",
goto done;
}
done:
return ret;
}
struct tevent_signal *se,
int signum,
int count,
void *siginfo,
void *private_data)
{
}
const char *be_domain,
struct tevent_context *ev,
struct confdb_ctx *cdb)
{
struct tevent_signal *tes;
int ret;
if (!ctx) {
DEBUG(0, ("fatal error initializing be_ctx\n"));
return ENOMEM;
}
DEBUG(0, ("Out of memory!?\n"));
return ENOMEM;
}
DEBUG(0, ("fatal error initializing failover context\n"));
return ret;
}
DEBUG(0, ("fatal error retrieving domain configuration\n"));
return ret;
}
DEBUG(0, ("fatal error opening cache database\n"));
return ret;
}
DEBUG(0, ("fatal error setting up monitor bus\n"));
return ret;
}
DEBUG(0, ("fatal error setting up server bus\n"));
return ret;
}
DEBUG(0, ("fatal error initializing data providers\n"));
return ret;
}
DEBUG(0, ("fatal error initializing data providers\n"));
return ret;
}
be_domain));
} else {
}
DEBUG(0, ("Failed to setup ACCESS backend.\n"));
return ret;
}
DEBUG(0, ("fatal error initializing data providers\n"));
return ret;
}
be_domain));
} else {
}
/* Handle SIGUSR1 to force offline behavior */
BlockSignals(false, SIGUSR1);
return EIO;
}
return EOK;
}
{
int opt;
char *conf_entry = NULL;
struct main_context *main_ctx;
int ret;
struct poptOption long_options[] = {
_("Domain of the information provider (mandatory)"), NULL },
};
switch(opt) {
default:
return 1;
}
}
return 1;
}
/* set up things like debug , signals, daemonization, etc... */
if (!debug_log_file) return 2;
if (!srv_name) return 2;
if (!conf_entry) return 2;
return 2;
}
ret = die_if_parent_died();
/* This is not fatal, don't return */
}
return 3;
}
/* loop on main */
return 0;
}
struct sbus_connection *conn)
{
}
struct sbus_connection *conn)
{
}