summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/Makefile.am8
-rw-r--r--server/monitor/monitor.c55
-rw-r--r--server/providers/data_provider.c1016
-rw-r--r--server/providers/data_provider.h32
-rw-r--r--server/providers/data_provider_be.c384
-rw-r--r--server/providers/dp_auth_util.c14
-rw-r--r--server/providers/dp_backend.h13
-rw-r--r--server/providers/dp_interfaces.h32
-rw-r--r--server/providers/dp_sbus.c9
-rw-r--r--server/responder/common/responder.h20
-rw-r--r--server/responder/common/responder_common.c73
-rw-r--r--server/responder/common/responder_dp.c19
-rw-r--r--server/responder/nss/nsssrv.c32
-rw-r--r--server/responder/pam/pamsrv.c31
-rw-r--r--server/responder/pam/pamsrv_dp.c18
15 files changed, 379 insertions, 1377 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index 4eb2c4bc..a65c9fa7 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -51,7 +51,6 @@ sbin_PROGRAMS = \
sssdlibexec_PROGRAMS = \
sssd_nss \
sssd_pam \
- sssd_dp \
sssd_be \
krb5_child \
$(sssd_pk) \
@@ -250,7 +249,6 @@ dist_noinst_HEADERS = \
confdb/confdb_private.h \
confdb/confdb_setup.h \
providers/data_provider.h \
- providers/dp_interfaces.h \
providers/dp_backend.h \
providers/providers.h \
providers/krb5/krb5_auth.h \
@@ -294,12 +292,6 @@ sssd_pam_SOURCES = \
sssd_pam_LDADD = \
$(SSSD_LIBS)
-sssd_dp_SOURCES = \
- providers/data_provider.c\
- $(SSSD_UTIL_OBJ)
-
-sssd_dp_LDADD = $(SSSD_LIBS)
-
sssd_be_SOURCES = \
providers/data_provider_be.c \
$(SSSD_UTIL_OBJ)
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index ef91b6b6..abd881e0 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -117,6 +117,7 @@ struct mt_ctx {
struct config_file_ctx *file_ctx;
int inotify_fd;
int service_id_timeout;
+ bool check_children;
};
static int start_service(struct mt_svc *mt_svc, bool startup);
@@ -487,6 +488,10 @@ static void global_checks_handler(struct tevent_context *ev,
int status;
pid_t pid;
+ if (!ctx->check_children) {
+ goto done;
+ }
+
errno = 0;
pid = waitpid(0, &status, WNOHANG);
if (pid == 0) {
@@ -785,33 +790,6 @@ static int check_domain_ranges(struct sss_domain_info *domains)
return EOK;
}
-static int append_data_provider(struct mt_ctx *ctx)
-{
- int i;
- char **new_services;
-
- for (i = 0; ctx->services[i]; i++) {
- if (strcasecmp(ctx->services[i], "dp") == 0) {
- return EOK;
- }
- }
-
- new_services = talloc_realloc(ctx, ctx->services, char *, i+2);
- if (new_services == NULL) {
- return ENOMEM;
- }
- ctx->services = new_services;
-
- ctx->services[i] = talloc_asprintf(ctx, "dp");
- if (ctx->services[i] == NULL) {
- return ENOMEM;
- }
- ctx->services[i+1] = NULL;
- DEBUG(4, ("Added mandatory service Data Provider\n"));
-
- return EOK;
-}
-
static int check_local_domain_unique(struct sss_domain_info *domains)
{
uint8_t count = 0;
@@ -864,11 +842,6 @@ int get_monitor_config(struct mt_ctx *ctx)
DEBUG(0, ("No services configured!\n"));
return EINVAL;
}
- ret = append_data_provider(ctx);
- if (ret != EOK) {
- DEBUG(0, ("Could not add Data Provider to the list of services!\n"));
- return ret;
- }
ctx->domain_ctx = talloc_new(ctx);
if(!ctx->domain_ctx) {
@@ -2273,13 +2246,18 @@ static int start_service(struct mt_svc *svc, bool startup)
DEBUG(4,("Queueing service %s for startup\n", svc->name));
- /* at startup we need to start the data provider service before all others
- * to avoid races where a service that need dp starts before it is ready
- * to accept connections on its dbus. So if startup is true delay by 1
- * second any process that is not the data provider */
+ /* at startup we need to start the data providers before the responders
+ * to avoid races where a service starts before sbus pipes are ready
+ * to accept connections. So if startup is true delay by 2 seconds any
+ * process that is not a data provider */
+
+ /* FIXME: use stat to check the pipes are available instead and rescheduleif
+ * not */
- if (startup && strcasecmp(svc->name, "dp")) {
- tv = tevent_timeval_current_ofs(1, 0);
+ if (startup &&
+ ((strcasecmp(svc->name, "nss") == 0) ||
+ (strcasecmp(svc->name, "pam") == 0))) {
+ tv = tevent_timeval_current_ofs(2, 0);
} else {
tv = tevent_timeval_current();
}
@@ -2336,6 +2314,7 @@ static void service_startup_handler(struct tevent_context *ev,
}
/* Parent */
+ mt_svc->mt_ctx->check_children = true;
mt_svc->failed_pongs = 0;
DLIST_ADD(mt_svc->mt_ctx->svc_list, mt_svc);
talloc_set_destructor((TALLOC_CTX *)mt_svc, delist_service);
diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
deleted file mode 100644
index 70b7cd3f..00000000
--- a/server/providers/data_provider.c
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- SSSD
-
- Data Provider
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <string.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <security/pam_modules.h>
-
-#include "popt.h"
-#include "util/util.h"
-#include "confdb/confdb.h"
-#include "dbus/dbus.h"
-#include "sbus/sssd_dbus.h"
-#include "data_provider.h"
-#include "dp_interfaces.h"
-#include "monitor/monitor_interfaces.h"
-
-struct dp_backend;
-struct dp_frontend;
-
-struct dp_ctx {
- struct tevent_context *ev;
- struct confdb_ctx *cdb;
- struct sbus_connection *sbus_srv;
- struct dp_backend *be_list;
- struct dp_frontend *fe_list;
-};
-
-struct dp_client {
- struct dp_ctx *dpctx;
- struct sbus_connection *conn;
- struct tevent_timer *timeout;
- bool initialized;
-};
-
-struct dp_backend {
- struct dp_backend *prev;
- struct dp_backend *next;
- char *domain;
- struct dp_client *dpcli;
-};
-
-struct dp_frontend {
- struct dp_frontend *prev;
- struct dp_frontend *next;
- char *name;
- uint16_t flags;
- struct dp_client *dpcli;
-};
-
-static int dp_backend_destructor(void *ctx);
-static int dp_frontend_destructor(void *ctx);
-
-static int service_reload(DBusMessage *message, struct sbus_connection *conn);
-
-struct sbus_method monitor_dp_methods[] = {
- { MON_CLI_METHOD_PING, monitor_common_pong },
- { MON_CLI_METHOD_RELOAD, service_reload },
- { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
- { NULL, NULL }
-};
-
-struct sbus_interface monitor_dp_interface = {
- MONITOR_INTERFACE,
- MONITOR_PATH,
- SBUS_DEFAULT_VTABLE,
- monitor_dp_methods,
- NULL
-};
-
-static int client_registration(DBusMessage *message,
- struct sbus_connection *conn);
-static int dp_get_account_info(DBusMessage *message,
- struct sbus_connection *conn);
-static int dp_pamhandler(DBusMessage *message, struct sbus_connection *conn);
-
-struct sbus_method dp_methods[] = {
- { DP_SRV_METHOD_REGISTER, client_registration },
- { DP_SRV_METHOD_GETACCTINFO, dp_get_account_info },
- { DP_SRV_METHOD_PAMHANDLER, dp_pamhandler },
- { NULL, NULL }
-};
-
-struct sbus_interface dp_interface = {
- DP_SRV_INTERFACE,
- DP_SRV_PATH,
- SBUS_DEFAULT_VTABLE,
- dp_methods,
- NULL
-};
-
-struct dp_request {
- /* reply message to send when request is done */
- DBusMessage *reply;
- /* frontend client that made the request */
- struct dp_client *src_cli;
-
- int pending_replies;
-};
-
-struct dp_be_request {
- struct dp_request *req;
- struct dp_backend *be;
-};
-
-static int service_reload(DBusMessage *message, struct sbus_connection *conn)
-{
- /* Monitor calls this function when we need to reload
- * our configuration information. Perform whatever steps
- * are needed to update the configuration objects.
- */
-
- /* Send an empty reply to acknowledge receipt */
- return monitor_common_pong(message, conn);
-}
-
-static int dp_monitor_init(struct dp_ctx *dpctx)
-{
- struct sbus_connection *conn;
- char *sbus_address;
- int ret;
-
- /* Set up SBUS connection to the monitor */
- ret = monitor_get_sbus_address(dpctx, &sbus_address);
- if (ret != EOK) {
- DEBUG(0, ("Could not locate monitor address.\n"));
- return ret;
- }
-
- ret = sbus_client_init(dpctx, dpctx->ev, sbus_address,
- &monitor_dp_interface, &conn,
- NULL, NULL);
- if (ret != EOK) {
- DEBUG(0, ("Failed to connect to monitor services.\n"));
- return ret;
- }
-
- /* Identify ourselves to the monitor */
- ret = monitor_common_send_id(conn,
- DATA_PROVIDER_SERVICE_NAME,
- DATA_PROVIDER_VERSION);
- if (ret != EOK) {
- DEBUG(0, ("Failed to identify to the monitor!\n"));
- return ret;
- }
-
- return EOK;
-}
-
-static void init_timeout(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval t, void *ptr)
-{
- struct dp_client *dpcli;
-
- DEBUG(2, ("Client timed out before Identification [%p]!\n", te));
-
- dpcli = talloc_get_type(ptr, struct dp_client);
-
- sbus_disconnect(dpcli->conn);
- talloc_zfree(dpcli);
-}
-
-static int dp_client_init(struct sbus_connection *conn, void *data)
-{
- struct dp_ctx *dpctx;
- struct dp_client *dpcli;
- struct timeval tv;
-
- dpctx = talloc_get_type(data, struct dp_ctx);
-
- /* hang off this memory to the connection so that when the connection
- * is freed we can potentially call a destructor */
-
- dpcli = talloc(conn, struct dp_client);
- if (!dpcli) {
- DEBUG(0,("Out of memory?!\n"));
- talloc_zfree(conn);
- return ENOMEM;
- }
- dpcli->dpctx = dpctx;
- dpcli->conn = conn;
- dpcli->initialized = false;
-
- /* 5 seconds should be plenty */
- tv = tevent_timeval_current_ofs(5, 0);
-
- dpcli->timeout = tevent_add_timer(dpctx->ev, dpcli,
- tv, init_timeout, dpcli);
- if (!dpcli->timeout) {
- DEBUG(0,("Out of memory?!\n"));
- talloc_zfree(conn);
- return ENOMEM;
- }
- DEBUG(4, ("Set-up DP ID timeout [%p]\n", dpcli->timeout));
-
- /* Attach the client context to the connection context, so that it is
- * always available when we need to manage the connection. */
- sbus_conn_set_private_data(conn, dpcli);
-
- return EOK;
-}
-
-static int client_registration(DBusMessage *message,
- struct sbus_connection *conn)
-{
- dbus_uint16_t version = DATA_PROVIDER_VERSION;
- struct dp_backend *dpbe;
- struct dp_frontend *dpfe;
- struct dp_client *dpcli;
- DBusMessage *reply;
- DBusError dbus_error;
- dbus_uint16_t cli_ver;
- dbus_uint16_t cli_type;
- char *cli_name;
- char *cli_domain;
- dbus_bool_t dbret;
- void *data;
-
- data = sbus_conn_get_private_data(conn);
- dpcli = talloc_get_type(data, struct dp_client);
- if (!dpcli) {
- DEBUG(0, ("Connection holds no valid init data\n"));
- return EINVAL;
- }
-
- /* First thing, cancel the timeout */
- DEBUG(4, ("Cancel DP ID timeout [%p]\n", dpcli->timeout));
- talloc_zfree(dpcli->timeout);
-
- dbus_error_init(&dbus_error);
-
- dbret = dbus_message_get_args(message, &dbus_error,
- DBUS_TYPE_UINT16, &cli_type,
- DBUS_TYPE_UINT16, &cli_ver,
- DBUS_TYPE_STRING, &cli_name,
- DBUS_TYPE_STRING, &cli_domain,
- DBUS_TYPE_INVALID);
- if (!dbret) {
- DEBUG(1, ("Failed to parse message, killing connection\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- sbus_disconnect(conn);
- /* FIXME: should we just talloc_zfree(conn) ? */
- return EIO;
- }
-
- switch (cli_type & DP_CLI_TYPE_MASK) {
- case DP_CLI_BACKEND:
- dpbe = talloc_zero(dpcli->dpctx, struct dp_backend);
- if (!dpbe) {
- DEBUG(0, ("Out of memory!\n"));
- sbus_disconnect(conn);
- return ENOMEM;
- }
-
- dpbe->domain = talloc_strdup(dpbe, cli_domain);
- if (!dpbe->domain) {
- DEBUG(0, ("Out of memory!\n"));
- sbus_disconnect(conn);
- return ENOMEM;
- }
-
- dpbe->dpcli = dpcli;
-
- DLIST_ADD(dpcli->dpctx->be_list, dpbe);
-
- DEBUG(4, ("Added Backend client for domain [%s]\n", dpbe->domain));
-
- talloc_set_destructor((TALLOC_CTX *)dpbe, dp_backend_destructor);
- break;
-
- case DP_CLI_FRONTEND:
- dpfe = talloc_zero(dpcli->dpctx, struct dp_frontend);
- if (!dpfe) {
- DEBUG(0, ("Out of memory!\n"));
- sbus_disconnect(conn);
- return ENOMEM;
- }
-
- dpfe->name = talloc_strdup(dpfe, cli_name);
- if (!dpfe->name) {
- DEBUG(0, ("Out of memory!\n"));
- sbus_disconnect(conn);
- return ENOMEM;
- }
-
- dpfe->dpcli = dpcli;
-
- DLIST_ADD(dpcli->dpctx->fe_list, dpfe);
-
- DEBUG(4, ("Added Frontend client [%s]\n", dpfe->name));
-
- talloc_set_destructor((TALLOC_CTX *)dpfe, dp_frontend_destructor);
- break;
-
- default:
- DEBUG(1, ("Unknown client type, killing connection\n"));
- sbus_disconnect(conn);
- return EIO;
- }
-
- /* reply that all is ok */
- reply = dbus_message_new_method_return(message);
- if (!reply) {
- DEBUG(0, ("Dbus Out of memory!\n"));
- return ENOMEM;
- }
-
- dbret = dbus_message_append_args(reply,
- DBUS_TYPE_UINT16, &version,
- DBUS_TYPE_INVALID);
- if (!dbret) {
- DEBUG(0, ("Failed to build dbus reply\n"));
- dbus_message_unref(reply);
- sbus_disconnect(conn);
- return EIO;
- }
-
- /* send reply back */
- sbus_conn_send_reply(conn, reply);
- dbus_message_unref(reply);
-
- dpcli->initialized = true;
- return EOK;
-}
-
-static void be_got_account_info(DBusPendingCall *pending, void *data)
-{
- struct dp_be_request *bereq;
- DBusMessage *reply;
- DBusConnection *dbus_conn;
- DBusError dbus_error;
- dbus_uint16_t err_maj = 0;
- dbus_uint32_t err_min = 0;
- const char *err_msg;
- dbus_bool_t ret;
- int type;
-
- bereq = talloc_get_type(data, struct dp_be_request);
- dbus_error_init(&dbus_error);
-
- reply = dbus_pending_call_steal_reply(pending);
- if (!reply) {
- /* reply should never be null. This function shouldn't be called
- * until reply is valid or timeout has occurred. If reply is NULL
- * here, something is seriously wrong and we should bail out.
- */
- DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n"));
-
- /* Destroy this connection */
- sbus_disconnect(bereq->be->dpcli->conn);
- goto done;
- }
-
- type = dbus_message_get_type(reply);
- switch (type) {
- case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- ret = dbus_message_get_args(reply, &dbus_error,
- DBUS_TYPE_UINT16, &err_maj,
- DBUS_TYPE_UINT32, &err_min,
- DBUS_TYPE_STRING, &err_msg,
- DBUS_TYPE_INVALID);
- if (!ret) {
- DEBUG(1,("Failed to parse message, killing connection\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- sbus_disconnect(bereq->be->dpcli->conn);
- goto done;
- }
-
- DEBUG(4, ("Got reply (%u, %u, %s) from (%s)\n",
- (unsigned int)err_maj, (unsigned int)err_min, err_msg,
- bereq->be->domain));
-
- break;
-
- case DBUS_MESSAGE_TYPE_ERROR:
- DEBUG(0,("The Data Provider returned an error [%s], closing connection.\n",
- dbus_message_get_error_name(reply)));
- /* Falling through to default intentionally*/
- default:
- /*
- * Timeout or other error occurred or something
- * unexpected happened.
- * It doesn't matter which, because either way we
- * know that this connection isn't trustworthy.
- * We'll destroy it now.
- */
- sbus_disconnect(bereq->be->dpcli->conn);
- }
-
- if (err_maj) {
- DEBUG(1, ("Backend returned an error: %d,%d(%s),%s\n",
- err_maj, err_min, strerror(err_min), err_msg));
- /* TODO: handle errors !! */
- }
-
- if (bereq->req->pending_replies > 1) {
- bereq->req->pending_replies--;
- talloc_free(bereq);
- } else {
- dbus_conn = sbus_get_connection(bereq->req->src_cli->conn);
- err_maj = 0;
- err_min = 0;
- err_msg = "Success";
- ret = dbus_message_append_args(bereq->req->reply,
- DBUS_TYPE_UINT16, &err_maj,
- DBUS_TYPE_UINT32, &err_min,
- DBUS_TYPE_STRING, &err_msg,
- DBUS_TYPE_INVALID);
- if (!ret) {
- DEBUG(1, ("Failed to build reply ... frontend will wait for timeout ...\n"));
- talloc_free(bereq->req);
- goto done;
- }
-
- /* finally send it */
- dbus_connection_send(dbus_conn, bereq->req->reply, NULL);
- dbus_message_unref(bereq->req->reply);
- talloc_free(bereq->req);
- }
-
-done:
- dbus_pending_call_unref(pending);
- dbus_message_unref(reply);
-}
-
-static int dp_send_acct_req(struct dp_be_request *bereq,
- uint32_t type, char *attrs, char *filter)
-{
- DBusMessage *msg;
- DBusPendingCall *pending_reply;
- DBusConnection *dbus_conn;
- dbus_bool_t ret;
-
- dbus_conn = sbus_get_connection(bereq->be->dpcli->conn);
-
- /* create the message */
- msg = dbus_message_new_method_call(NULL,
- DP_CLI_PATH,
- DP_CLI_INTERFACE,
- DP_CLI_METHOD_GETACCTINFO);
- if (msg == NULL) {
- DEBUG(0,("Out of memory?!\n"));
- return ENOMEM;
- }
-
- DEBUG(4, ("Sending request for [%u][%s][%s]\n", type, attrs, filter));
-
- ret = dbus_message_append_args(msg,
- DBUS_TYPE_UINT32, &type,
- DBUS_TYPE_STRING, &attrs,
- DBUS_TYPE_STRING, &filter,
- DBUS_TYPE_INVALID);
- if (!ret) {
- DEBUG(1,("Failed to build message\n"));
- return EIO;
- }
-
- ret = dbus_connection_send_with_reply(dbus_conn, msg, &pending_reply,
- 600000 /* TODO: set timeout */);
- if (!ret || pending_reply == NULL) {
- /*
- * Critical Failure
- * We can't communicate on this connection
- * We'll drop it using the default destructor.
- */
- DEBUG(0, ("D-BUS send failed.\n"));
- dbus_message_unref(msg);
- return EIO;
- }
-
- /* Set up the reply handler */
- dbus_pending_call_set_notify(pending_reply, be_got_account_info,
- bereq, NULL);
- dbus_message_unref(msg);
-
- return EOK;
-}
-
-static int dp_get_account_info(DBusMessage *message, struct sbus_connection *conn)
-{
- struct dp_client *dpcli;
- struct dp_be_request *bereq;
- struct dp_request *dpreq = NULL;
- struct dp_backend *dpbe;
- DBusMessage *reply;
- DBusError dbus_error;
- dbus_bool_t dbret;
- void *user_data;
- uint32_t type;
- char *domain, *attrs, *filter;
- const char *errmsg = NULL;
- int dpret = 0, ret = 0;
-
- user_data = sbus_conn_get_private_data(conn);
- if (!user_data) return EINVAL;
- dpcli = talloc_get_type(user_data, struct dp_client);
- if (!dpcli) return EINVAL;
-
- dbus_error_init(&dbus_error);
-
- ret = dbus_message_get_args(message, &dbus_error,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_UINT32, &type,
- DBUS_TYPE_STRING, &attrs,
- DBUS_TYPE_STRING, &filter,
- DBUS_TYPE_INVALID);
- if (!ret) {
- DEBUG(1,("Failed, to parse message!\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- return EIO;
- }
-
- DEBUG(4, ("Got request for [%s][%u][%s][%s]\n",
- domain, type, attrs, filter));
-
- reply = dbus_message_new_method_return(message);
- if (!reply) return ENOMEM;
-
- /* search for domain */
- if (!domain) {
- dpret = DP_ERR_FATAL;
- errmsg = "Invalid Domain";
- ret = EINVAL;
- goto respond;
- }
-
- /* all domains, fire off a request for each backend */
- if (strcmp(domain, "*") == 0) {
- dpreq = talloc(dpcli->dpctx, struct dp_request);
- if (!dpreq) {
- dpret = DP_ERR_FATAL;
- errmsg = "Out of memory";
- ret = ENOMEM;
- goto respond;
- }
-
- dpreq->reply = reply;
- dpreq->src_cli = dpcli;
- dpreq->pending_replies = 0;
-
- /* now fire off requests */
- dpbe = dpcli->dpctx->be_list;
- while (dpbe) {
- bereq = talloc(dpreq, struct dp_be_request);
- if (!bereq) {
- DEBUG(1, ("Out of memory while sending requests\n"));
- dpbe = dpbe->next;
- continue;
- }
- bereq->req = dpreq;
- bereq->be = dpbe;
- DEBUG(4, ("Sending wildcard request to [%s]\n", dpbe->domain));
- ret = dp_send_acct_req(bereq, type, attrs, filter);
- if (ret != EOK) {
- DEBUG(2,("Failed to dispatch request to %s\n", dpbe->domain));
- dpbe = dpbe->next;
- continue;
- }
- dpreq->pending_replies++;
- dpbe = dpbe->next;
- }
-
- if (dpreq->pending_replies == 0) {
- dpret = DP_ERR_FATAL;
- errmsg = "Unable to contact backends";
- ret = EIO;
- talloc_free(dpreq);
- goto respond;
- }
-
- return EOK;
- }
-
- dpbe = dpcli->dpctx->be_list;
- while (dpbe) {
- if (strcasecmp(dpbe->domain, domain) == 0) {
- break;
- }
-
- dpbe = dpbe->next;
- }
-
- if (dpbe) {
- dpreq = talloc(dpcli->dpctx, struct dp_request);
- if (!dpreq) {
- DEBUG(1, ("Out of memory while sending request\n"));
- dpret = DP_ERR_FATAL;
- errmsg = "Out of memory";
- ret = ENOMEM;
- goto respond;
- }
-
- dpreq->reply = reply;
- dpreq->src_cli = dpcli;
- dpreq->pending_replies = 1;
-
- bereq = talloc(dpreq, struct dp_be_request);
- if (!bereq) {
- DEBUG(1, ("Out of memory while sending request\n"));
- dpret = DP_ERR_FATAL;
- errmsg = "Out of memory";
- ret = ENOMEM;
- talloc_free(dpreq);
- goto respond;
- }
- bereq->req = dpreq;
- bereq->be = dpbe;
-
- ret = dp_send_acct_req(bereq, type, attrs, filter);
- if (ret != EOK) {
- DEBUG(2,("Failed to dispatch request to %s\n", dpbe->domain));
- dpret = DP_ERR_FATAL;
- errmsg = "Dispatch Failed";
- talloc_free(dpreq);
- goto respond;
- }
-
- } else {
-
- dpret = DP_ERR_FATAL;
- errmsg = "Invalid Domain";
- ret = EINVAL;
- goto respond;
- }
-
- return EOK;
-
-respond:
- dbret = dbus_message_append_args(reply,
- DBUS_TYPE_UINT16, &dpret,
- DBUS_TYPE_UINT32, &ret,
- DBUS_TYPE_STRING, &errmsg,
- DBUS_TYPE_INVALID);
- if (!dbret) return EIO;
-
- /* send reply back immediately */
- sbus_conn_send_reply(conn, reply);
- dbus_message_unref(reply);
-
- return EOK;
-}
-
-static void be_got_pam_reply(DBusPendingCall *pending, void *data)
-{
- struct dp_be_request *bereq;
- DBusMessage *reply;
- DBusConnection *dbus_conn;
- DBusError dbus_error;
- dbus_bool_t ret;
- struct pam_data *pd = NULL;
- int type;
-
- bereq = talloc_get_type(data, struct dp_be_request);
- dbus_error_init(&dbus_error);
-
- reply = dbus_pending_call_steal_reply(pending);
- if (!reply) {
- /* reply should never be null. This function shouldn't be called
- * until reply is valid or timeout has occurred. If reply is NULL
- * here, something is seriously wrong and we should bail out.
- */
- DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n"));
-
- /* Destroy this connection */
- sbus_disconnect(bereq->be->dpcli->conn);
- goto done;
- }
-
- pd = talloc_zero(bereq, struct pam_data);
- type = dbus_message_get_type(reply);
- switch (type) {
- case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- ret = dp_unpack_pam_response(reply, pd, &dbus_error);
- if (!ret) {
- DEBUG(1,("Failed to parse message, killing connection\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- sbus_disconnect(bereq->be->dpcli->conn);
- pd->pam_status = PAM_SYSTEM_ERR;
- pd->domain = talloc_strdup(pd, "");
- goto done;
- }
-
- DEBUG(4, ("Got reply (%d, %s) from (%s)\n", pd->pam_status, pd->domain,
- bereq->be->domain));
-
- break;
-
- case DBUS_MESSAGE_TYPE_ERROR:
- DEBUG(0,("The Data Provider returned an error [%s], closing connection.\n",
- dbus_message_get_error_name(reply)));
- /* Falling through to default intentionally*/
- default:
- /*
- * Timeout or other error occurred or something
- * unexpected happened.
- * It doesn't matter which, because either way we
- * know that this connection isn't trustworthy.
- * We'll destroy it now.
- */
- DEBUG(1,("Maybe timeout?\n"));
- sbus_disconnect(bereq->be->dpcli->conn);
- goto done;
- }
-
- dbus_conn = sbus_get_connection(bereq->req->src_cli->conn);
-
- ret = dp_pack_pam_response(bereq->req->reply, pd);
- if (!ret) {
- DEBUG(1, ("Failed to build reply ... frontend will wait for timeout ...\n"));
- talloc_free(bereq->req);
- goto done;
- }
-
- /* finally send it */
- dbus_connection_send(dbus_conn, bereq->req->reply, NULL);
- dbus_message_unref(bereq->req->reply);
- talloc_free(bereq->req);
-
-done:
- dbus_pending_call_unref(pending);
- dbus_message_unref(reply);
-}
-
-static int dp_call_pamhandler(struct dp_be_request *bereq, struct pam_data *pd)
-{
- DBusMessage *msg;
- DBusPendingCall *pending_reply;
- DBusConnection *dbus_conn;
- dbus_bool_t ret;
-
- dbus_conn = sbus_get_connection(bereq->be->dpcli->conn);
-
- /* create the message */
- msg = dbus_message_new_method_call(NULL,
- DP_CLI_PATH,
- DP_CLI_INTERFACE,
- DP_CLI_METHOD_PAMHANDLER);
- if (msg == NULL) {
- DEBUG(0,("Out of memory?!\n"));
- return ENOMEM;
- }
-
- DEBUG(4, ("Sending request with to following data\n"));
- DEBUG_PAM_DATA(4, pd);
-
- ret = dp_pack_pam_request(msg, pd);
- if (!ret) {
- DEBUG(1,("Failed to build message\n"));
- return EIO;
- }
-
- ret = dbus_connection_send_with_reply(dbus_conn, msg, &pending_reply,
- 600000 /* TODO: set timeout */);
- if (!ret || pending_reply == NULL) {
- /*
- * Critical Failure
- * We can't communicate on this connection
- * We'll drop it using the default destructor.
- */
- DEBUG(0, ("D-BUS send failed.\n"));
- dbus_message_unref(msg);
- return EIO;
- }
-
- /* Set up the reply handler */
- dbus_pending_call_set_notify(pending_reply, be_got_pam_reply,
- bereq, NULL);
- dbus_message_unref(msg);
-
- return EOK;
-}
-
-static int dp_pamhandler(DBusMessage *message, struct sbus_connection *conn)
-{
- DBusMessage *reply;
- DBusError dbus_error;
- struct dp_client *dpcli;
- struct dp_backend *dpbe;
- struct dp_be_request *bereq;
- struct dp_request *dpreq = NULL;
- dbus_bool_t dbret;
- void *user_data;
- int ret;
- struct pam_data *pd;
- int pam_status=PAM_SUCCESS;
- int domain_found=0;
-
- user_data = sbus_conn_get_private_data(conn);
- if (!user_data) return EINVAL;
- dpcli = talloc_get_type(user_data, struct dp_client);
- if (!dpcli) return EINVAL;
-
-/* FIXME: free arrays returned by dbus_message_get_args() */
- pd = talloc(NULL, struct pam_data);
- if (!pd) return ENOMEM;
-
- dbus_error_init(&dbus_error);
-
- ret = dp_unpack_pam_request(message, pd, &dbus_error);
- if (!ret) {
- DEBUG(0,("Failed, to parse message!\n"));
- if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
- talloc_free(pd);
- return EIO;
- }
-
- DEBUG(4, ("Got the following data:\n"));
- DEBUG_PAM_DATA(4, pd);
-
- reply = dbus_message_new_method_return(message);
- if (!reply) {
- DEBUG(0,("Out of memory?!\n"));
- talloc_free(pd);
- return ENOMEM;
- }
-
- dpreq = talloc(dpcli->dpctx, struct dp_request);
- if (!dpreq) {
- ret = ENOMEM;
- pam_status = PAM_ABORT;
- goto respond;
- }
-
- dpreq->reply = reply;
- dpreq->src_cli = dpcli;
- dpreq->pending_replies = 0;
- /* FIXME: add handling of default domain */
- dpbe = dpcli->dpctx->be_list;
- while (dpbe) {
- DEBUG(4, ("Checking [%s][%s]\n", pd->domain, dpbe->domain));
- if (strcasecmp(dpbe->domain, pd->domain) == 0 ) {
- domain_found=1;
- bereq = talloc(dpreq, struct dp_be_request);
- if (!bereq) {
- DEBUG(1, ("Out of memory while sending requests\n"));
- dpbe = dpbe->next;
- continue;
- }
- bereq->req = dpreq;
- bereq->be = dpbe;
- DEBUG(4, ("Sending wildcard request to [%s]\n", dpbe->domain));
- ret = dp_call_pamhandler(bereq, pd);
- if (ret != EOK) {
- DEBUG(2,("Failed to dispatch request to %s\n", dpbe->domain));
- dpbe = dpbe->next;
- continue;
- }
- dpreq->pending_replies++;
- }
- dpbe = dpbe->next;
- }
-
- if (domain_found) {
- talloc_free(pd);
- return EOK;
- }
-
- pam_status = PAM_MODULE_UNKNOWN;
-
-respond:
- dbret = dbus_message_append_args(reply,
- DBUS_TYPE_UINT32, &pam_status,
- DBUS_TYPE_STRING, &(pd->domain),
- DBUS_TYPE_INVALID);
- if (!dbret) return EIO;
-
- /* send reply back immediately */
- sbus_conn_send_reply(conn, reply);
- dbus_message_unref(reply);
-
- talloc_free(pd);
- return EOK;
-}
-
-static int dp_backend_destructor(void *ctx)
-{
- struct dp_backend *dpbe = talloc_get_type(ctx, struct dp_backend);
- if (dpbe->dpcli && dpbe->dpcli->dpctx && dpbe->dpcli->dpctx->be_list) {
- DLIST_REMOVE(dpbe->dpcli->dpctx->be_list, dpbe);
- DEBUG(4, ("Removed Backend client for domain [%s]\n",
- dpbe->domain));
- }
- return 0;
-}
-
-static int dp_frontend_destructor(void *ctx)
-{
- struct dp_frontend *dpfe = talloc_get_type(ctx, struct dp_frontend);
- if (dpfe->dpcli && dpfe->dpcli->dpctx && dpfe->dpcli->dpctx->fe_list) {
- DLIST_REMOVE(dpfe->dpcli->dpctx->fe_list, dpfe);
- DEBUG(4, ("Removed Frontend client [%s]\n", dpfe->name));
- }
- return 0;
-}
-
-/* monitor_dbus_init
- * Set up the monitor service as a D-BUS Server */
-static int dp_srv_init(struct dp_ctx *dpctx)
-{
- char *dpbus_address;
- int ret;
-
- DEBUG(3, ("Initializing Data Provider D-BUS Server\n"));
- ret = dp_get_sbus_address(dpctx, &dpbus_address);
-
- ret = sbus_new_server(dpctx, dpctx->ev, dpbus_address,
- &dp_interface, &dpctx->sbus_srv,
- dp_client_init, dpctx);
- return ret;
-}
-
-static int dp_process_init(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct confdb_ctx *cdb)
-{
- struct dp_ctx *dpctx;
- int ret;
-
- dpctx = talloc_zero(mem_ctx, struct dp_ctx);
- if (!dpctx) {
- DEBUG(0, ("fatal error initializing dp_ctx\n"));
- return ENOMEM;
- }
- dpctx->ev = ev;
- dpctx->cdb = cdb;
-
- ret = dp_monitor_init(dpctx);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up monitor bus\n"));
- return ret;
- }
-
- ret = dp_srv_init(dpctx);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up server bus\n"));
- return ret;
- }
-
- return EOK;
-}
-
-int main(int argc, const char *argv[])
-{
- int opt;
- poptContext pc;
- struct main_context *main_ctx;
- int ret;
-
- struct poptOption long_options[] = {
- POPT_AUTOHELP
- SSSD_MAIN_OPTS
- { NULL }
- };
-
- pc = poptGetContext(argv[0], argc, argv, long_options, 0);
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch(opt) {
- default:
- fprintf(stderr, "\nInvalid option %s: %s\n\n",
- poptBadOption(pc, 0), poptStrerror(opt));
- poptPrintUsage(pc, stderr, 0);
- return 1;
- }
- }
-
- poptFreeContext(pc);
-
- /* set up things like debug, signals, daemonization, etc... */
- debug_log_file = "sssd_dp";
-
- ret = server_setup("sssd[dp]", 0, CONFDB_DP_CONF_ENTRY, &main_ctx);
- if (ret != EOK) return 2;
-
- ret = die_if_parent_died();
- if (ret != EOK) {
- /* This is not fatal, don't return */
- DEBUG(2, ("Could not set up to exit when parent process does\n"));
- }
-
- ret = dp_process_init(main_ctx,
- main_ctx->event_ctx,
- main_ctx->confdb_ctx);
- if (ret != EOK) return 3;
-
- /* loop on main */
- server_loop(main_ctx);
-
- return 0;
-}
-
diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h
index 779da0f3..cfb2ec97 100644
--- a/server/providers/data_provider.h
+++ b/server/providers/data_provider.h
@@ -34,7 +34,6 @@
#include "dbus/dbus.h"
#include "sbus/sssd_dbus.h"
#include "sbus/sbus_client.h"
-#include "providers/dp_interfaces.h"
#include "../sss_client/sss_cli.h"
#define DATA_PROVIDER_VERSION 0x0001
@@ -47,24 +46,17 @@
#define MOD_OFFLINE 0x0000
#define MOD_ONLINE 0x0001
-#define DP_CLI_INTERFACE "org.freedesktop.sssd.dataprovider"
-#define DP_CLI_PATH "/org/freedesktop/sssd/dataprovider"
+#define DP_INTERFACE "org.freedesktop.sssd.dataprovider"
+#define DP_PATH "/org/freedesktop/sssd/dataprovider"
-#define DP_CLI_BACKEND 0x0001
-#define DP_CLI_FRONTEND 0x0002
-#define DP_CLI_TYPE_MASK 0x0003
+#define BE_PROVIDE_ACC_INFO (1<<8)
+#define BE_PROVIDE_PAM (1<<9)
+#define BE_PROVIDE_POLICY (1<<10)
-#define DP_CLI_PROVIDE_ACC_INFO (1<<8)
-#define DP_CLI_PROVIDE_PAM (1<<9)
-#define DP_CLI_PROVIDE_POLICY (1<<10)
-
-#define DP_CLI_METHOD_ONLINE "getOnline"
-#define DP_CLI_METHOD_GETACCTINFO "getAccountInfo"
-#define DP_CLI_METHOD_PAMHANDLER "pamHandler"
-
-#define DP_SRV_METHOD_REGISTER "RegisterService"
-#define DP_SRV_METHOD_GETACCTINFO "getAccountInfo"
-#define DP_SRV_METHOD_PAMHANDLER "pamHandler"
+#define DP_METHOD_REGISTER "RegisterService"
+#define DP_METHOD_ONLINE "getOnline"
+#define DP_METHOD_GETACCTINFO "getAccountInfo"
+#define DP_METHOD_PAMHANDLER "pamHandler"
#define DP_ERR_OK 0
#define DP_ERR_OFFLINE 1
@@ -138,12 +130,12 @@ bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd);
bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd,
DBusError *dbus_error);
-int dp_common_send_id(struct sbus_connection *conn,
- uint16_t cli_type, uint16_t version,
+int dp_common_send_id(struct sbus_connection *conn, uint16_t version,
const char *name, const char *domain);
/* from dp_sbus.c */
-int dp_get_sbus_address(TALLOC_CTX *mem_ctx, char **address);
+int dp_get_sbus_address(TALLOC_CTX *mem_ctx,
+ char **address, const char *domain_name);
#endif /* __DATA_PROVIDER_ */
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 2fa99da2..c891a0f1 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -57,20 +57,22 @@ struct sbus_interface monitor_be_interface = {
NULL
};
+static int client_registration(DBusMessage *message, struct sbus_connection *conn);
static int be_check_online(DBusMessage *message, struct sbus_connection *conn);
static int be_get_account_info(DBusMessage *message, struct sbus_connection *conn);
static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn);
struct sbus_method be_methods[] = {
- { DP_CLI_METHOD_ONLINE, be_check_online },
- { DP_CLI_METHOD_GETACCTINFO, be_get_account_info },
- { DP_CLI_METHOD_PAMHANDLER, be_pam_handler },
+ { DP_METHOD_REGISTER, client_registration },
+ { DP_METHOD_ONLINE, be_check_online },
+ { DP_METHOD_GETACCTINFO, be_get_account_info },
+ { DP_METHOD_PAMHANDLER, be_pam_handler },
{ NULL, NULL }
};
struct sbus_interface be_interface = {
- DP_CLI_INTERFACE,
- DP_CLI_PATH,
+ DP_INTERFACE,
+ DP_PATH,
SBUS_DEFAULT_VTABLE,
be_methods,
NULL
@@ -154,7 +156,7 @@ void be_mark_offline(struct be_ctx *ctx)
static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
{
- struct be_ctx *ctx;
+ struct be_client *becli;
DBusMessage *reply;
DBusConnection *dbus_conn;
dbus_bool_t dbret;
@@ -166,13 +168,13 @@ static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
user_data = sbus_conn_get_private_data(conn);
if (!user_data) return EINVAL;
- ctx = talloc_get_type(user_data, struct be_ctx);
- if (!ctx) return EINVAL;
+ becli = talloc_get_type(user_data, struct be_client);
+ if (!becli) return EINVAL;
reply = dbus_message_new_method_return(message);
if (!reply) return ENOMEM;
- if (be_is_offline(ctx)) {
+ if (be_is_offline(becli->bectx)) {
online = MOD_OFFLINE;
} else {
online = MOD_ONLINE;
@@ -189,7 +191,7 @@ static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
return EIO;
}
- dbus_conn = sbus_get_connection(ctx->dp_conn);
+ dbus_conn = sbus_get_connection(becli->conn);
dbus_connection_send(dbus_conn, reply, NULL);
dbus_message_unref(reply);
@@ -229,7 +231,7 @@ static void acctinfo_callback(struct be_req *req, int status,
return;
}
- dbus_conn = sbus_get_connection(req->be_ctx->dp_conn);
+ dbus_conn = sbus_get_connection(req->becli->conn);
dbus_connection_send(dbus_conn, reply, NULL);
dbus_message_unref(reply);
@@ -244,7 +246,7 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con
{
struct be_acct_req *req;
struct be_req *be_req;
- struct be_ctx *ctx;
+ struct be_client *becli;
DBusMessage *reply;
DBusError dbus_error;
dbus_bool_t dbret;
@@ -262,8 +264,8 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con
user_data = sbus_conn_get_private_data(conn);
if (!user_data) return EINVAL;
- ctx = talloc_get_type(user_data, struct be_ctx);
- if (!ctx) return EINVAL;
+ becli = talloc_get_type(user_data, struct be_client);
+ if (!becli) return EINVAL;
dbus_error_init(&dbus_error);
@@ -321,14 +323,15 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con
}
/* process request */
- be_req = talloc(ctx, struct be_req);
+ be_req = talloc(becli, struct be_req);
if (!be_req) {
err_maj = DP_ERR_FATAL;
err_min = ENOMEM;
err_msg = "Out of memory";
goto done;
}
- be_req->be_ctx = ctx;
+ be_req->becli = becli;
+ be_req->be_ctx = becli->bectx;
be_req->fn = acctinfo_callback;
be_req->pvt = reply;
@@ -346,7 +349,9 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con
be_req->req_data = req;
- ret = be_file_request(ctx, ctx->bet_info[BET_ID].bet_ops->handler, be_req);
+ ret = be_file_request(becli->bectx,
+ becli->bectx->bet_info[BET_ID].bet_ops->handler,
+ be_req);
if (ret != EOK) {
err_maj = DP_ERR_FATAL;
err_min = ret;
@@ -395,7 +400,7 @@ static void be_pam_handler_callback(struct be_req *req, int status,
return;
}
- dbus_conn = sbus_get_connection(req->be_ctx->dp_conn);
+ dbus_conn = sbus_get_connection(req->becli->conn);
dbus_connection_send(dbus_conn, reply, NULL);
dbus_message_unref(reply);
@@ -408,7 +413,7 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn)
{
DBusError dbus_error;
DBusMessage *reply;
- struct be_ctx *ctx;
+ struct be_client *becli;
dbus_bool_t ret;
void *user_data;
struct pam_data *pd = NULL;
@@ -418,8 +423,8 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn)
user_data = sbus_conn_get_private_data(conn);
if (!user_data) return EINVAL;
- ctx = talloc_get_type(user_data, struct be_ctx);
- if (!ctx) return EINVAL;
+ becli = talloc_get_type(user_data, struct be_client);
+ if (!becli) return EINVAL;
reply = dbus_message_new_method_return(message);
if (!reply) {
@@ -428,7 +433,18 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn)
return ENOMEM;
}
- pd = talloc_zero(ctx, struct pam_data);
+ be_req = talloc_zero(becli, struct be_req);
+ if (!be_req) {
+ DEBUG(7, ("talloc_zero failed.\n"));
+ goto done;
+ }
+
+ be_req->becli = becli;
+ be_req->be_ctx = becli->bectx;
+ be_req->fn = be_pam_handler_callback;
+ be_req->pvt = reply;
+
+ pd = talloc_zero(be_req, struct pam_data);
if (!pd) return ENOMEM;
dbus_error_init(&dbus_error);
@@ -461,23 +477,16 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn)
}
/* return an error if corresponding backend target is configured */
- if (!ctx->bet_info[target].bet_ops) {
+ if (!becli->bectx->bet_info[target].bet_ops) {
DEBUG(7, ("Undefined backend target.\n"));
goto done;
}
- be_req = talloc_zero(ctx, struct be_req);
- if (!be_req) {
- DEBUG(7, ("talloc_zero failed.\n"));
- goto done;
- }
-
- be_req->be_ctx = ctx;
- be_req->fn = be_pam_handler_callback;
- be_req->pvt = reply;
be_req->req_data = pd;
- ret = be_file_request(ctx, ctx->bet_info[target].bet_ops->handler, be_req);
+ ret = be_file_request(becli->bectx,
+ becli->bectx->bet_info[target].bet_ops->handler,
+ be_req);
if (ret != EOK) {
DEBUG(7, ("be_file_request failed.\n"));
goto done;
@@ -488,207 +497,226 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn)
done:
talloc_free(be_req);
- DEBUG(4, ("Sending result [%d][%s]\n", pam_status, ctx->domain->name));
+ DEBUG(4, ("Sending result [%d][%s]\n",
+ pam_status, becli->bectx->domain->name));
ret = dbus_message_append_args(reply,
DBUS_TYPE_UINT32, &pam_status,
- DBUS_TYPE_STRING, &ctx->domain->name,
+ DBUS_TYPE_STRING, &becli->bectx->domain->name,
DBUS_TYPE_INVALID);
- if (!ret) return EIO;
+ if (!ret) {
+ return EIO;
+ }
/* send reply back immediately */
sbus_conn_send_reply(conn, reply);
dbus_message_unref(reply);
- talloc_free(pd);
return EOK;
}
-/* mon_cli_init
- * sbus channel to the monitor daemon */
-static int mon_cli_init(struct be_ctx *ctx)
+static int be_client_destructor(void *ctx)
{
- char *sbus_address;
- int ret;
-
- /* Set up SBUS connection to the monitor */
- ret = monitor_get_sbus_address(ctx, &sbus_address);
- if (ret != EOK) {
- DEBUG(0, ("Could not locate monitor address.\n"));
- return ret;
+ struct be_client *becli = talloc_get_type(ctx, struct be_client);
+ if (becli->bectx) {
+ if (becli->bectx->nss_cli == becli) {
+ DEBUG(4, ("Removed NSS client\n"));
+ becli->bectx->nss_cli = NULL;
+ } else if (becli->bectx->pam_cli == becli) {
+ DEBUG(4, ("Removed PAM client\n"));
+ becli->bectx->pam_cli = NULL;
+ } else {
+ DEBUG(2, ("Unknown client removed ...\n"));
+ }
}
+ return 0;
+}
- ret = sbus_client_init(ctx, ctx->ev, sbus_address,
- &monitor_be_interface, &ctx->mon_conn,
- NULL, ctx);
- if (ret != EOK) {
- DEBUG(0, ("Failed to connect to monitor services.\n"));
- return ret;
- }
+static int client_registration(DBusMessage *message,
+ struct sbus_connection *conn)
+{
+ dbus_uint16_t version = DATA_PROVIDER_VERSION;
+ struct be_client *becli;
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_uint16_t cli_ver;
+ char *cli_name;
+ char *cli_domain;
+ dbus_bool_t dbret;
+ void *data;
- /* Identify ourselves to the monitor */
- ret = monitor_common_send_id(ctx->mon_conn,
- ctx->identity,
- DATA_PROVIDER_VERSION);
- if (ret != EOK) {
- DEBUG(0, ("Failed to identify to the monitor!\n"));
- return ret;
+ data = sbus_conn_get_private_data(conn);
+ becli = talloc_get_type(data, struct be_client);
+ if (!becli) {
+ DEBUG(0, ("Connection holds no valid init data\n"));
+ return EINVAL;
}
- return EOK;
-}
+ /* First thing, cancel the timeout */
+ DEBUG(4, ("Cancel DP ID timeout [%p]\n", becli->timeout));
+ talloc_zfree(becli->timeout);
-static void be_cli_reconnect_init(struct sbus_connection *conn, int status, void *pvt);
-
-/* be_cli_init
- * sbus channel to the data provider daemon */
-static int be_cli_init(struct be_ctx *ctx)
-{
- int ret, max_retries;
- char *sbus_address;
+ dbus_error_init(&dbus_error);
- /* Set up SBUS connection to the monitor */
- ret = dp_get_sbus_address(ctx, &sbus_address);
- if (ret != EOK) {
- DEBUG(0, ("Could not locate monitor address.\n"));
- return ret;
+ dbret = dbus_message_get_args(message, &dbus_error,
+ DBUS_TYPE_UINT16, &cli_ver,
+ DBUS_TYPE_STRING, &cli_name,
+ DBUS_TYPE_STRING, &cli_domain,
+ DBUS_TYPE_INVALID);
+ if (!dbret) {
+ DEBUG(1, ("Failed to parse message, killing connection\n"));
+ if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error);
+ sbus_disconnect(conn);
+ /* FIXME: should we just talloc_zfree(conn) ? */
+ return EIO;
}
- ret = sbus_client_init(ctx, ctx->ev, sbus_address,
- &be_interface, &ctx->dp_conn,
- NULL, ctx);
- if (ret != EOK) {
- DEBUG(0, ("Failed to connect to monitor services.\n"));
- return ret;
+ if (strcasecmp(cli_name, "NSS") == 0) {
+ becli->bectx->nss_cli = becli;
+ } else if (strcasecmp(cli_name, "PAM") == 0) {
+ becli->bectx->pam_cli = becli;
+ } else {
+ DEBUG(1, ("Unknown client! [%s]\n", cli_name));
}
+ talloc_set_destructor((TALLOC_CTX *)becli, be_client_destructor);
- /* Identify ourselves to the data provider */
- ret = dp_common_send_id(ctx->dp_conn,
- DP_CLI_BACKEND, DATA_PROVIDER_VERSION,
- "", ctx->domain->name);
- if (ret != EOK) {
- DEBUG(0, ("Failed to identify to the data provider!\n"));
- return ret;
+ DEBUG(4, ("Added Frontend client [%s]\n", cli_name));
+
+ /* reply that all is ok */
+ reply = dbus_message_new_method_return(message);
+ if (!reply) {
+ DEBUG(0, ("Dbus Out of memory!\n"));
+ return ENOMEM;
}
- /* Enable automatic reconnection to the Data Provider */
- ret = confdb_get_int(ctx->cdb, ctx, CONFDB_DP_CONF_ENTRY,
- CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries);
- if (ret != EOK) {
- DEBUG(0, ("Failed to set up automatic reconnection\n"));
- return ret;
+ dbret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_INVALID);
+ if (!dbret) {
+ DEBUG(0, ("Failed to build dbus reply\n"));
+ dbus_message_unref(reply);
+ sbus_disconnect(conn);
+ return EIO;
}
- sbus_reconnect_init(ctx->dp_conn, max_retries,
- be_cli_reconnect_init, ctx);
+ /* send reply back */
+ sbus_conn_send_reply(conn, reply);
+ dbus_message_unref(reply);
+ becli->initialized = true;
return EOK;
}
-static int be_finalize(struct be_ctx *ctx);
-static void be_shutdown(struct be_req *req, int status, const char *errstr);
-
-static void be_cli_reconnect_init(struct sbus_connection *conn, int status, void *pvt)
+static void init_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval t, void *ptr)
{
- int ret;
- struct be_ctx *be_ctx = talloc_get_type(pvt, struct be_ctx);
-
- /* Did we reconnect successfully? */
- if (status == SBUS_RECONNECT_SUCCESS) {
- DEBUG(1, ("Reconnected to the Data Provider.\n"));
-
- /* Identify ourselves to the data provider */
- ret = dp_common_send_id(be_ctx->dp_conn,
- DP_CLI_BACKEND, DATA_PROVIDER_VERSION,
- "", be_ctx->domain->name);
- if (ret != EOK) {
- DEBUG(0, ("Failed to send id to the data provider!\n"));
- } else {
- return;
- }
- }
+ struct be_client *becli;
- /* Handle failure */
- DEBUG(0, ("Could not reconnect to data provider.\n"));
+ DEBUG(2, ("Client timed out before Identification [%p]!\n", te));
- /* Kill the backend and let the monitor restart it */
- ret = be_finalize(be_ctx);
- if (ret != EOK) {
- DEBUG(0, ("Finalizing back-end failed with error [%d] [%s]\n",
- ret, strerror(ret)));
- be_shutdown(NULL, ret, NULL);
- }
+ becli = talloc_get_type(ptr, struct be_client);
+
+ sbus_disconnect(becli->conn);
+ talloc_zfree(becli);
}
-static void be_shutdown(struct be_req *req, int status, const char *errstr)
+static int be_client_init(struct sbus_connection *conn, void *data)
{
- /* Nothing left to do but exit() */
- if (status == EOK)
- exit(0);
-
- /* Something went wrong in finalize */
- DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
- status, errstr ? : strerror(status)));
+ struct be_ctx *bectx;
+ struct be_client *becli;
+ struct timeval tv;
- exit(1);
-}
+ bectx = talloc_get_type(data, struct be_ctx);
-static void be_id_shutdown(struct be_req *req, int status, const char *errstr)
-{
- struct be_req *shutdown_req;
- struct be_ctx *ctx;
- int ret;
+ /* hang off this memory to the connection so that when the connection
+ * is freed we can potentially call a destructor */
- if (status != EOK) {
- /* Something went wrong in finalize */
- DEBUG(0, ("Finalizing auth module failed with error [%d] [%s]\n",
- status, errstr ? : strerror(status)));
+ becli = talloc(conn, struct be_client);
+ if (!becli) {
+ DEBUG(0,("Out of memory?!\n"));
+ talloc_zfree(conn);
+ return ENOMEM;
}
+ becli->bectx = bectx;
+ becli->conn = conn;
+ becli->initialized = false;
- ctx = req->be_ctx;
+ /* 5 seconds should be plenty */
+ tv = tevent_timeval_current_ofs(5, 0);
- /* Now shutdown the id module too */
- shutdown_req = talloc_zero(ctx, struct be_req);
- if (!shutdown_req) {
- ret = ENOMEM;
- goto fail;
+ becli->timeout = tevent_add_timer(bectx->ev, becli,
+ tv, init_timeout, becli);
+ if (!becli->timeout) {
+ DEBUG(0,("Out of memory?!\n"));
+ talloc_zfree(conn);
+ return ENOMEM;
}
+ DEBUG(4, ("Set-up Backend ID timeout [%p]\n", becli->timeout));
- shutdown_req->be_ctx = ctx;
- shutdown_req->fn = be_id_shutdown;
+ /* Attach the client context to the connection context, so that it is
+ * always available when we need to manage the connection. */
+ sbus_conn_set_private_data(conn, becli);
- shutdown_req->pvt = ctx->bet_info[BET_ID].pvt_bet_data;
+ return EOK;
+}
- ret = be_file_request(ctx, ctx->bet_info[BET_ID].bet_ops->finalize, shutdown_req);
- if (ret == EOK)
- return;
+/* be_srv_init
+ * set up per-domain sbus channel */
+static int be_srv_init(struct be_ctx *ctx)
+{
+ char *sbus_address;
+ int ret;
-fail:
- /* If we got here, we couldn't shut down cleanly. */
- be_shutdown(NULL, ret, NULL);
+ /* Set up SBUS connection to the monitor */
+ ret = dp_get_sbus_address(ctx, &sbus_address, ctx->domain->name);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not get sbus backend address.\n"));
+ return ret;
+ }
+
+ ret = sbus_new_server(ctx, ctx->ev, sbus_address,
+ &be_interface, &ctx->sbus_srv,
+ be_client_init, ctx);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not set up sbus server.\n"));
+ return ret;
+ }
+
+ return EOK;
}
-static int be_finalize(struct be_ctx *ctx)
+/* mon_cli_init
+ * sbus channel to the monitor daemon */
+static int mon_cli_init(struct be_ctx *ctx)
{
- struct be_req *shutdown_req;
+ char *sbus_address;
int ret;
- shutdown_req = talloc_zero(ctx, struct be_req);
- if (!shutdown_req) {
- ret = ENOMEM;
- goto fail;
+ /* Set up SBUS connection to the monitor */
+ ret = monitor_get_sbus_address(ctx, &sbus_address);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not locate monitor address.\n"));
+ return ret;
}
- shutdown_req->be_ctx = ctx;
- shutdown_req->fn = be_id_shutdown;
- shutdown_req->pvt = ctx->bet_info[BET_AUTH].pvt_bet_data;
+ ret = sbus_client_init(ctx, ctx->ev, sbus_address,
+ &monitor_be_interface, &ctx->mon_conn,
+ NULL, ctx);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to connect to monitor services.\n"));
+ return ret;
+ }
- ret = be_file_request(ctx, ctx->bet_info[BET_AUTH].bet_ops->finalize, shutdown_req);
- if (ret == EOK) return EOK;
+ /* Identify ourselves to the monitor */
+ ret = monitor_common_send_id(ctx->mon_conn,
+ ctx->identity,
+ DATA_PROVIDER_VERSION);
+ if (ret != EOK) {
+ DEBUG(0, ("Failed to identify to the monitor!\n"));
+ return ret;
+ }
-fail:
- /* If we got here, we couldn't shut down cleanly. */
- DEBUG(0, ("ERROR: could not shut down cleanly.\n"));
- return ret;
+ return EOK;
}
static void be_target_access_permit(struct be_req *be_req)
@@ -854,7 +882,7 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = be_cli_init(ctx);
+ ret = be_srv_init(ctx);
if (ret != EOK) {
DEBUG(0, ("fatal error setting up server bus\n"));
return ret;
diff --git a/server/providers/dp_auth_util.c b/server/providers/dp_auth_util.c
index 80e9f167..b9175047 100644
--- a/server/providers/dp_auth_util.c
+++ b/server/providers/dp_auth_util.c
@@ -287,8 +287,7 @@ done:
dbus_message_unref(reply);
}
-int dp_common_send_id(struct sbus_connection *conn,
- uint16_t cli_type, uint16_t version,
+int dp_common_send_id(struct sbus_connection *conn, uint16_t version,
const char *name, const char *domain)
{
DBusPendingCall *pending_reply;
@@ -300,19 +299,18 @@ int dp_common_send_id(struct sbus_connection *conn,
/* create the message */
msg = dbus_message_new_method_call(NULL,
- DP_SRV_PATH,
- DP_SRV_INTERFACE,
- DP_SRV_METHOD_REGISTER);
+ DP_PATH,
+ DP_INTERFACE,
+ DP_METHOD_REGISTER);
if (msg == NULL) {
DEBUG(0, ("Out of memory?!\n"));
return ENOMEM;
}
- DEBUG(4, ("Sending ID to DP: (%d,%d,%s,%s)\n",
- cli_type, version, name, domain));
+ DEBUG(4, ("Sending ID to DP: (%d,%s,%s)\n",
+ version, name, domain));
ret = dbus_message_append_args(msg,
- DBUS_TYPE_UINT16, &cli_type,
DBUS_TYPE_UINT16, &version,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &domain,
diff --git a/server/providers/dp_backend.h b/server/providers/dp_backend.h
index f9949632..ae245ef8 100644
--- a/server/providers/dp_backend.h
+++ b/server/providers/dp_backend.h
@@ -65,6 +65,13 @@ struct be_offline_status {
bool offline;
};
+struct be_client {
+ struct be_ctx *bectx;
+ struct sbus_connection *conn;
+ struct tevent_timer *timeout;
+ bool initialized;
+};
+
struct be_ctx {
struct tevent_context *ev;
struct confdb_ctx *cdb;
@@ -76,7 +83,10 @@ struct be_ctx {
struct be_offline_status offstat;
struct sbus_connection *mon_conn;
- struct sbus_connection *dp_conn;
+ struct sbus_connection *sbus_srv;
+
+ struct be_client *nss_cli;
+ struct be_client *pam_cli;
struct loaded_be loaded_be[BET_MAX];
struct bet_info bet_info[BET_MAX];
@@ -89,6 +99,7 @@ struct bet_ops {
};
struct be_req {
+ struct be_client *becli;
struct be_ctx *be_ctx;
void *req_data;
diff --git a/server/providers/dp_interfaces.h b/server/providers/dp_interfaces.h
deleted file mode 100644
index 0b75f083..00000000
--- a/server/providers/dp_interfaces.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- SSSD
-
- Data Provider Helpers
-
- Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009
-
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef DP_INTERFACES_H_
-#define DP_INTERFACES_H_
-
-/* Data Provider */
-
-#define DP_SRV_INTERFACE "org.freedesktop.sssd.dataprovider"
-#define DP_SRV_PATH "/org/freedesktop/sssd/dataprovider"
-
-#define DP_METHOD_CHECK_ONLINE "isOnline"
-
-#endif /* DP_INTERFACES_H_ */
diff --git a/server/providers/dp_sbus.c b/server/providers/dp_sbus.c
index c5c9a001..f9dd2821 100644
--- a/server/providers/dp_sbus.c
+++ b/server/providers/dp_sbus.c
@@ -25,15 +25,16 @@
#include "confdb/confdb.h"
#include "sbus/sssd_dbus.h"
#include "providers/data_provider.h"
-#include "providers/dp_interfaces.h"
-int dp_get_sbus_address(TALLOC_CTX *mem_ctx, char **address)
+int dp_get_sbus_address(TALLOC_CTX *mem_ctx,
+ char **address, const char *domain_name)
{
char *default_address;
*address = NULL;
- default_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s",
- PIPE_PATH, DATA_PROVIDER_PIPE);
+ default_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s_%s",
+ PIPE_PATH, DATA_PROVIDER_PIPE,
+ domain_name);
if (default_address == NULL) {
return ENOMEM;
}
diff --git a/server/responder/common/responder.h b/server/responder/common/responder.h
index 558cba31..439bf873 100644
--- a/server/responder/common/responder.h
+++ b/server/responder/common/responder.h
@@ -55,6 +55,18 @@ struct cli_protocol_version {
const char *description;
};
+struct be_conn {
+ struct be_conn *next;
+ struct be_conn *prev;
+
+ const char *cli_name;
+ struct sss_domain_info *domain;
+
+ char *sbus_address;
+ struct sbus_interface *intf;
+ struct sbus_connection *conn;
+};
+
struct resp_ctx {
struct tevent_context *ev;
struct tevent_fd *lfde;
@@ -66,7 +78,7 @@ struct resp_ctx {
const char *priv_sock_name;
struct sbus_connection *mon_conn;
- struct sbus_connection *dp_conn;
+ struct be_conn *be_conns;
struct sss_domain_info *domains;
struct sysdb_ctx_list *db_list;
@@ -107,8 +119,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
const char *svc_name,
uint16_t svc_version,
struct sbus_interface *monitor_intf,
- uint16_t cli_type, uint16_t cli_version,
- const char *cli_name, const char *cli_domain,
+ const char *cli_name,
struct sbus_interface *dp_intf,
struct resp_ctx **responder_ctx);
@@ -116,6 +127,9 @@ int sss_parse_name(TALLOC_CTX *memctx,
struct sss_names_ctx *snctx,
const char *orig, char **domain, char **name);
+int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
+ struct be_conn **_conn);
+
/* responder_cmd.c */
int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds);
void sss_cmd_done(struct cli_ctx *cctx, void *freectx);
diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c
index 92270afd..37bbcb30 100644
--- a/server/responder/common/responder_common.c
+++ b/server/responder/common/responder_common.c
@@ -318,31 +318,40 @@ static int sss_monitor_init(struct resp_ctx *rctx,
static int sss_dp_init(struct resp_ctx *rctx,
struct sbus_interface *intf,
- uint16_t cli_type, uint16_t cli_version,
- const char *cli_name, const char *cli_domain)
+ const char *cli_name,
+ struct sss_domain_info *domain)
{
- char *sbus_address;
+ struct be_conn *be_conn;
int ret;
+ be_conn = talloc_zero(rctx, struct be_conn);
+ if (!be_conn) return ENOMEM;
+
+ be_conn->cli_name = cli_name;
+ be_conn->domain = domain;
+ be_conn->intf = intf;
+
/* Set up SBUS connection to the monitor */
- ret = dp_get_sbus_address(rctx, &sbus_address);
+ ret = dp_get_sbus_address(be_conn, &be_conn->sbus_address, domain->name);
if (ret != EOK) {
DEBUG(0, ("Could not locate DP address.\n"));
return ret;
}
-
- ret = sbus_client_init(rctx, rctx->ev, sbus_address,
- intf, &rctx->dp_conn,
+ ret = sbus_client_init(rctx, rctx->ev,
+ be_conn->sbus_address,
+ intf, &be_conn->conn,
NULL, NULL);
if (ret != EOK) {
DEBUG(0, ("Failed to connect to monitor services.\n"));
return ret;
}
+ DLIST_ADD_END(rctx->be_conns, be_conn, struct be_conn *);
+
/* Identify ourselves to the DP */
- ret = dp_common_send_id(rctx->dp_conn,
- cli_type, cli_version,
- cli_name, cli_domain);
+ ret = dp_common_send_id(be_conn->conn,
+ DATA_PROVIDER_VERSION,
+ cli_name, domain->name);
if (ret != EOK) {
DEBUG(0, ("Failed to identify to the DP!\n"));
return ret;
@@ -489,12 +498,12 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
const char *svc_name,
uint16_t svc_version,
struct sbus_interface *monitor_intf,
- uint16_t cli_type, uint16_t cli_version,
- const char *cli_name, const char *cli_domain,
+ const char *cli_name,
struct sbus_interface *dp_intf,
struct resp_ctx **responder_ctx)
{
struct resp_ctx *rctx;
+ struct sss_domain_info *dom;
int ret;
rctx = talloc_zero(mem_ctx, struct resp_ctx);
@@ -521,16 +530,18 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = sss_dp_init(rctx, dp_intf,
- cli_type, cli_version,
- cli_name, cli_domain);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up backend connector\n"));
- return ret;
- }
- else if (!rctx->dp_conn) {
- DEBUG(0, ("Data Provider is not yet available. Retrying.\n"));
- return EIO;
+ for (dom = rctx->domains; dom; dom = dom->next) {
+
+ /* skip local domain, it doesn't have a backend */
+ if (strcasecmp(dom->provider, "local") == 0) {
+ continue;
+ }
+
+ ret = sss_dp_init(rctx, dp_intf, cli_name, dom);
+ if (ret != EOK) {
+ DEBUG(0, ("fatal error setting up backend connector\n"));
+ return ret;
+ }
}
ret = sysdb_init(rctx, ev, cdb, NULL, false, &rctx->db_list);
@@ -558,3 +569,21 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return EOK;
}
+int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
+ struct be_conn **_conn)
+{
+ struct be_conn *iter;
+
+ if (!rctx->be_conns) return ENOENT;
+
+ for (iter = rctx->be_conns; iter; iter = iter->next) {
+ if (strcasecmp(domain, iter->domain->name) == 0) break;
+ }
+
+ if (!iter) return ENOENT;
+
+ *_conn = iter;
+
+ return EOK;
+}
+
diff --git a/server/responder/common/responder_dp.c b/server/responder/common/responder_dp.c
index c8200f80..236755f5 100644
--- a/server/responder/common/responder_dp.c
+++ b/server/responder/common/responder_dp.c
@@ -417,25 +417,27 @@ static int sss_dp_send_acct_req_create(struct resp_ctx *rctx,
dbus_bool_t dbret;
struct sss_dp_callback *cb;
struct sss_dp_req *sdp_req;
-
const char *attrs = "core";
+ struct be_conn *be_conn;
+ int ret;
/* double check dp_ctx has actually been initialized.
* in some pathological cases it may happen that nss starts up before
* dp connection code is actually able to establish a connection.
*/
- if (!rctx->dp_conn) {
- DEBUG(1, ("The Data Provider connection is not available yet!"
- " This maybe a bug, it shouldn't happen!\n"));
+ ret = sss_dp_get_domain_conn(rctx, domain, &be_conn);
+ if (ret != EOK) {
+ DEBUG(1, ("The Data Provider connection for %s is not available!"
+ " This maybe a bug, it shouldn't happen!\n", domain));
return EIO;
}
- dbus_conn = sbus_get_connection(rctx->dp_conn);
+ dbus_conn = sbus_get_connection(be_conn->conn);
/* create the message */
msg = dbus_message_new_method_call(NULL,
- DP_CLI_PATH,
- DP_CLI_INTERFACE,
- DP_SRV_METHOD_GETACCTINFO);
+ DP_PATH,
+ DP_INTERFACE,
+ DP_METHOD_GETACCTINFO);
if (msg == NULL) {
DEBUG(0,("Out of memory?!\n"));
return ENOMEM;
@@ -445,7 +447,6 @@ static int sss_dp_send_acct_req_create(struct resp_ctx *rctx,
domain, be_type, attrs, filter));
dbret = dbus_message_append_args(msg,
- DBUS_TYPE_STRING, &domain,
DBUS_TYPE_UINT32, &be_type,
DBUS_TYPE_STRING, &attrs,
DBUS_TYPE_STRING, &filter,
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index e7c2307d..319c0b74 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -229,8 +229,8 @@ static struct sbus_method nss_dp_methods[] = {
};
struct sbus_interface nss_dp_interface = {
- DP_CLI_INTERFACE,
- DP_CLI_PATH,
+ DP_INTERFACE,
+ DP_PATH,
SBUS_DEFAULT_VTABLE,
nss_dp_methods,
NULL
@@ -240,7 +240,7 @@ struct sbus_interface nss_dp_interface = {
static void nss_dp_reconnect_init(struct sbus_connection *conn,
int status, void *pvt)
{
- struct resp_ctx *rctx = talloc_get_type(pvt, struct resp_ctx);
+ struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
int ret;
/* Did we reconnect successfully? */
@@ -248,18 +248,19 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn,
DEBUG(1, ("Reconnected to the Data Provider.\n"));
/* Identify ourselves to the data provider */
- ret = dp_common_send_id(conn,
- DP_CLI_FRONTEND,
+ ret = dp_common_send_id(be_conn->conn,
DATA_PROVIDER_VERSION,
- "NSS", "");
+ "NSS", be_conn->domain->name);
/* all fine */
if (ret == EOK) return;
}
/* Failed to reconnect */
- DEBUG(0, ("Could not reconnect to data provider.\n"));
- /* Kill the backend and let the monitor restart it */
- nss_shutdown(rctx);
+ DEBUG(0, ("Could not reconnect to %s provider.\n",
+ be_conn->domain->name));
+
+ /* FIXME: kill the frontend and let the monitor restart it ? */
+ /* nss_shutdown(rctx); */
}
int nss_process_init(TALLOC_CTX *mem_ctx,
@@ -267,6 +268,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
struct confdb_ctx *cdb)
{
struct sss_cmd_table *nss_cmds;
+ struct be_conn *iter;
struct nss_ctx *nctx;
int ret, max_retries;
@@ -291,10 +293,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
NSS_SBUS_SERVICE_NAME,
NSS_SBUS_SERVICE_VERSION,
&monitor_nss_interface,
- DP_CLI_FRONTEND,
- DATA_PROVIDER_VERSION,
- "NSS", "",
- &nss_dp_interface,
+ "NSS", &nss_dp_interface,
&nctx->rctx);
if (ret != EOK) {
return ret;
@@ -317,9 +316,10 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- sbus_reconnect_init(nctx->rctx->dp_conn,
- max_retries,
- nss_dp_reconnect_init, nctx->rctx);
+ for (iter = nctx->rctx->be_conns; iter; iter = iter->next) {
+ sbus_reconnect_init(iter->conn, max_retries,
+ nss_dp_reconnect_init, iter);
+ }
DEBUG(1, ("NSS Initialization complete\n"));
diff --git a/server/responder/pam/pamsrv.c b/server/responder/pam/pamsrv.c
index f8af665b..53478522 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -88,8 +88,8 @@ static struct sbus_method pam_dp_methods[] = {
};
struct sbus_interface pam_dp_interface = {
- DP_CLI_INTERFACE,
- DP_CLI_PATH,
+ DP_INTERFACE,
+ DP_PATH,
SBUS_DEFAULT_VTABLE,
pam_dp_methods,
NULL
@@ -98,7 +98,7 @@ struct sbus_interface pam_dp_interface = {
static void pam_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt)
{
- struct resp_ctx *rctx = talloc_get_type(pvt, struct resp_ctx);
+ struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn);
int ret;
/* Did we reconnect successfully? */
@@ -106,18 +106,19 @@ static void pam_dp_reconnect_init(struct sbus_connection *conn, int status, void
DEBUG(1, ("Reconnected to the Data Provider.\n"));
/* Identify ourselves to the data provider */
- ret = dp_common_send_id(conn,
- DP_CLI_FRONTEND,
+ ret = dp_common_send_id(be_conn->conn,
DATA_PROVIDER_VERSION,
- "PAM", "");
+ "PAM", be_conn->domain->name);
/* all fine */
if (ret == EOK) return;
}
/* Handle failure */
- DEBUG(0, ("Could not reconnect to data provider.\n"));
- /* Kill the backend and let the monitor restart it */
- pam_shutdown(rctx);
+ DEBUG(0, ("Could not reconnect to %s provider.\n",
+ be_conn->domain->name));
+
+ /* FIXME: kill the frontend and let the monitor restart it ? */
+ /* pam_shutdown(rctx); */
}
static int pam_process_init(TALLOC_CTX *mem_ctx,
@@ -125,6 +126,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
struct confdb_ctx *cdb)
{
struct sss_cmd_table *pam_cmds;
+ struct be_conn *iter;
struct resp_ctx *rctx;
int ret, max_retries;
@@ -137,10 +139,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
PAM_SBUS_SERVICE_NAME,
PAM_SBUS_SERVICE_VERSION,
&monitor_pam_interface,
- DP_CLI_FRONTEND,
- DATA_PROVIDER_VERSION,
- "PAM", "",
- &pam_dp_interface,
+ "PAM", &pam_dp_interface,
&rctx);
if (ret != EOK) {
return ret;
@@ -157,8 +156,10 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- sbus_reconnect_init(rctx->dp_conn, max_retries,
- pam_dp_reconnect_init, rctx);
+ for (iter = rctx->be_conns; iter; iter = iter->next) {
+ sbus_reconnect_init(iter->conn, max_retries,
+ pam_dp_reconnect_init, iter);
+ }
return EOK;
}
diff --git a/server/responder/pam/pamsrv_dp.c b/server/responder/pam/pamsrv_dp.c
index 7ea2b7e4..071d09b8 100644
--- a/server/responder/pam/pamsrv_dp.c
+++ b/server/responder/pam/pamsrv_dp.c
@@ -82,26 +82,30 @@ done:
int pam_dp_send_req(struct pam_auth_req *preq, int timeout)
{
struct pam_data *pd = preq->pd;
+ struct be_conn *be_conn;
DBusMessage *msg;
DBusPendingCall *pending_reply;
DBusConnection *dbus_conn;
dbus_bool_t ret;
+ int res;
/* double check dp_ctx has actually been initialized.
* in some pathological cases it may happen that nss starts up before
* dp connection code is actually able to establish a connection.
*/
- if (!preq->cctx->rctx->dp_conn) {
- DEBUG(1, ("The Data Provider connection is not available yet!"
- " This maybe a bug, it shouldn't happen!\n"));
+ res = sss_dp_get_domain_conn(preq->cctx->rctx,
+ preq->domain->name, &be_conn);
+ if (res != EOK) {
+ DEBUG(1, ("The Data Provider connection for %s is not available!"
+ " This maybe a bug, it shouldn't happen!\n", preq->domain));
return EIO;
}
- dbus_conn = sbus_get_connection(preq->cctx->rctx->dp_conn);
+ dbus_conn = sbus_get_connection(be_conn->conn);
msg = dbus_message_new_method_call(NULL,
- DP_CLI_PATH,
- DP_CLI_INTERFACE,
- DP_SRV_METHOD_PAMHANDLER);
+ DP_PATH,
+ DP_INTERFACE,
+ DP_METHOD_PAMHANDLER);
if (msg == NULL) {
DEBUG(0,("Out of memory?!\n"));
return ENOMEM;