diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-10-02 19:36:01 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2009-10-09 16:11:08 -0400 |
commit | dc55d62f4d9f6520ffcb4aa8c6beb308896d9fbb (patch) | |
tree | 7842b16b9ce9e4367c2a9a6f05db25fc40b2ab08 /server | |
parent | 1f2b3f82f9896a99f8f2b8b2145af47402a9c3c6 (diff) | |
download | sssd-dc55d62f4d9f6520ffcb4aa8c6beb308896d9fbb.tar.gz sssd-dc55d62f4d9f6520ffcb4aa8c6beb308896d9fbb.tar.bz2 sssd-dc55d62f4d9f6520ffcb4aa8c6beb308896d9fbb.zip |
Remove DP process
Turn the backend process into data provider servers
Make Frontends (pam, nss) directly attach to the backends
Diffstat (limited to 'server')
-rw-r--r-- | server/Makefile.am | 8 | ||||
-rw-r--r-- | server/monitor/monitor.c | 55 | ||||
-rw-r--r-- | server/providers/data_provider.c | 1016 | ||||
-rw-r--r-- | server/providers/data_provider.h | 32 | ||||
-rw-r--r-- | server/providers/data_provider_be.c | 384 | ||||
-rw-r--r-- | server/providers/dp_auth_util.c | 14 | ||||
-rw-r--r-- | server/providers/dp_backend.h | 13 | ||||
-rw-r--r-- | server/providers/dp_interfaces.h | 32 | ||||
-rw-r--r-- | server/providers/dp_sbus.c | 9 | ||||
-rw-r--r-- | server/responder/common/responder.h | 20 | ||||
-rw-r--r-- | server/responder/common/responder_common.c | 73 | ||||
-rw-r--r-- | server/responder/common/responder_dp.c | 19 | ||||
-rw-r--r-- | server/responder/nss/nsssrv.c | 32 | ||||
-rw-r--r-- | server/responder/pam/pamsrv.c | 31 | ||||
-rw-r--r-- | server/responder/pam/pamsrv_dp.c | 18 |
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; |