Hi, I've been working on re-adding a public DBus API to SSSD lately, based on Stephen's InfoPipe code. While I'm not finished yet, the interface is also important to Pavel's OpenLMI thesis, so I'll be sending the patches for review as the individual subtasks are finished and rebased on top of Stef's recent patches.
Attached are two patches that I think are ready to be reviewed and merged with some minor exceptions or questions. The review would be a good opportunity to solve those. [PATCH 1/2] IFP: Re-add the InfoPipe server This commit only adds the responder and the needed plumbing. No DBus related code is in yet. With this patch, I was wondering whether to build the code by default, or only when --enable-experimental-features is set until the whole feature is finished? Also, with the current code, all responders spawn a client socket now, but this responder listens on the system bus instead. I created https://fedorahosted.org/sssd/ticket/2290 for this purpose -- Pavel, feel free to take it. [PATCH 2/2] IFP: Connect to the system bus Adds the possibility for the InfoPipe responder to connect to the system bus. At the moment, only a dummy method "Ping" is provided. The method only accepts a single string parameter that has to be 'ping'. To test, you can call the Ping method like this: dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.Ping 'string:Ping' Or test that the code can catch wrong options: dbus-send --print-reply --system --dest=org.freedesktop.sssd.infopipe /org/freedesktop/sssd/infopipe org.freedesktop.sssd.infopipe.Ping 'string:sdf' I'll be sending next round of patches later this week. Hopefully this would unblock Pavel's work.
From 07aacbbbd259dfa0ffb388bc87ddc140155b7fb4 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Wed, 2 Oct 2013 14:59:35 +0200 Subject: [PATCH 1/2] IFP: Re-add the InfoPipe server Related: https://fedorahosted.org/sssd/ticket/2072 This commit only adds the responder and the needed plumbing. No DBus related code is in yet. --- Makefile.am | 19 +++ configure.ac | 1 + contrib/sssd.spec.in | 17 +++ src/conf_macros.m4 | 16 +++ src/confdb/confdb.h | 3 + src/man/Makefile.am | 9 +- src/man/include/seealso.xml | 6 + src/man/sssd-ifp.5.xml | 46 +++++++ src/man/sssd.conf.5.xml | 1 + src/monitor/monitor.c | 2 +- src/providers/data_provider_be.c | 2 + src/providers/dp_backend.h | 1 + src/responder/common/responder_sbus.h | 3 + src/responder/ifp/ifp_private.h | 35 ++++++ src/responder/ifp/ifpsrv.c | 227 ++++++++++++++++++++++++++++++++++ src/responder/ifp/ifpsrv_cmd.c | 32 +++++ 16 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 src/man/sssd-ifp.5.xml create mode 100644 src/responder/ifp/ifp_private.h create mode 100644 src/responder/ifp/ifpsrv.c create mode 100644 src/responder/ifp/ifpsrv_cmd.c diff --git a/Makefile.am b/Makefile.am index f3196242d6691114738c58d5c2b60cffd1c0031a..620474f098b20f86e2e26c8dd35689686943f6f8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,10 @@ endif if BUILD_SSH sssdlibexec_PROGRAMS += sssd_ssh endif +if BUILD_IFP +sssdlibexec_PROGRAMS += sssd_ifp +endif + if BUILD_PAC_RESPONDER sssdlibexec_PROGRAMS += sssd_pac @@ -320,6 +324,7 @@ AM_CPPFLAGS = \ -DSSS_SUDO_SOCKET_NAME=\"$(pipepath)/sudo\" \ -DSSS_AUTOFS_SOCKET_NAME=\"$(pipepath)/autofs\" \ -DSSS_SSH_SOCKET_NAME=\"$(pipepath)/ssh\" \ + -DSSS_IFP_SOCKET_NAME=\"$(pipepath)/ifp\" \ -DLOCALEDIR=\"$(localedir)\" EXTRA_DIST = build/config.rpath @@ -457,6 +462,7 @@ dist_noinst_HEADERS = \ src/responder/sudo/sudosrv_private.h \ src/responder/autofs/autofs_private.h \ src/responder/ssh/sshsrv_private.h \ + src/responder/ifp/ifp_private.h \ src/sbus/sbus_client.h \ src/sbus/sssd_dbus.h \ src/sbus/sssd_dbus_meta.h \ @@ -797,6 +803,19 @@ sssd_pac_LDADD = \ libsss_idmap.la \ $(SSSD_INTERNAL_LTLIBS) +if BUILD_IFP +sssd_ifp_SOURCES = \ + src/responder/ifp/ifpsrv.c \ + src/responder/ifp/ifpsrv_cmd.c \ + $(SSSD_UTIL_OBJ) \ + $(SSSD_RESPONDER_OBJ) +sssd_ifp_CFLAGS = \ + $(AM_CFLAGS) +sssd_ifp_LDADD = \ + $(SSSD_LIBS) \ + $(SSSD_INTERNAL_LTLIBS) +endif + sssd_be_SOURCES = \ src/providers/data_provider_be.c \ src/providers/data_provider_fo.c \ diff --git a/configure.ac b/configure.ac index 82951396aa8990f15e468b0e919437e7d066e14d..d5313c85b872371766a8f6fd4a0381bbc4077b8b 100644 --- a/configure.ac +++ b/configure.ac @@ -125,6 +125,7 @@ WITH_SUDO WITH_SUDO_LIB_PATH WITH_AUTOFS WITH_SSH +WITH_IFP WITH_CRYPTO WITH_SYSLOG diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 055de4accd52b3fbd66e2b1914da1f3356df208f..4cf022ac6ee18a6f3e607423a25423f59c043239 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -393,6 +393,16 @@ Requires: libsss_nss_idmap = %{version}-%{release} The libsss_nss_idmap-python contains the bindings so that libsss_nss_idmap can be used by Python applications. +%package dbus +Summary: The DBus responder if the SSSD +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} + +%description dbus +Provides the DBus responder of the SSSD, called the InfoPipe, that allows +the information from the SSSD to be transmitted over the system bus. + %prep %setup -q -n %{name}-%{version} @@ -553,6 +563,7 @@ rm -rf $RPM_BUILD_ROOT %{_libexecdir}/%{servicename}/sssd_autofs %{_libexecdir}/%{servicename}/sssd_ssh %{_libexecdir}/%{servicename}/sssd_sudo +%{_libexecdir}/%{servicename}/sssd_ifp %dir %{_libdir}/%{name} %{_libdir}/%{name}/libsss_simple.so @@ -651,6 +662,12 @@ rm -rf $RPM_BUILD_ROOT %{_libexecdir}/%{servicename}/proxy_child %{_libdir}/%{name}/libsss_proxy.so +%files dbus +%defattr(-,root,root,-) +%doc COPYING +%{_libexecdir}/%{servicename}/sssd_ifp +%{_mandir}/man5/sssd-ifp.5* + %files client -f sssd_client.lang %defattr(-,root,root,-) %doc src/sss_client/COPYING src/sss_client/COPYING.LESSER diff --git a/src/conf_macros.m4 b/src/conf_macros.m4 index 71118593c81ba81804b077a0a51719b9c71574c7..1e2dbe647ecc0889ff4a3b84db5ec5c998feb3a5 100644 --- a/src/conf_macros.m4 +++ b/src/conf_macros.m4 @@ -646,3 +646,19 @@ AC_DEFUN([WITH_SSH], fi AM_CONDITIONAL([BUILD_SSH], [test x"$with_ssh" = xyes]) ]) + +AC_DEFUN([WITH_IFP], + [ AC_ARG_WITH([infopipe], + [AC_HELP_STRING([--with-infopipe], + [Whether to build with InfoPipe support [yes]] + ) + ], + [with_infopipe=$withval], + with_infopipe=yes + ) + + if test x"$with_infopipe" = xyes; then + AC_DEFINE(BUILD_IFP, 1, [whether to build with InfoPipe support]) + fi + AM_CONDITIONAL([BUILD_IFP], [test x"$with_infopipe" = xyes]) + ]) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 11a9252126089d2ac6edb4a1da92bcd545a9635c..8498adb2f11a732e22be64b2e227d98af5d05cbc 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -130,6 +130,9 @@ /* PAC */ #define CONFDB_PAC_CONF_ENTRY "config/pac" +/* InfoPipe */ +#define CONFDB_IFP_CONF_ENTRY "config/ifp" + /* Domains */ #define CONFDB_DOMAIN_PATH_TMPL "config/domain/%s" #define CONFDB_DOMAIN_BASEDN "cn=domain,cn=config" diff --git a/src/man/Makefile.am b/src/man/Makefile.am index eb879802ee6c7dbc1ad688b639b018193f677cad..58104dffc363448cf9c40765aae625e7b17b16eb 100644 --- a/src/man/Makefile.am +++ b/src/man/Makefile.am @@ -21,7 +21,10 @@ endif if BUILD_PAC_RESPONDER PAC_RESPONDER_CONDS = ;with_pac_responder endif -CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS) +if BUILD_IFP +IFP_CONDS = ;with_ifp +endif +CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS) #Special Rules: @@ -52,6 +55,10 @@ if BUILD_SUDO man_MANS += sssd-sudo.5 endif +if BUILD_IFP +man_MANS += sssd-ifp.5 +endif + SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8 .1.xml.1: $(XMLLINT) $(XMLLINT_FLAGS) $< diff --git a/src/man/include/seealso.xml b/src/man/include/seealso.xml index 4f7943113e2ff50172f652bf919713092d0b985b..992e64b76102f1b8b9a693fa92f35df1bb2048e2 100644 --- a/src/man/include/seealso.xml +++ b/src/man/include/seealso.xml @@ -74,6 +74,12 @@ <manvolnum>8</manvolnum> </citerefentry>, </phrase> + <phrase condition="with_ifp"> + <citerefentry> + <refentrytitle>sssd-ifp</refentrytitle> + <manvolnum>5</manvolnum> + </citerefentry>, + </phrase> <citerefentry> <refentrytitle>pam_sss</refentrytitle><manvolnum>8</manvolnum> </citerefentry>. diff --git a/src/man/sssd-ifp.5.xml b/src/man/sssd-ifp.5.xml new file mode 100644 index 0000000000000000000000000000000000000000..41cd3af0ac496576d03d448aae72e1609abf4ad2 --- /dev/null +++ b/src/man/sssd-ifp.5.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN" +"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> +<reference> +<title>SSSD Manual pages</title> +<refentry> + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/upstream.xml" /> + + <refmeta> + <refentrytitle>sssd-ifp</refentrytitle> + <manvolnum>5</manvolnum> + <refmiscinfo class="manual">File Formats and Conventions</refmiscinfo> + </refmeta> + + <refnamediv id='name'> + <refname>sssd-ifp</refname> + <refpurpose>SSSD InfoPipe provider</refpurpose> + </refnamediv> + + <refsect1 id='description'> + <title>DESCRIPTION</title> + <para> + This manual page describes the configuration of the InfoPipe responder + for + <citerefentry> + <refentrytitle>sssd</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>. + For a detailed syntax reference, refer to the <quote>FILE FORMAT</quote> section of the + <citerefentry> + <refentrytitle>sssd.conf</refentrytitle> + <manvolnum>5</manvolnum> + </citerefentry> manual page. + </para> + <para> + The InfoPipe responder provides a public D-Bus interface + accessible over the system bus. The interface allows the user + to query information about remote users and groups over the + system bus. + </para> + </refsect1> + + <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/seealso.xml" /> + +</refentry> +</reference> diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 4c5337606418f440f7b0e1523cfb48f8bebad431..6f63e3611ed59f5f393268c036f778c7b45a3e7b 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -153,6 +153,7 @@ <phrase condition="with_autofs">, autofs</phrase> <phrase condition="with_ssh">, ssh</phrase> <phrase condition="with_pac_responder">, pac</phrase> + <phrase condition="with_ifp">, ifp</phrase> </para> </listitem> </varlistentry> diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 9470075b511469c3691bbe4dc497282db8a0c216..dc80c8777df7233ec797b03c396d6f8162b463e2 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -889,7 +889,7 @@ done: static char *check_services(char **services) { const char *known_services[] = { "nss", "pam", "sudo", "autofs", "ssh", - "pac", NULL }; + "pac", "ifp", NULL }; int i; int ii; diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 0957bedc0e1169461324c366af2dedb82fbf4842..5c2b480db4cec8bdd0d0dfc71f01885396f822fb 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -2013,6 +2013,8 @@ static int client_registration(struct sbus_request *dbus_req, void *data) becli->bectx->ssh_cli = becli; } else if (strcasecmp(cli_name, "PAC") == 0) { becli->bectx->pac_cli = becli; + } else if (strcasecmp(cli_name, "InfoPipe") == 0) { + becli->bectx->ifp_cli = becli; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown client! [%s]\n", cli_name); } diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index ed022c2079b4ca490b86644d279703976188423e..8e3a68a5b46998c3e0bd9752a6aec28e1764ed09 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -143,6 +143,7 @@ struct be_ctx { struct be_client *autofs_cli; struct be_client *ssh_cli; struct be_client *pac_cli; + struct be_client *ifp_cli; struct loaded_be loaded_be[BET_MAX]; struct bet_info bet_info[BET_MAX]; diff --git a/src/responder/common/responder_sbus.h b/src/responder/common/responder_sbus.h index 4927d72a750cf2827710298af638513a30154b54..ca1ce512b83954ab44c1ca7b860d8ecc20b0ccd3 100644 --- a/src/responder/common/responder_sbus.h +++ b/src/responder/common/responder_sbus.h @@ -37,6 +37,9 @@ #define SSS_SSH_SBUS_SERVICE_NAME "ssh" #define SSS_SSH_SBUS_SERVICE_VERSION 0x0001 +#define SSS_IFP_SBUS_SERVICE_NAME "ifp" +#define SSS_IFP_SBUS_SERVICE_VERSION 0x0001 + #define PAC_SBUS_SERVICE_NAME "pac" #define PAC_SBUS_SERVICE_VERSION 0x0001 diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h new file mode 100644 index 0000000000000000000000000000000000000000..32c7281ea40e3e12c3e2db9b1439bec713399fea --- /dev/null +++ b/src/responder/ifp/ifp_private.h @@ -0,0 +1,35 @@ +/* + Authors: + Jakub Hrozek <jhro...@redhat.com> + Stephen Gallagher <sgall...@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: A private header + + 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 _IFPSRV_PRIVATE_H_ +#define _IFPSRV_PRIVATE_H_ + +#include "responder/common/responder.h" +#include "providers/data_provider.h" + +struct ifp_ctx { + struct resp_ctx *rctx; + struct sss_names_ctx *snctx; +}; + +#endif /* _IFPSRV_PRIVATE_H_ */ diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c new file mode 100644 index 0000000000000000000000000000000000000000..06434c328359bdbf9e9241252eee0392c3017bce --- /dev/null +++ b/src/responder/ifp/ifpsrv.c @@ -0,0 +1,227 @@ +/* + Authors: + Jakub Hrozek <jhro...@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: the responder server + + 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 <popt.h> +#include <dbus/dbus.h> + +#include "util/util.h" +#include "sbus/sssd_dbus.h" +#include "monitor/monitor_interfaces.h" +#include "confdb/confdb.h" +#include "responder/ifp/ifp_private.h" +#include "responder/common/responder_sbus.h" + +struct mon_cli_iface monitor_ifp_methods = { + { &mon_cli_iface_meta, 0 }, + .ping = monitor_common_pong, + .resInit = monitor_common_res_init, + .shutDown = NULL, + .goOffline = NULL, + .resetOffline = NULL, + .rotateLogs = responder_logrotate, +}; + +static struct data_provider_iface ifp_dp_methods = { + { &data_provider_iface_meta, 0 }, + .RegisterService = NULL, + .pamHandler = NULL, + .sudoHandler = NULL, + .autofsHandler = NULL, + .hostHandler = NULL, + .getDomains = NULL, + .getAccountInfo = NULL, +}; + +struct sss_cmd_table *get_ifp_cmds(void) +{ + static struct sss_cmd_table ifp_cmds[] = { + { SSS_GET_VERSION, sss_cmd_get_version }, + { SSS_CLI_NULL, NULL} + }; + + return ifp_cmds; +} + +static void ifp_dp_reconnect_init(struct sbus_connection *conn, + int status, void *pvt) +{ + struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); + int ret; + + /* Did we reconnect successfully? */ + if (status == SBUS_RECONNECT_SUCCESS) { + DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n"); + + /* Identify ourselves to the data provider */ + ret = dp_common_send_id(be_conn->conn, + DATA_PROVIDER_VERSION, + "InfoPipe"); + /* all fine */ + if (ret == EOK) { + handle_requests_after_reconnect(be_conn->rctx); + return; + } + } + + /* Failed to reconnect */ + DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", + be_conn->domain->name); +} + +int ifp_process_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct confdb_ctx *cdb) +{ + struct resp_ctx *rctx; + struct sss_cmd_table *ifp_cmds; + struct ifp_ctx *ifp_ctx; + struct be_conn *iter; + int ret; + int max_retries; + + ifp_cmds = get_ifp_cmds(); + ret = sss_process_init(mem_ctx, ev, cdb, + ifp_cmds, + SSS_IFP_SOCKET_NAME, NULL, + CONFDB_IFP_CONF_ENTRY, + SSS_IFP_SBUS_SERVICE_NAME, + SSS_IFP_SBUS_SERVICE_VERSION, + &monitor_ifp_methods, + "InfoPipe", + &ifp_dp_methods.vtable, + &rctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); + return ret; + } + + ifp_ctx = talloc_zero(rctx, struct ifp_ctx); + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ifp_ctx\n"); + ret = ENOMEM; + goto fail; + } + + ifp_ctx->rctx = rctx; + ifp_ctx->rctx->pvt_ctx = ifp_ctx; + + ret = sss_names_init_from_args(ifp_ctx, + "(?P<name>[^@]+)@?(?P<domain>[^@]*$)", + "%1$s@%2$s", &ifp_ctx->snctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data\n"); + goto fail; + } + + /* Enable automatic reconnection to the Data Provider */ + ret = confdb_get_int(ifp_ctx->rctx->cdb, + CONFDB_IFP_CONF_ENTRY, + CONFDB_SERVICE_RECON_RETRIES, + 3, &max_retries); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to set up automatic reconnection\n"); + goto fail; + } + + for (iter = ifp_ctx->rctx->be_conns; iter; iter = iter->next) { + sbus_reconnect_init(iter->conn, max_retries, + ifp_dp_reconnect_init, iter); + } + + ret = schedule_get_domains_task(rctx, rctx->ev, rctx); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); + goto fail; + } + + DEBUG(SSSDBG_TRACE_FUNC, "InfoPipe Initialization complete\n"); + return EOK; + +fail: + talloc_free(rctx); + return ret; +} + +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 + POPT_TABLEEND + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + 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); + + DEBUG_INIT(debug_level); + + /* set up things like debug, signals, daemonization, etc... */ + debug_log_file = "sssd_ifp"; + + ret = server_setup("sssd[ifp]", 0, CONFDB_IFP_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(SSSDBG_MINOR_FAILURE, + "Could not set up to exit when parent process does\n"); + } + + ret = ifp_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/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c new file mode 100644 index 0000000000000000000000000000000000000000..b9641ff605dc777fb3279751b08a995d148b12e5 --- /dev/null +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -0,0 +1,32 @@ +/* + Authors: + Jakub Hrozek <jhro...@redhat.com> + + Copyright (C) 2013 Red Hat + + InfoPipe responder: the responder commands + + 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 "responder/ifp/ifp_private.h" + +struct cli_protocol_version *register_cli_protocol_version(void) +{ + static struct cli_protocol_version ssh_cli_protocol_version[] = { + {0, NULL, NULL} + }; + + return ssh_cli_protocol_version; +} -- 1.8.5.3
From 316b1b752a50777e58aae805ad291d08b2f479c3 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Mon, 6 Jan 2014 15:15:40 +0100 Subject: [PATCH 2/2] IFP: Connect to the system bus Related: https://fedorahosted.org/sssd/ticket/2072 Adds the possibility for the InfoPipe responder to connect to the system bus. At the moment, only a dummy method "Ping" is provided. The method only accepts a single string parameter that has to be 'ping'. --- Makefile.am | 9 +- contrib/sssd.spec.in | 2 + src/responder/ifp/ifp_iface.xml | 10 ++ src/responder/ifp/ifp_iface_generated.c | 25 +++++ src/responder/ifp/ifp_iface_generated.h | 49 +++++++++ src/responder/ifp/ifp_private.h | 14 +++ src/responder/ifp/ifpsrv.c | 110 ++++++++++++++++++++- src/responder/ifp/ifpsrv_cmd.c | 36 +++++++ .../ifp/org.freedesktop.sssd.infopipe.conf | 22 +++++ 9 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 src/responder/ifp/ifp_iface.xml create mode 100644 src/responder/ifp/ifp_iface_generated.c create mode 100644 src/responder/ifp/ifp_iface_generated.h create mode 100644 src/responder/ifp/org.freedesktop.sssd.infopipe.conf diff --git a/Makefile.am b/Makefile.am index 620474f098b20f86e2e26c8dd35689686943f6f8..2cd6b8b40f122b1a75a521bffc2ff65db3cdbbc1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ sssdconfdir = $(sysconfdir)/sssd sssddatadir = $(datadir)/sssd sssdapiplugindir = $(sssddatadir)/sssd.api.d dbusintrospectdir = $(datarootdir)/sssd/introspect +dbuspolicydir = $(sysconfdir)/dbus-1/system.d localedir = @localedir@ nsslibdir = @nsslibdir@ pamlibdir = @pammoddir@ @@ -685,7 +686,8 @@ include_HEADERS = \ CODEGEN_XML = \ $(srcdir)/src/tests/sbus_codegen_tests.xml \ $(srcdir)/src/monitor/monitor_iface.xml \ - $(srcdir)/src/providers/data_provider_iface.xml + $(srcdir)/src/providers/data_provider_iface.xml \ + $(srcdir)/src/responder/ifp/ifp_iface.xml SBUS_CODEGEN = src/sbus/sbus_codegen @@ -807,6 +809,8 @@ if BUILD_IFP sssd_ifp_SOURCES = \ src/responder/ifp/ifpsrv.c \ src/responder/ifp/ifpsrv_cmd.c \ + src/responder/ifp/ifp_iface_generated.c \ + src/responder/ifp/ifp_iface_generated.h \ $(SSSD_UTIL_OBJ) \ $(SSSD_RESPONDER_OBJ) sssd_ifp_CFLAGS = \ @@ -814,6 +818,8 @@ sssd_ifp_CFLAGS = \ sssd_ifp_LDADD = \ $(SSSD_LIBS) \ $(SSSD_INTERNAL_LTLIBS) +dist_dbuspolicy_DATA = \ + src/responder/ifp/org.freedesktop.sssd.infopipe.conf endif sssd_be_SOURCES = \ @@ -2265,6 +2271,7 @@ installsssddirs:: $(DESTDIR)$(pluginpath) \ $(DESTDIR)$(libdir)/ldb \ $(DESTDIR)$(dbusintrospectdir) \ + $(DESTDIR)$(dbuspolicydir) \ $(DESTDIR)$(pipepath)/private \ $(DESTDIR)$(sssdlibdir) \ $(DESTDIR)$(pkglibdir) \ diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 4cf022ac6ee18a6f3e607423a25423f59c043239..ac09b003007ddc8fe4792dbd0b5791b00495a425 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -667,6 +667,8 @@ rm -rf $RPM_BUILD_ROOT %doc COPYING %{_libexecdir}/%{servicename}/sssd_ifp %{_mandir}/man5/sssd-ifp.5* +# InfoPipe DBus plumbing +%{_sysconfdir}/dbus-1/system.d/org.freedesktop.sssd.infopipe.conf %files client -f sssd_client.lang %defattr(-,root,root,-) diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml new file mode 100644 index 0000000000000000000000000000000000000000..e3221b577b88dc622b4a467f3ae78aa44c84927d --- /dev/null +++ b/src/responder/ifp/ifp_iface.xml @@ -0,0 +1,10 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.freedesktop.sssd.infopipe"> + <annotation value="infopipe_iface" name="org.freedesktop.DBus.GLib.CSymbol"/> + <method name="Ping"> + <!-- arguments parsed manually --> + </method> + </interface> +</node> diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c new file mode 100644 index 0000000000000000000000000000000000000000..db5e0e545d8d1a956ae052be52a824ed0bf5d273 --- /dev/null +++ b/src/responder/ifp/ifp_iface_generated.c @@ -0,0 +1,25 @@ +/* The following definitions are auto-generated from ifp_iface.xml */ + +#include "util/util.h" +#include "sbus/sssd_dbus.h" +#include "sbus/sssd_dbus_meta.h" +#include "ifp_iface_generated.h" + +/* methods for org.freedesktop.sssd.infopipe */ +const struct sbus_method_meta infopipe_iface__methods[] = { + { + "Ping", /* name */ + NULL, /* no in_args */ + NULL, /* no out_args */ + offsetof(struct infopipe_iface, Ping), + }, + { NULL, } +}; + +/* interface info for org.freedesktop.sssd.infopipe */ +const struct sbus_interface_meta infopipe_iface_meta = { + "org.freedesktop.sssd.infopipe", /* name */ + infopipe_iface__methods, + NULL, /* no signals */ + NULL, /* no propetries */ +}; diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h new file mode 100644 index 0000000000000000000000000000000000000000..8db83fc115d62390560e9be94ac1480ade48296f --- /dev/null +++ b/src/responder/ifp/ifp_iface_generated.h @@ -0,0 +1,49 @@ +/* The following declarations are auto-generated from ifp_iface.xml */ + +#ifndef __IFP_IFACE_XML__ +#define __IFP_IFACE_XML__ + +#include "sbus/sssd_dbus.h" + +/* ------------------------------------------------------------------------ + * DBus Constants + * + * Various constants of interface and method names mostly for use by clients + */ + +/* constants for org.freedesktop.sssd.infopipe */ +#define INFOPIPE_IFACE "org.freedesktop.sssd.infopipe" +#define INFOPIPE_IFACE_PING "Ping" + +/* ------------------------------------------------------------------------ + * DBus Vtable handler structures + * + * These structures are filled in by implementors of the different + * dbus interfaces to handle method calls. + * + * Handler functions of type sbus_msg_handler_fn accept raw messages, + * other handlers will be typed appropriately. If a handler that is + * set to NULL is invoked it will result in a + * org.freedesktop.DBus.Error.NotSupported error for the caller. + */ + +/* vtable for org.freedesktop.sssd.infopipe */ +struct infopipe_iface { + struct sbus_vtable vtable; /* derive from sbus_vtable */ + sbus_msg_handler_fn Ping; +}; + +/* ------------------------------------------------------------------------ + * DBus Interface Metadata + * + * These structure definitions are filled in with the information about + * the interfaces, methods, properties and so on. + * + * The actual definitions are found in the accompanying C file next + * to this header. + */ + +/* interface info for org.freedesktop.sssd.infopipe */ +extern const struct sbus_interface_meta infopipe_iface_meta; + +#endif /* __IFP_IFACE_XML__ */ diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h index 32c7281ea40e3e12c3e2db9b1439bec713399fea..b97cb8a7d9e55f550a3eda0e9acc034329d4ba17 100644 --- a/src/responder/ifp/ifp_private.h +++ b/src/responder/ifp/ifp_private.h @@ -26,10 +26,24 @@ #include "responder/common/responder.h" #include "providers/data_provider.h" +#include "responder/ifp/ifp_iface_generated.h" + +#define INFOPIPE_PATH "/org/freedesktop/sssd/infopipe" + +struct sysbus_ctx { + struct sbus_connection *conn; + char *introspect_xml; +}; struct ifp_ctx { struct resp_ctx *rctx; struct sss_names_ctx *snctx; + + struct sysbus_ctx *sysbus; }; +/* This is a throwaway method to ease the review of the patch. + * It will be removed later */ +int ifp_ping(struct sbus_request *dbus_req, void *data); + #endif /* _IFPSRV_PRIVATE_H_ */ diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c index 06434c328359bdbf9e9241252eee0392c3017bce..accf679efe3332aa0fb57162e288ef67eaf54adb 100644 --- a/src/responder/ifp/ifpsrv.c +++ b/src/responder/ifp/ifpsrv.c @@ -61,6 +61,11 @@ static struct data_provider_iface ifp_dp_methods = { .getAccountInfo = NULL, }; +struct infopipe_iface ifp_iface = { + { &infopipe_iface_meta, 0 }, + .Ping = ifp_ping, +}; + struct sss_cmd_table *get_ifp_cmds(void) { static struct sss_cmd_table ifp_cmds[] = { @@ -97,6 +102,95 @@ static void ifp_dp_reconnect_init(struct sbus_connection *conn, be_conn->domain->name); } +static errno_t +sysbus_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *dbus_name, + const char *dbus_path, + struct sbus_vtable *iface_vtable, + void *pvt, + struct sysbus_ctx **sysbus) +{ + DBusError dbus_error; + DBusConnection *conn = NULL; + struct sysbus_ctx *system_bus = NULL; + struct sbus_interface *sif; + errno_t ret; + + system_bus = talloc_zero(mem_ctx, struct sysbus_ctx); + if (system_bus == NULL) { + return ENOMEM; + } + + dbus_error_init(&dbus_error); + + /* Connect to the well-known system bus */ + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); + if (conn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to connect to D-BUS system bus.\n")); + ret = EIO; + goto fail; + } + dbus_connection_set_exit_on_disconnect(conn, FALSE); + + ret = dbus_bus_request_name(conn, dbus_name, + /* We want exclusive access */ + DBUS_NAME_FLAG_DO_NOT_QUEUE, + &dbus_error); + if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + /* We were unable to register on the system bus */ + DEBUG(SSSDBG_CRIT_FAILURE, + ("Unable to request name on the system bus.\n")); + ret = EIO; + goto fail; + } + + DEBUG(SSSDBG_TRACE_FUNC, "Listening on %s\n", dbus_name); + + /* Integrate with tevent loop */ + ret = sbus_init_connection(system_bus, ev, conn, + SBUS_CONN_TYPE_SHARED, + &system_bus->conn); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not integrate D-BUS into mainloop.\n"); + goto fail; + } + + sif = sbus_new_interface(system_bus->conn, + dbus_path, + iface_vtable, + pvt); + if (sif == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not add the sbus interface\n"); + goto fail; + } + + ret = sbus_conn_add_interface(system_bus->conn, sif); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not add the interface\n"); + goto fail; + } + + *sysbus = system_bus; + return EOK; + +fail: + if (dbus_error_is_set(&dbus_error)) { + DEBUG(SSSDBG_OP_FAILURE, + "DBus error message: %s\n", dbus_error.message); + dbus_error_free(&dbus_error); + } + + if (conn) dbus_connection_unref(conn); + + talloc_free(system_bus); + return ret; +} + int ifp_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) @@ -158,9 +252,23 @@ int ifp_process_init(TALLOC_CTX *mem_ctx, ifp_dp_reconnect_init, iter); } + /* Connect to the D-BUS system bus and set up methods */ + ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, + INFOPIPE_IFACE, + INFOPIPE_PATH, + &ifp_iface.vtable, + ifp_ctx, &ifp_ctx->sysbus); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to connect to the system message bus\n"); + talloc_free(ifp_ctx); + return EIO; + } + ret = schedule_get_domains_task(rctx, rctx->ev, rctx); if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); + DEBUG(SSSDBG_FATAL_FAILURE, + "schedule_get_domains_tasks failed.\n"); goto fail; } diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c index b9641ff605dc777fb3279751b08a995d148b12e5..4f73342dd8a8e5ef34a9061634e8f10c52e59964 100644 --- a/src/responder/ifp/ifpsrv_cmd.c +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -30,3 +30,39 @@ struct cli_protocol_version *register_cli_protocol_version(void) return ssh_cli_protocol_version; } + +/* This is a throwaway method to ease the review of the patch. + * It will be removed later */ +int ifp_ping(struct sbus_request *dbus_req, void *data) +{ + struct ifp_ctx *ifp_ctx = talloc_get_type(data, struct ifp_ctx); + static const char *pong = "PONG"; + const char *request; + DBusError dberr; + + if (ifp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); + } + + + if (!sbus_request_parse_or_finish(dbus_req, + DBUS_TYPE_STRING, &request, + DBUS_TYPE_INVALID)) { + return EOK; /* handled */ + } + + DEBUG(SSSDBG_CONF_SETTINGS, "Got request for [%s]\n", request); + + if (strcasecmp(request, "ping") != 0) { + dbus_error_init(&dberr); + dbus_set_error_const(&dberr, + DBUS_ERROR_INVALID_ARGS, + "Ping() only accepts ping as a param\n"); + return sbus_request_fail_and_finish(dbus_req, &dberr); + } + + return sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_STRING, &pong, + DBUS_TYPE_INVALID); +} diff --git a/src/responder/ifp/org.freedesktop.sssd.infopipe.conf b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf new file mode 100644 index 0000000000000000000000000000000000000000..fea847ceed6b3d0f999f4bd747cc7b16df2124a9 --- /dev/null +++ b/src/responder/ifp/org.freedesktop.sssd.infopipe.conf @@ -0,0 +1,22 @@ +<?xml version="1.0"?> <!--*-nxml-*--> +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <!-- This configuration file specifies the required security policies + for the SSSD InfoPipe to work. --> + + <!-- Only root can own (provide) the SSSD service --> + <policy user="root"> + <allow own="org.freedesktop.sssd.infopipe"/> + </policy> + + <!-- Allow all methods on the interface --> + <!-- Right now, this will be handled by a limited ACL + within the InfoPipe Daemon. --> + <policy context="default"> + <allow send_interface="org.freedesktop.sssd.infopipe"/> + </policy> + +</busconfig> -- 1.8.5.3
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel