summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2008-11-03 17:18:49 -0500
committerSimo Sorce <idra@samba.org>2008-11-03 17:18:49 -0500
commita2c6e0e0beb75e0a8fa7e3e07e9443d97ea2b731 (patch)
treec59aa17b7b63327d1a63561586ab7ba4ea70edf0
parentddbc682f58bcee78ac1dbd24b3c44da67512d888 (diff)
downloadsssd-a2c6e0e0beb75e0a8fa7e3e07e9443d97ea2b731.tar.gz
sssd-a2c6e0e0beb75e0a8fa7e3e07e9443d97ea2b731.tar.xz
sssd-a2c6e0e0beb75e0a8fa7e3e07e9443d97ea2b731.zip
Add support for dbus comunication in the nss service
Add utility function in confdb Make all component fetch the dbus socket from the confdb
-rw-r--r--server/confdb/confdb.c34
-rw-r--r--server/confdb/confdb.h4
-rw-r--r--server/monitor.c13
-rw-r--r--server/nss/nsssrv.c161
-rw-r--r--server/nss/nsssrv.h13
-rw-r--r--server/sbus/tests/test_client.c11
-rw-r--r--server/sbus_interfaces.h2
7 files changed, 197 insertions, 41 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 18b369caf..1dd799827 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -282,6 +282,40 @@ done:
return ret;
}
+int confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
+ const char *section, const char *attribute,
+ const char *defstr, char **result)
+{
+ char **values;
+ char *restr;
+ int ret;
+
+ ret = confdb_get_param(cdb, ctx, section, attribute, &values);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ if (values[0]) {
+ if (values[1] != NULL) {
+ /* too many values */
+ talloc_free(values);
+ return EINVAL;
+ }
+ restr = talloc_steal(ctx, values[0]);
+ } else {
+ restr = talloc_strdup(ctx, defstr);
+ }
+ if (!restr) {
+ talloc_free(values);
+ return ENOMEM;
+ }
+
+ talloc_free(values);
+
+ *result = restr;
+ return EOK;
+}
+
static int confdb_test(struct confdb_ctx *cdb)
{
char **values;
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index 8becdf99c..b8b685311 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -34,6 +34,10 @@ int confdb_get_param(struct confdb_ctx *cdb,
const char *attribute,
char ***values);
+int confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
+ const char *section, const char *attribute,
+ const char *defstr, char **result);
+
int confdb_init(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct confdb_ctx **cdb_ctx);
diff --git a/server/monitor.c b/server/monitor.c
index f7ba80098..5574d70c8 100644
--- a/server/monitor.c
+++ b/server/monitor.c
@@ -32,9 +32,6 @@
#include "sbus/sssd_dbus.h"
#include "sbus_interfaces.h"
-/* TODO: get this value from LDB */
-#define DBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus"
-
struct mt_ctx {
struct event_context *ev;
struct confdb_ctx *cdb;
@@ -84,8 +81,16 @@ struct sbus_method monitor_methods[] = {
static int monitor_dbus_init(struct mt_ctx *ctx)
{
struct sbus_method_ctx *sd_ctx;
+ char *sbus_address;
int ret;
+ ret = confdb_get_string(ctx->cdb, ctx,
+ "config.services.monitor", "sbusAddress",
+ DEFAULT_SBUS_ADDRESS, &sbus_address);
+ if (ret != EOK) {
+ return ret;
+ }
+
sd_ctx = talloc_zero(ctx, struct sbus_method_ctx);
if (!sd_ctx) {
return ENOMEM;
@@ -105,7 +110,7 @@ static int monitor_dbus_init(struct mt_ctx *ctx)
sd_ctx->methods = monitor_methods;
sd_ctx->message_handler = NULL; /* Use the default message_handler */
- ret = sbus_new_server(ctx->ev, sd_ctx, DBUS_ADDRESS, dbus_service_init);
+ ret = sbus_new_server(ctx->ev, sd_ctx, sbus_address, dbus_service_init);
return ret;
}
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index d1dfa3444..04eead6dd 100644
--- a/server/nss/nsssrv.c
+++ b/server/nss/nsssrv.c
@@ -35,6 +35,16 @@
#include "nss/nsssrv.h"
#include "nss/nsssrv_ldb.h"
#include "confdb/confdb.h"
+#include "dbus/dbus.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus_interfaces.h"
+
+static int provide_identity(DBusMessage *message, void *data, DBusMessage **r);
+
+struct sbus_method nss_sbus_methods[] = {
+ {SERVICE_METHOD_IDENTITY, provide_identity},
+ {NULL, NULL}
+};
static void set_nonblocking(int fd)
{
@@ -193,16 +203,108 @@ static void accept_fd_handler(struct event_context *ev,
return;
}
+static int provide_identity(DBusMessage *message, void *data, DBusMessage **r)
+{
+ dbus_uint16_t version = NSS_SBUS_SERVICE_VERSION;
+ const char *name = NSS_SBUS_SERVICE_NAME;
+ DBusMessage *reply;
+ dbus_bool_t ret;
+
+ reply = dbus_message_new_method_return(message);
+ ret = dbus_message_append_args(reply,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ return EIO;
+ }
+
+ *r = reply;
+ return EOK;
+}
+
+static int nss_sbus_init(struct nss_ctx *nctx)
+{
+ struct sbus_method_ctx *cli_sm_ctx;
+ struct sbus_method_ctx *srv_sm_ctx;
+ struct nss_sbus_ctx *ns_ctx;
+ DBusConnection *dbus_conn;
+ char *sbus_address;
+ int ret;
+
+ ret = confdb_get_string(nctx->cdb, nctx,
+ "config.services.monitor", "sbusAddress",
+ DEFAULT_SBUS_ADDRESS, &sbus_address);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ns_ctx = talloc(nctx, struct nss_sbus_ctx);
+ if (!ns_ctx) {
+ return ENOMEM;
+ }
+ ns_ctx->ev = nctx->ev;
+
+ ret = sbus_new_connection(ns_ctx, ns_ctx->ev,
+ sbus_address,
+ &ns_ctx->scon_ctx, NULL);
+ if (ret != EOK) {
+ talloc_free(ns_ctx);
+ return ret;
+ }
+ dbus_conn = sbus_get_connection(ns_ctx->scon_ctx);
+ dbus_connection_set_exit_on_disconnect(dbus_conn, TRUE);
+
+ /* set up handler for service methods */
+ srv_sm_ctx = talloc_zero(ns_ctx, struct sbus_method_ctx);
+ if (!srv_sm_ctx) {
+ talloc_free(ns_ctx);
+ return ENOMEM;
+ }
+ srv_sm_ctx->interface = talloc_strdup(srv_sm_ctx, SERVICE_INTERFACE);
+ srv_sm_ctx->path = talloc_strdup(srv_sm_ctx, SERVICE_PATH);
+ if (!srv_sm_ctx->interface || !srv_sm_ctx->path) {
+ talloc_free(ns_ctx);
+ return ENOMEM;
+ }
+ srv_sm_ctx->methods = nss_sbus_methods;
+ sbus_conn_add_method_ctx(ns_ctx->scon_ctx, srv_sm_ctx);
+
+ /* set up client stuff */
+ cli_sm_ctx = talloc(ns_ctx, struct sbus_method_ctx);
+ if (!cli_sm_ctx) {
+ talloc_free(ns_ctx);
+ return ENOMEM;
+ }
+ cli_sm_ctx->interface = talloc_strdup(cli_sm_ctx, MONITOR_DBUS_INTERFACE);
+ cli_sm_ctx->path = talloc_strdup(cli_sm_ctx, MONITOR_DBUS_PATH);
+ if (!cli_sm_ctx->interface || !cli_sm_ctx->path) {
+ talloc_free(ns_ctx);
+ return ENOMEM;
+ }
+ ns_ctx->sm_ctx = cli_sm_ctx;
+
+ nctx->ns_ctx = ns_ctx;
+
+ return EOK;
+}
+
/* create a unix socket and listen to it */
-static void set_unix_socket(struct event_context *ev,
- struct nss_ctx *nctx,
- const char *sock_name)
+static int set_unix_socket(struct nss_ctx *nctx)
{
struct sockaddr_un addr;
+ int ret;
+
+ ret = confdb_get_string(nctx->cdb, nctx,
+ "config.services.nss", "unixSocket",
+ SSS_NSS_SOCKET_NAME, &nctx->sock_name);
+ if (ret != EOK) {
+ return ret;
+ }
nctx->lfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (nctx->lfd == -1) {
- return;
+ return EIO;
}
/* Set the umask so that permissions are set right on the socket.
@@ -214,76 +316,73 @@ static void set_unix_socket(struct event_context *ev,
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, sock_name, sizeof(addr.sun_path));
+ strncpy(addr.sun_path, nctx->sock_name, sizeof(addr.sun_path));
/* make sure we have no old sockets around */
- unlink(sock_name);
+ unlink(nctx->sock_name);
if (bind(nctx->lfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- DEBUG(0,("Unable to bind on socket '%s'\n", sock_name));
+ DEBUG(0,("Unable to bind on socket '%s'\n", nctx->sock_name));
goto failed;
}
if (listen(nctx->lfd, 10) != 0) {
- DEBUG(0,("Unable to listen on socket '%s'\n", sock_name));
+ DEBUG(0,("Unable to listen on socket '%s'\n", nctx->sock_name));
goto failed;
}
- nctx->lfde = event_add_fd(ev, nctx, nctx->lfd,
- EVENT_FD_READ, accept_fd_handler, nctx);
+ nctx->lfde = event_add_fd(nctx->ev, nctx, nctx->lfd,
+ EVENT_FD_READ, accept_fd_handler, nctx);
/* we want default permissions on created files to be very strict,
so set our umask to 0177 */
umask(0177);
- return;
+ return EOK;
failed:
/* we want default permissions on created files to be very strict,
so set our umask to 0177 */
umask(0177);
close(nctx->lfd);
+ return EIO;
}
void nss_task_init(struct task_server *task)
{
- struct confdb_ctx *cdb;
struct nss_ctx *nctx;
- const char *sock_name;
- char **values;
int ret;
task_server_set_title(task, "sssd[nsssrv]");
- ret = confdb_init(task, task->event_ctx, &cdb);
- if (ret != EOK) {
- task_server_terminate(task, "fatal error initializing confdb\n");
- return;
- }
-
nctx = talloc_zero(task, struct nss_ctx);
if (!nctx) {
task_server_terminate(task, "fatal error initializing nss_ctx\n");
return;
}
+ nctx->ev = task->event_ctx;
nctx->task = task;
- ret = confdb_get_param(cdb, nctx,
- "config.services.nss", "unixSocket", &values);
+ ret = confdb_init(task, task->event_ctx, &nctx->cdb);
if (ret != EOK) {
- task_server_terminate(task, "fatal error reading configuration\n");
+ task_server_terminate(task, "fatal error initializing confdb\n");
return;
}
- if (values[0]) {
- sock_name = talloc_steal(nctx, values[0]);
- } else {
- sock_name = talloc_strdup(nctx, SSS_NSS_SOCKET_NAME);
- }
- talloc_free(values);
- set_unix_socket(task->event_ctx, nctx, sock_name);
+ ret = nss_sbus_init(nctx);
+ if (ret != EOK) {
+ task_server_terminate(task, "fatal error setting up message bus\n");
+ return;
+ }
- ret = nss_ldb_init(nctx, task->event_ctx, cdb, &nctx->lctx);
+ ret = nss_ldb_init(nctx, nctx->ev, nctx->cdb, &nctx->lctx);
if (ret != EOK) {
task_server_terminate(task, "fatal error initializing nss_ctx\n");
return;
}
+
+ /* after all initializations we are ready to listen on our socket */
+ ret = set_unix_socket(nctx);
+ if (ret != EOK) {
+ task_server_terminate(task, "fatal error initializing socket\n");
+ return;
+ }
}
diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h
index e00ccced5..300b8af31 100644
--- a/server/nss/nsssrv.h
+++ b/server/nss/nsssrv.h
@@ -29,14 +29,27 @@
#include "ldb.h"
#include "../nss_client/sss_nss.h"
+#define NSS_SBUS_SERVICE_VERSION 0x0001
+#define NSS_SBUS_SERVICE_NAME "NSS"
+
struct nss_ldb_ctx;
struct getent_ctx;
+struct nss_sbus_ctx {
+ struct event_context *ev;
+ struct sbus_method_ctx *sm_ctx;
+ struct sbus_conn_ctx *scon_ctx;
+};
+
struct nss_ctx {
+ struct event_context *ev;
struct task_server *task;
struct fd_event *lfde;
int lfd;
struct nss_ldb_ctx *lctx;
+ struct confdb_ctx *cdb;
+ char *sock_name;
+ struct nss_sbus_ctx *ns_ctx;
};
struct cli_ctx {
diff --git a/server/sbus/tests/test_client.c b/server/sbus/tests/test_client.c
index bd7f42d57..06cd11338 100644
--- a/server/sbus/tests/test_client.c
+++ b/server/sbus/tests/test_client.c
@@ -7,9 +7,6 @@
#include "sbus/sssd_dbus.h"
#include "sbus_interfaces.h"
-/* TODO: get this value from LDB */
-#define DBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus"
-
/* Identity */
#define TEST_CLIENT_NAME "testclient"
#define TEST_CLIENT_VERSION 1
@@ -149,13 +146,13 @@ int main (int argc, const char *argv[])
printf("Out of memory!?\n");
exit(1);
}
-
+
test_ctx = talloc(event_ctx, struct test_cli_ctx);
if (!test_ctx) {
printf("Out of memory!?\n");
exit(1);
}
-
+
test_ctx->ev = event_ctx;
ctx->interface = talloc_strdup(ctx, MONITOR_DBUS_INTERFACE);
ctx->path = talloc_strdup(ctx, MONITOR_DBUS_PATH);
@@ -164,7 +161,9 @@ int main (int argc, const char *argv[])
exit(1);
}
- ret = sbus_new_connection(test_ctx, test_ctx->ev, DBUS_ADDRESS, &(test_ctx->dct_ctx), NULL);
+ ret = sbus_new_connection(test_ctx, test_ctx->ev,
+ DEFAULT_SBUS_ADDRESS,
+ &test_ctx->dct_ctx, NULL);
if (ret != EOK) {
exit(1);
}
diff --git a/server/sbus_interfaces.h b/server/sbus_interfaces.h
index 5c6c52e74..106a54957 100644
--- a/server/sbus_interfaces.h
+++ b/server/sbus_interfaces.h
@@ -37,3 +37,5 @@
/* Service Methods */
#define SERVICE_METHOD_IDENTITY "getIdentity"
+#define DEFAULT_SBUS_ADDRESS "unix:path=/var/lib/sss/pipes/private/dbus"
+