summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2013-10-02 14:59:35 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-04-04 14:05:50 +0200
commitcb4d5b588e704114b7090678752d33512baa718e (patch)
treeff637857b795a31fcd52e1b9ff5ddbae742d4969
parent03fb48fdaa7ed95ecb38ecc43a6d221ff2cfd950 (diff)
downloadsssd-cb4d5b588e704114b7090678752d33512baa718e.tar.gz
sssd-cb4d5b588e704114b7090678752d33512baa718e.tar.xz
sssd-cb4d5b588e704114b7090678752d33512baa718e.zip
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.
-rw-r--r--Makefile.am19
-rw-r--r--configure.ac1
-rw-r--r--contrib/sssd.spec.in17
-rw-r--r--src/conf_macros.m416
-rw-r--r--src/confdb/confdb.h3
-rw-r--r--src/man/Makefile.am9
-rw-r--r--src/man/include/seealso.xml6
-rw-r--r--src/man/sssd-ifp.5.xml46
-rw-r--r--src/man/sssd.conf.5.xml1
-rw-r--r--src/monitor/monitor.c2
-rw-r--r--src/providers/data_provider_be.c2
-rw-r--r--src/providers/dp_backend.h1
-rw-r--r--src/responder/common/responder_sbus.h3
-rw-r--r--src/responder/ifp/ifp_private.h35
-rw-r--r--src/responder/ifp/ifpsrv.c227
-rw-r--r--src/responder/ifp/ifpsrv_cmd.c32
16 files changed, 418 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 8b24e9ea0..69273256d 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 b4f9221fb..6cc546ccb 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 055de4acc..8e6f53579 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 87e1eefe1..1c3162668 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 11a925212..8498adb2f 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 eb879802e..58104dffc 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 4f7943113..992e64b76 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 000000000..dfac25298
--- /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 responder</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 4c5337606..6f63e3611 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 7f8ef412e..845968dff 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 0957bedc0..5c2b480db 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 ed022c207..8e3a68a5b 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 4927d72a7..ca1ce512b 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 000000000..32c7281ea
--- /dev/null
+++ b/src/responder/ifp/ifp_private.h
@@ -0,0 +1,35 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek@redhat.com>
+ Stephen Gallagher <sgallagh@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 000000000..06434c328
--- /dev/null
+++ b/src/responder/ifp/ifpsrv.c
@@ -0,0 +1,227 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek@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 000000000..b9641ff60
--- /dev/null
+++ b/src/responder/ifp/ifpsrv_cmd.c
@@ -0,0 +1,32 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek@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;
+}