From cb4d5b588e704114b7090678752d33512baa718e Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Apr 04 2014 12:05:50 +0000 Subject: 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. --- diff --git a/Makefile.am b/Makefile.am index 8b24e9e..6927325 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 b4f9221..6cc546c 100644 --- a/configure.ac +++ b/configure.ac @@ -124,6 +124,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 055de4a..8e6f535 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 D-Bus responder of the SSSD +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} + +%description dbus +Provides the D-Bus 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 87e1eef..1c31626 100644 --- a/src/conf_macros.m4 +++ b/src/conf_macros.m4 @@ -635,3 +635,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 11a9252..8498adb 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 eb87980..58104df 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 4f79431..992e64b 100644 --- a/src/man/include/seealso.xml +++ b/src/man/include/seealso.xml @@ -74,6 +74,12 @@ 8 , + + + sssd-ifp + 5 + , + pam_sss8 . diff --git a/src/man/sssd-ifp.5.xml b/src/man/sssd-ifp.5.xml new file mode 100644 index 0000000..dfac252 --- /dev/null +++ b/src/man/sssd-ifp.5.xml @@ -0,0 +1,46 @@ + + + +SSSD Manual pages + + + + + sssd-ifp + 5 + File Formats and Conventions + + + + sssd-ifp + SSSD InfoPipe responder + + + + DESCRIPTION + + This manual page describes the configuration of the InfoPipe responder + for + + sssd + 8 + . + For a detailed syntax reference, refer to the FILE FORMAT section of the + + sssd.conf + 5 + manual page. + + + 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. + + + + + + + diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 4c53376..6f63e36 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -153,6 +153,7 @@ , autofs , ssh , pac + , ifp diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 7f8ef41..845968d 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 0957bed..5c2b480 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 ed022c2..8e3a68a 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 4927d72..ca1ce51 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 0000000..32c7281 --- /dev/null +++ b/src/responder/ifp/ifp_private.h @@ -0,0 +1,35 @@ +/* + Authors: + Jakub Hrozek + Stephen Gallagher + + 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 . +*/ + +#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 0000000..06434c3 --- /dev/null +++ b/src/responder/ifp/ifpsrv.c @@ -0,0 +1,227 @@ +/* + Authors: + Jakub Hrozek + + 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 . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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[^@]+)@?(?P[^@]*$)", + "%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 0000000..b9641ff --- /dev/null +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -0,0 +1,32 @@ +/* + Authors: + Jakub Hrozek + + 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 . +*/ + +#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; +}