From 7a7adf458bd8519e68960748af0222b794e0a02b Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 23 Feb 2009 16:54:02 -0500 Subject: Add D-BUS introspection to InfoPipe This function is necessary to play nice with D-BUS clients built in multiple languages. It will read in the XML file on the first request and store the returned XML as a component of the sbus_message_handler_ctx for the connection. All subsequent requests during the process' lifetime will be returned from the stored memory. This is perfectly safe, as the available methods cannot change during the process lifetime. --- server/Makefile.in | 12 ++++++-- server/configure.ac | 3 ++ server/infopipe/infopipe.c | 77 ++++++++++++++++++++++++++++++++++++++++++++-- server/infopipe/infopipe.h | 2 ++ server/sbus/sssd_dbus.h | 1 + 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/server/Makefile.in b/server/Makefile.in index b8009bf9..eca8bb1a 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -17,6 +17,7 @@ sharedbuilddir = @sharedbuilddir@ INSTALLCMD = @INSTALL@ EXTRA_OBJ=@EXTRA_OBJ@ SSSD_LIBEXEC_PATH = @SSSD_LIBEXEC_PATH@ +SSSD_INTROSPECT_PATH = @SSSD_INTROSPECT_PATH@ PACKAGE_VERSION = @PACKAGE_VERSION@ srvdir = $(srcdir) @@ -55,7 +56,8 @@ LIBS = @LIBS@ $(TALLOC_LIBS) $(TDB_LIBS) $(EVENTS_LIBS) $(POPT_LIBS) $(LDB_LIBS) PICFLAG = @PICFLAG@ CFLAGS += -g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \ $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(EVENTS_CFLAGS) $(LDB_CFLAGS) $(DBUS_CFLAGS) $(CHECK_CFLAGS)\ - -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"$(SHLIBEXT)\" -DSSSD_LIBEXEC_PATH=\"$(SSSD_LIBEXEC_PATH)\" -DUSE_MMAP=1 @CFLAGS@ + -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"$(SHLIBEXT)\" -DSSSD_LIBEXEC_PATH=\"$(SSSD_LIBEXEC_PATH)\" -DSSSD_INTROSPECT_PATH=\"$(SSSD_INTROSPECT_PATH)\"\ + -DUSE_MMAP=1 @CFLAGS@ MDLD = @MDLD@ MDLD_FLAGS = @MDLD_FLAGS@ @@ -73,6 +75,7 @@ DBUS_SYSBUS_POLICY_DIR = @sysbuspath@ LIBEXECBINS = sbin/sssd_nss sbin/sssd_dp sbin/sssd_be sbin/sssd_info sbin/sssd_pk DBUS_SYSBUS_POLICIES = infopipe/org.freeipa.sssd.infopipe.conf +INFP_INTROSPECT_XML = infopipe/org.freeipa.sssd.infopipe.Introspect.xml BINS = sbin/sssd $(LIBEXECBINS) SOLIBS = lib/libsss_proxy.$(SHLIBEXT) lib/memberof.$(SHLIBEXT) TESTS = tests/sysdb-tests @@ -110,7 +113,11 @@ install:: all installdirs installheaders installlibs installbin installsupport ${INSTALLCMD} -m 755 lib/memberof.$(SHLIBEXT) $(DESTDIR)$(libdir) installdirs:: - mkdir -p $(DESTDIR)$(includedir) $(DESTDIR)$(libdir) $(DESTDIR)$(sbindir) $(DBUS_SYSBUS_POLICY_DIR) + mkdir -p $(DESTDIR)$(includedir) \ + $(DESTDIR)$(libdir) \ + $(DESTDIR)$(sbindir) \ + $(DBUS_SYSBUS_POLICY_DIR) \ + $(SSSD_INTROSPECT_PATH)/infopipe installheaders:: installdirs ifneq (x$(headers), x) @@ -126,3 +133,4 @@ installbin:: installdirs installsupport:: installdirs cp $(DBUS_SYSBUS_POLICIES) $(DBUS_SYSBUS_POLICY_DIR) + cp $(INFP_INTROSPECT_XML) $(SSSD_INTROSPECT_PATH)/infopipe diff --git a/server/configure.ac b/server/configure.ac index fda38db2..4ef3ffc9 100644 --- a/server/configure.ac +++ b/server/configure.ac @@ -29,6 +29,9 @@ EXTRA_OBJ="" SSSD_LIBEXEC_PATH=$libexecdir/$PACKAGE_NAME AC_SUBST(SSSD_LIBEXEC_PATH) +SSSD_INTROSPECT_PATH=$datarootdir/$PACKAGE_NAME/introspect +AC_SUBST(SSSD_INTROSPECT_PATH) + m4_include(build_macros.m4) BUILD_WITH_SHARED_BUILD_DIR diff --git a/server/infopipe/infopipe.c b/server/infopipe/infopipe.c index 1e7a88c8..9c129d26 100644 --- a/server/infopipe/infopipe.c +++ b/server/infopipe/infopipe.c @@ -132,11 +132,82 @@ struct sbus_method infp_methods[] = { { NULL, NULL } }; +#define INTROSPECT_CHUNK_SIZE 128 + int infp_introspect(DBusMessage *message, struct sbus_message_ctx *reply) { - /* TODO: actually return the file */ - reply->reply_message = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, "Not yet implemented"); - return EOK; + FILE *xml_stream; + char *introspect_xml; + char *chunk; + TALLOC_CTX *tmp_ctx; + unsigned long xml_size; + size_t chunk_size; + int ret; + dbus_bool_t dbret; + + tmp_ctx = talloc_new(reply); + if(tmp_ctx == NULL) { + return ENOMEM; + } + + if (reply->mh_ctx->introspection_xml == NULL) { + /* Read in the Introspection XML the first time */ + xml_stream = fopen(SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, "r"); + if(xml_stream == NULL) { + DEBUG(0, ("Could not open the introspection XML for reading: [%d] [%s].\n", errno, SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML)); + return errno; + } + + chunk = talloc_size(tmp_ctx, INTROSPECT_CHUNK_SIZE); + if (chunk == NULL) { + ret = ENOMEM; + goto done; + } + + xml_size = 0; + introspect_xml = NULL; + do { + chunk_size = fread(chunk, 1, INTROSPECT_CHUNK_SIZE, xml_stream); + introspect_xml = talloc_realloc_size(tmp_ctx, introspect_xml, xml_size+chunk_size+1); + if (introspect_xml == NULL) { + ret = ENOMEM; + goto done; + } + memcpy(introspect_xml+xml_size, chunk, chunk_size); + xml_size += chunk_size; + } while(chunk_size == INTROSPECT_CHUNK_SIZE); + introspect_xml[xml_size] = '\0'; + talloc_free(chunk); + + /* Store the instrospection XML for future calls */ + reply->mh_ctx->introspection_xml = introspect_xml; + talloc_steal(reply->mh_ctx, introspect_xml); + } + else { + /* Subsequent calls should just reuse the saved value */ + introspect_xml = reply->mh_ctx->introspection_xml; + } + + /* Return the Introspection XML */ + reply->reply_message = dbus_message_new_method_return(message); + if (reply->reply_message == NULL) { + ret = ENOMEM; + goto done; + } + dbret = dbus_message_append_args(reply->reply_message, + DBUS_TYPE_STRING, &introspect_xml, + DBUS_TYPE_INVALID); + if (!dbret) { + ret = ENOMEM; + goto done; + } + + DEBUG(9, ("%s\n", introspect_xml)); + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; } static int infp_process_init(TALLOC_CTX *mem_ctx, diff --git a/server/infopipe/infopipe.h b/server/infopipe/infopipe.h index aabc2bfa..83a3d8d4 100644 --- a/server/infopipe/infopipe.h +++ b/server/infopipe/infopipe.h @@ -25,6 +25,8 @@ #include #include "sbus/sssd_dbus.h" +#define INFP_INTROSPECT_XML "infopipe/org.freeipa.sssd.infopipe.Introspect.xml" + #define INFOPIPE_DBUS_NAME "org.freeipa.sssd.infopipe1" #define INFOPIPE_INTERFACE "org.freeipa.sssd.infopipe1" #define INFOPIPE_PATH "/org/freeipa/sssd/infopipe1" diff --git a/server/sbus/sssd_dbus.h b/server/sbus/sssd_dbus.h index bc65e314..20165ffb 100644 --- a/server/sbus/sssd_dbus.h +++ b/server/sbus/sssd_dbus.h @@ -70,6 +70,7 @@ struct sbus_method_ctx { struct sbus_message_handler_ctx { struct sbus_conn_ctx *conn_ctx; struct sbus_method_ctx *method_ctx; + char *introspection_xml; }; struct sbus_message_ctx { -- cgit