Blame SOURCES/0022-KCM-Initial-responder-build-and-packaging.patch

bb7cd1
From 8cb263f039da9e616e907d25701593dca22b11ed Mon Sep 17 00:00:00 2001
bb7cd1
From: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
Date: Mon, 1 Aug 2016 12:52:07 +0200
bb7cd1
Subject: [PATCH 22/36] KCM: Initial responder build and packaging
bb7cd1
MIME-Version: 1.0
bb7cd1
Content-Type: text/plain; charset=UTF-8
bb7cd1
Content-Transfer-Encoding: 8bit
bb7cd1
bb7cd1
Adds the initial build of the Kerberos Cache Manager responder (KCM).
bb7cd1
bb7cd1
This is a deamon that is capable of holding and storing Kerberos
bb7cd1
ccaches. When KCM is used, the kerberos libraries (invoked through e.g.
bb7cd1
kinit) are referred to as a 'client' and the KCM deamon is referred to
bb7cd1
as 'server'.
bb7cd1
bb7cd1
At the moment, only the Heimdal implementation of Kerberos implements the
bb7cd1
KCM server:
bb7cd1
    https://www.h5l.org/manual/HEAD/info/heimdal/Credential-cache-server-_002d-KCM.html
bb7cd1
This patch adds a KCM server to SSSD.
bb7cd1
bb7cd1
In MIT, only the 'client-side' support was added:
bb7cd1
    http://k5wiki.kerberos.org/wiki/Projects/KCM_client
bb7cd1
This page also describes the protocol between the client and the server.
bb7cd1
bb7cd1
The client is capable of talking to the server over either UNIX sockets
bb7cd1
(Linux, most Unixes) or Mach RPC (macOS). Our server only implements the
bb7cd1
UNIX sockets way and should be socket-activated by systemd, although can
bb7cd1
in theory be also ran explicitly.
bb7cd1
bb7cd1
The KCM server only builds if the configuration option "--with-kcm" is
bb7cd1
enabled. It is packaged in a new subpackage sssd-kcm in order to allow
bb7cd1
distributions to enable the KCM credential caches by installing this
bb7cd1
subpackage only, without the rest of the SSSD. The sssd-kcm subpackage
bb7cd1
also includes a krb5.conf.d snippet that allows the admin to just uncomment
bb7cd1
the KCM defaults and instructs them to start the socket.
bb7cd1
bb7cd1
The server can be configured in sssd.conf in the "[kcm]" section.
bb7cd1
By default, the server only listens on the same socket path the Heimdal
bb7cd1
server uses, which is "/var/run/.heim_org.h5l.kcm-socket". This is,
bb7cd1
however, configurable.
bb7cd1
bb7cd1
The file src/responder/kcm/kcm.h is more or less directly imported from
bb7cd1
the MIT Kerberos tree, with an additional sentinel code and some
bb7cd1
comments. Not all KCM operations are implemented, only those that also
bb7cd1
the MIT client implements. That said, this KCM server should also be
bb7cd1
usable with a Heimdal client, although no special testing was with this
bb7cd1
hybrid.
bb7cd1
bb7cd1
The patch also adds several error codes that will be used in later
bb7cd1
patches.
bb7cd1
bb7cd1
Related to:
bb7cd1
    https://pagure.io/SSSD/sssd/issue/2887
bb7cd1
bb7cd1
Reviewed-by: Michal Židek <mzidek@redhat.com>
bb7cd1
Reviewed-by: Simo Sorce <simo@redhat.com>
bb7cd1
---
bb7cd1
 Makefile.am                          |  53 ++++++++
bb7cd1
 configure.ac                         |  10 +-
bb7cd1
 contrib/kcm_default_ccache           |  12 ++
bb7cd1
 contrib/sssd.spec.in                 |  41 ++++++
bb7cd1
 src/conf_macros.m4                   |  16 +++
bb7cd1
 src/confdb/confdb.h                  |   3 +
bb7cd1
 src/config/cfg_rules.ini             |  19 +++
bb7cd1
 src/external/libcurl.m4              |   6 +-
bb7cd1
 src/responder/kcm/kcm.c              | 254 +++++++++++++++++++++++++++++++++++
bb7cd1
 src/responder/kcm/kcm.h              |  97 +++++++++++++
bb7cd1
 src/responder/kcm/kcmsrv_cmd.c       |  65 +++++++++
bb7cd1
 src/responder/kcm/kcmsrv_pvt.h       |  58 ++++++++
bb7cd1
 src/sysv/systemd/sssd-kcm.service.in |   9 ++
bb7cd1
 src/sysv/systemd/sssd-kcm.socket.in  |  10 ++
bb7cd1
 src/util/util_errors.c               |   5 +
bb7cd1
 src/util/util_errors.h               |   5 +
bb7cd1
 16 files changed, 658 insertions(+), 5 deletions(-)
bb7cd1
 create mode 100644 contrib/kcm_default_ccache
bb7cd1
 create mode 100644 src/responder/kcm/kcm.c
bb7cd1
 create mode 100644 src/responder/kcm/kcm.h
bb7cd1
 create mode 100644 src/responder/kcm/kcmsrv_cmd.c
bb7cd1
 create mode 100644 src/responder/kcm/kcmsrv_pvt.h
bb7cd1
 create mode 100644 src/sysv/systemd/sssd-kcm.service.in
bb7cd1
 create mode 100644 src/sysv/systemd/sssd-kcm.socket.in
bb7cd1
bb7cd1
diff --git a/Makefile.am b/Makefile.am
bb7cd1
index 7516338bc6fd95045d20db8155a0c82fd7003358..4248536e90370c1aab59549a9c18408ef314e6d4 100644
bb7cd1
--- a/Makefile.am
bb7cd1
+++ b/Makefile.am
bb7cd1
@@ -87,6 +87,7 @@ sudolibdir = @sudolibpath@
bb7cd1
 polkitdir = @polkitdir@
bb7cd1
 pamconfdir = $(sysconfdir)/pam.d
bb7cd1
 systemtap_tapdir = @tapset_dir@
bb7cd1
+krb5sysincludedir = $(sysconfdir)/krb5.conf.d
bb7cd1
 
bb7cd1
 if HAVE_SYSTEMD_UNIT
bb7cd1
 ifp_exec_cmd = $(sssdlibexecdir)/sssd_ifp --uid 0 --gid 0 --debug-to-files --dbus-activated
bb7cd1
@@ -186,6 +187,11 @@ endif
bb7cd1
 if BUILD_SECRETS
bb7cd1
 sssdlibexec_PROGRAMS += sssd_secrets
bb7cd1
 endif
bb7cd1
+if BUILD_KCM
bb7cd1
+sssdlibexec_PROGRAMS += sssd_kcm
bb7cd1
+dist_krb5sysinclude_DATA = contrib/kcm_default_ccache
bb7cd1
+endif
bb7cd1
+
bb7cd1
 
bb7cd1
 if BUILD_PAC_RESPONDER
bb7cd1
     sssdlibexec_PROGRAMS += sssd_pac
bb7cd1
@@ -703,6 +709,8 @@ dist_noinst_HEADERS = \
bb7cd1
     src/responder/secrets/secsrv_private.h \
bb7cd1
     src/responder/secrets/secsrv_local.h \
bb7cd1
     src/responder/secrets/secsrv_proxy.h \
bb7cd1
+    src/responder/kcm/kcm.h \
bb7cd1
+    src/responder/kcm/kcmsrv_pvt.h \
bb7cd1
     src/sbus/sbus_client.h \
bb7cd1
     src/sbus/sssd_dbus.h \
bb7cd1
     src/sbus/sssd_dbus_meta.h \
bb7cd1
@@ -1476,6 +1484,24 @@ sssd_secrets_LDADD = \
bb7cd1
     $(NULL)
bb7cd1
 endif
bb7cd1
 
bb7cd1
+if BUILD_KCM
bb7cd1
+sssd_kcm_SOURCES = \
bb7cd1
+    src/responder/kcm/kcm.c \
bb7cd1
+    src/responder/kcm/kcmsrv_cmd.c \
bb7cd1
+    src/util/sss_sockets.c \
bb7cd1
+    $(SSSD_RESPONDER_OBJ) \
bb7cd1
+    $(NULL)
bb7cd1
+sssd_kcm_CFLAGS = \
bb7cd1
+    $(AM_CFLAGS) \
bb7cd1
+    $(KRB5_CFLAGS) \
bb7cd1
+    $(NULL)
bb7cd1
+sssd_kcm_LDADD = \
bb7cd1
+    $(KRB5_LIBS) \
bb7cd1
+    $(SSSD_LIBS) \
bb7cd1
+    $(SSSD_INTERNAL_LTLIBS) \
bb7cd1
+    $(NULL)
bb7cd1
+endif
bb7cd1
+
bb7cd1
 sssd_be_SOURCES = \
bb7cd1
     src/providers/data_provider_be.c \
bb7cd1
     src/providers/data_provider_req.c \
bb7cd1
@@ -4259,6 +4285,12 @@ if BUILD_SUDO
bb7cd1
         src/sysv/systemd/sssd-sudo.service \
bb7cd1
         $(NULL)
bb7cd1
 endif
bb7cd1
+if BUILD_KCM
bb7cd1
+    systemdunit_DATA += \
bb7cd1
+        src/sysv/systemd/sssd-kcm.socket \
bb7cd1
+        src/sysv/systemd/sssd-kcm.service \
bb7cd1
+        $(NULL)
bb7cd1
+endif
bb7cd1
 if WITH_JOURNALD
bb7cd1
     systemdconf_DATA += \
bb7cd1
         src/sysv/systemd/journal.conf
bb7cd1
@@ -4350,6 +4382,12 @@ EXTRA_DIST += \
bb7cd1
     src/sysv/systemd/sssd-sudo.service.in \
bb7cd1
     $(NULL)
bb7cd1
 endif
bb7cd1
+if BUILD_KCM
bb7cd1
+EXTRA_DIST += \
bb7cd1
+    src/sysv/systemd/sssd-kcm.socket.in \
bb7cd1
+    src/sysv/systemd/sssd-kcm.service.in \
bb7cd1
+    $(NULL)
bb7cd1
+endif
bb7cd1
 
bb7cd1
 src/sysv/systemd/sssd.service: src/sysv/systemd/sssd.service.in Makefile
bb7cd1
 	@$(MKDIR_P) src/sysv/systemd/
bb7cd1
@@ -4433,6 +4471,16 @@ src/sysv/systemd/sssd-sudo.service: src/sysv/systemd/sssd-sudo.service.in Makefi
bb7cd1
 	$(replace_script)
bb7cd1
 endif
bb7cd1
 
bb7cd1
+if BUILD_KCM
bb7cd1
+src/sysv/systemd/sssd-kcm.socket: src/sysv/systemd/sssd-kcm.socket.in Makefile
bb7cd1
+	@$(MKDIR_P) src/sysv/systemd/
bb7cd1
+	$(replace_script)
bb7cd1
+
bb7cd1
+src/sysv/systemd/sssd-kcm.service: src/sysv/systemd/sssd-kcm.service.in Makefile
bb7cd1
+	@$(MKDIR_P) src/sysv/systemd/
bb7cd1
+	$(replace_script)
bb7cd1
+endif
bb7cd1
+
bb7cd1
 SSSD_USER_DIRS = \
bb7cd1
     $(DESTDIR)$(dbpath) \
bb7cd1
     $(DESTDIR)$(keytabdir) \
bb7cd1
@@ -4596,6 +4644,9 @@ install-data-hook:
bb7cd1
 if BUILD_SAMBA
bb7cd1
 	mv $(DESTDIR)/$(winbindplugindir)/winbind_idmap_sss.so $(DESTDIR)/$(winbindplugindir)/sss.so
bb7cd1
 endif
bb7cd1
+if BUILD_KCM
bb7cd1
+	$(MKDIR_P) $(DESTDIR)/$(krb5sysincludedir)
bb7cd1
+endif
bb7cd1
 
bb7cd1
 uninstall-hook:
bb7cd1
 	if [ -f $(abs_builddir)/src/config/.files2 ]; then \
bb7cd1
@@ -4670,6 +4721,8 @@ endif
bb7cd1
 	rm -f $(builddir)/src/sysv/systemd/sssd-sudo.service
bb7cd1
 	rm -f $(builddir)/src/sysv/systemd/sssd-secrets.socket
bb7cd1
 	rm -f $(builddir)/src/sysv/systemd/sssd-secrets.service
bb7cd1
+	rm -f $(builddir)/src/sysv/systemd/sssd-kcm.socket
bb7cd1
+	rm -f $(builddir)/src/sysv/systemd/sssd-kcm.service
bb7cd1
 	rm -f $(builddir)/src/sysv/systemd/journal.conf
bb7cd1
 
bb7cd1
 CLEANFILES += *.X */*.X */*/*.X
bb7cd1
diff --git a/configure.ac b/configure.ac
bb7cd1
index dd1012015a5fea9f25e5b5199b4868fbc0bc14c4..c363d48a806cc1998e85779a92b6b59b0e2a5c9c 100644
bb7cd1
--- a/configure.ac
bb7cd1
+++ b/configure.ac
bb7cd1
@@ -155,6 +155,7 @@ WITH_SSSD_USER
bb7cd1
 SSSD_RUNSTATEDIR
bb7cd1
 WITH_SECRETS
bb7cd1
 WITH_SECRETS_DB_PATH
bb7cd1
+WITH_KCM
bb7cd1
 
bb7cd1
 m4_include([src/external/pkg.m4])
bb7cd1
 m4_include([src/external/libpopt.m4])
bb7cd1
@@ -193,13 +194,20 @@ m4_include([src/external/libresolv.m4])
bb7cd1
 m4_include([src/external/intgcheck.m4])
bb7cd1
 m4_include([src/external/systemtap.m4])
bb7cd1
 m4_include([src/external/service.m4])
bb7cd1
-m4_include([src/external/libcurl.m4])
bb7cd1
 
bb7cd1
 if test x$with_secrets = xyes; then
bb7cd1
     m4_include([src/external/libhttp_parser.m4])
bb7cd1
     m4_include([src/external/libjansson.m4])
bb7cd1
 fi
bb7cd1
 
bb7cd1
+if test x$with_kcm = xyes; then
bb7cd1
+    m4_include([src/external/libcurl.m4])
bb7cd1
+fi
bb7cd1
+# This variable is defined by external/libcurl.m4, but conditionals
bb7cd1
+# must be always evaluated
bb7cd1
+AM_CONDITIONAL([BUILD_WITH_LIBCURL],
bb7cd1
+               [test x"$have_curlopt_unix_sockpath" = xyes])
bb7cd1
+
bb7cd1
 WITH_UNICODE_LIB
bb7cd1
 if test x$unicode_lib = xlibunistring; then
bb7cd1
     m4_include([src/external/libunistring.m4])
bb7cd1
diff --git a/contrib/kcm_default_ccache b/contrib/kcm_default_ccache
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..ac88fca86b60b19f772912b5d9d14595a96d101d
bb7cd1
--- /dev/null
bb7cd1
+++ b/contrib/kcm_default_ccache
bb7cd1
@@ -0,0 +1,12 @@
bb7cd1
+# This file should normally be installed by your distribution into a
bb7cd1
+# directory that is included from the Kerberos configuration file (/etc/krb5.conf)
bb7cd1
+# On Fedora/RHEL/CentOS, this is /etc/krb5.conf.d/
bb7cd1
+#
bb7cd1
+# To enable the KCM credential cache, uncomment the following lines and
bb7cd1
+# enable the KCM socket and the service:
bb7cd1
+#   systemctl enable sssd-kcm.socket
bb7cd1
+#   systemctl start sssd-kcm.socket
bb7cd1
+#   systemctl enable sssd-kcm.service
bb7cd1
+
bb7cd1
+#[libdefaults]
bb7cd1
+#    default_ccache_name = KCM:
bb7cd1
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
bb7cd1
index 28ebe07a26a3112210b092b7831e7f6aae061c8d..5c7c2af521a84ef2ca6cca7b2d6cd1f9b3057056 100644
bb7cd1
--- a/contrib/sssd.spec.in
bb7cd1
+++ b/contrib/sssd.spec.in
bb7cd1
@@ -112,6 +112,13 @@
bb7cd1
     %global enable_systemtap_opt --enable-systemtap
bb7cd1
 %endif
bb7cd1
 
bb7cd1
+%if (0%{?fedora} >= 23 || 0%{?rhel} >= 7)
bb7cd1
+    %global with_kcm 1
bb7cd1
+    %global with_kcm_option --with-kcm
bb7cd1
+%else
bb7cd1
+    %global with_kcm_option --without-kcm
bb7cd1
+%endif
bb7cd1
+
bb7cd1
 Name: @PACKAGE_NAME@
bb7cd1
 Version: @PACKAGE_VERSION@
bb7cd1
 Release: 0@PRERELEASE_VERSION@%{?dist}
bb7cd1
@@ -677,6 +684,18 @@ Requires: libsss_certmap = %{version}-%{release}
bb7cd1
 %description -n libsss_certmap-devel
bb7cd1
 Library to map certificates to users based on rules
bb7cd1
 
bb7cd1
+%if (0%{?with_kcm} == 1)
bb7cd1
+%package kcm
bb7cd1
+Summary: An implementation of a Kerberos KCM server
bb7cd1
+Group:  Applications/System
bb7cd1
+License: GPLv3+
bb7cd1
+Requires: sssd-common = %{version}-%{release}
bb7cd1
+
bb7cd1
+%description kcm
bb7cd1
+An implementation of a Kerberos KCM server. Use this package if you want to
bb7cd1
+use the KCM: Kerberos credentials cache.
bb7cd1
+%endif
bb7cd1
+
bb7cd1
 %prep
bb7cd1
 %setup -q -n %{name}-%{version}
bb7cd1
 
bb7cd1
@@ -706,6 +725,7 @@ autoreconf -ivf
bb7cd1
     %{?with_python3_option} \
bb7cd1
     %{?enable_polkit_rules_option} \
bb7cd1
     %{?enable_systemtap_opt} \
bb7cd1
+    %{?with_kcm_option} \
bb7cd1
     %{?experimental}
bb7cd1
 
bb7cd1
 make %{?_smp_mflags} all
bb7cd1
@@ -1178,6 +1198,15 @@ done
bb7cd1
 %{_libdir}/libsss_certmap.so
bb7cd1
 %{_libdir}/pkgconfig/sss_certmap.pc
bb7cd1
 
bb7cd1
+%if (0%{?with_kcm} == 1)
bb7cd1
+%files kcm
bb7cd1
+%{_libexecdir}/%{servicename}/sssd_kcm
bb7cd1
+%dir %{_sysconfdir}/krb5.conf.d
bb7cd1
+%config(noreplace) %{_sysconfdir}/krb5.conf.d/kcm_default_ccache
bb7cd1
+%{_unitdir}/sssd-kcm.socket
bb7cd1
+%{_unitdir}/sssd-kcm.service
bb7cd1
+%endif
bb7cd1
+
bb7cd1
 %pre common
bb7cd1
 getent group sssd >/dev/null || groupadd -r sssd
bb7cd1
 getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd
bb7cd1
@@ -1274,6 +1303,18 @@ fi
bb7cd1
 
bb7cd1
 %postun -n libsss_simpleifp -p /sbin/ldconfig
bb7cd1
 
bb7cd1
+%if (0%{?with_kcm} == 1)
bb7cd1
+%post kcm
bb7cd1
+%systemd_post sssd-kcm.socket
bb7cd1
+
bb7cd1
+%preun kcm
bb7cd1
+%systemd_preun sssd-kcm.socket
bb7cd1
+
bb7cd1
+%postun kcm
bb7cd1
+%systemd_postun_with_restart sssd-kcm.socket
bb7cd1
+%systemd_postun_with_restart sssd-kcm.service
bb7cd1
+%endif
bb7cd1
+
bb7cd1
 %changelog
bb7cd1
 * Mon Mar 15 2010 Stephen Gallagher <sgallagh@redhat.com> - @PACKAGE_VERSION@-0@PRERELEASE_VERSION@
bb7cd1
 - Automated build of the SSSD
bb7cd1
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
bb7cd1
index 749e7694f4dd7086468e461194ef274be2094236..420997229cb3c244afd8fb21b074e43a21de0eda 100644
bb7cd1
--- a/src/conf_macros.m4
bb7cd1
+++ b/src/conf_macros.m4
bb7cd1
@@ -887,6 +887,22 @@ AC_DEFUN([WITH_SECRETS],
bb7cd1
     AM_CONDITIONAL([BUILD_SECRETS], [test x"$with_secrets" = xyes])
bb7cd1
   ])
bb7cd1
 
bb7cd1
+AC_DEFUN([WITH_KCM],
bb7cd1
+  [ AC_ARG_WITH([kcm],
bb7cd1
+                [AC_HELP_STRING([--with-kcm],
bb7cd1
+                                [Whether to build with KCM server support [yes]]
bb7cd1
+                               )
bb7cd1
+                ],
bb7cd1
+                [with_kcm=$withval],
bb7cd1
+                with_kcm=yes
bb7cd1
+               )
bb7cd1
+
bb7cd1
+    if test x"$with_kcm" = xyes; then
bb7cd1
+        AC_DEFINE(BUILD_KCM, 1, [whether to build with KCM server support])
bb7cd1
+    fi
bb7cd1
+    AM_CONDITIONAL([BUILD_KCM], [test x"$with_kcm" = xyes])
bb7cd1
+  ])
bb7cd1
+
bb7cd1
 AC_DEFUN([WITH_SECRETS_DB_PATH],
bb7cd1
   [ AC_ARG_WITH([secrets-db-path],
bb7cd1
                 [AC_HELP_STRING([--with-secrets-db-path=PATH],
bb7cd1
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
bb7cd1
index c05b1cee45ece748bf8e2b1e1ecf3dc28979e48b..c443e869a7a6782265b42c4ad122867c4e3dd8e0 100644
bb7cd1
--- a/src/confdb/confdb.h
bb7cd1
+++ b/src/confdb/confdb.h
bb7cd1
@@ -231,6 +231,9 @@
bb7cd1
 #define CONFDB_SEC_MAX_SECRETS "max_secrets"
bb7cd1
 #define CONFDB_SEC_MAX_PAYLOAD_SIZE "max_payload_size"
bb7cd1
 
bb7cd1
+/* KCM Service */
bb7cd1
+#define CONFDB_KCM_CONF_ENTRY "config/kcm"
bb7cd1
+#define CONFDB_KCM_SOCKET "socket_path"
bb7cd1
 
bb7cd1
 struct confdb_ctx;
bb7cd1
 struct config_file_ctx;
bb7cd1
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
bb7cd1
index c287328828cae2f0ad8a5a105f1c2b3e05353021..5e789c51658c51c0af1338d23d6c0f30f40bf119 100644
bb7cd1
--- a/src/config/cfg_rules.ini
bb7cd1
+++ b/src/config/cfg_rules.ini
bb7cd1
@@ -9,6 +9,7 @@ section = ssh
bb7cd1
 section = pac
bb7cd1
 section = ifp
bb7cd1
 section = secrets
bb7cd1
+section = kcm
bb7cd1
 section_re = ^secrets/users/[0-9]\+$
bb7cd1
 section_re = ^domain/.*$
bb7cd1
 
bb7cd1
@@ -262,6 +263,24 @@ option = forward_headers
bb7cd1
 option = username
bb7cd1
 option = password
bb7cd1
 
bb7cd1
+# KCM responder
bb7cd1
+[rule/allowed_kcm_options]
bb7cd1
+validator = ini_allowed_options
bb7cd1
+section_re = ^kcm$
bb7cd1
+
bb7cd1
+option = timeout
bb7cd1
+option = debug
bb7cd1
+option = debug_level
bb7cd1
+option = debug_timestamps
bb7cd1
+option = debug_microseconds
bb7cd1
+option = debug_to_files
bb7cd1
+option = command
bb7cd1
+option = reconnection_retries
bb7cd1
+option = fd_limit
bb7cd1
+option = client_idle_timeout
bb7cd1
+option = description
bb7cd1
+option = socket_path
bb7cd1
+
bb7cd1
 [rule/allowed_domain_options]
bb7cd1
 validator = ini_allowed_options
bb7cd1
 section_re = ^domain/.*$
bb7cd1
diff --git a/src/external/libcurl.m4 b/src/external/libcurl.m4
bb7cd1
index 3bc303ca4e1dea8a04117e32b8c4466b80d885b1..b420b04ad806bd1251f086b773ffe480d39f8bd3 100644
bb7cd1
--- a/src/external/libcurl.m4
bb7cd1
+++ b/src/external/libcurl.m4
bb7cd1
@@ -9,8 +9,8 @@ AS_IF([test x$enable_libcurl = xyes],
bb7cd1
       [PKG_CHECK_MODULES([CURL],
bb7cd1
                          [libcurl],
bb7cd1
                          [found_libcurl=yes],
bb7cd1
-                         [AC_MSG_WARN([
bb7cd1
-The libcurl development library was not found. Some features will be disabled.])
bb7cd1
+                         [AC_MSG_ERROR([
bb7cd1
+The libcurl development library was not found.])
bb7cd1
       ])])
bb7cd1
 
bb7cd1
 AS_IF([test x"$found_libcurl" = xyes],
bb7cd1
@@ -32,7 +32,5 @@ AS_IF([test x"$found_libcurl" = xyes],
bb7cd1
 AC_SUBST(CURL_LIBS)
bb7cd1
 AC_SUBST(CURL_CFLAGS)
bb7cd1
 
bb7cd1
-AM_CONDITIONAL([BUILD_WITH_LIBCURL],
bb7cd1
-               [test x"$have_curlopt_unix_sockpath" = xyes])
bb7cd1
 AM_COND_IF([BUILD_WITH_LIBCURL],
bb7cd1
            [AC_DEFINE_UNQUOTED(HAVE_LIBCURL, 1, [Build with libcurl support])])
bb7cd1
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..90a6999c5e39d48a1a2ea8168d171612a65077d5
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/responder/kcm/kcm.c
bb7cd1
@@ -0,0 +1,254 @@
bb7cd1
+/*
bb7cd1
+   SSSD
bb7cd1
+
bb7cd1
+   KCM Server - the mainloop and server setup
bb7cd1
+
bb7cd1
+   Copyright (C) Red Hat, 2016
bb7cd1
+
bb7cd1
+   This program is free software; you can redistribute it and/or modify
bb7cd1
+   it under the terms of the GNU General Public License as published by
bb7cd1
+   the Free Software Foundation; either version 3 of the License, or
bb7cd1
+   (at your option) any later version.
bb7cd1
+
bb7cd1
+   This program is distributed in the hope that it will be useful,
bb7cd1
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
bb7cd1
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bb7cd1
+   GNU General Public License for more details.
bb7cd1
+
bb7cd1
+   You should have received a copy of the GNU General Public License
bb7cd1
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
bb7cd1
+*/
bb7cd1
+
bb7cd1
+#include "config.h"
bb7cd1
+
bb7cd1
+#include <popt.h>
bb7cd1
+#include <krb5/krb5.h>
bb7cd1
+
bb7cd1
+#include "responder/kcm/kcm.h"
bb7cd1
+#include "responder/kcm/kcmsrv_pvt.h"
bb7cd1
+#include "responder/common/responder.h"
bb7cd1
+#include "util/util.h"
bb7cd1
+
bb7cd1
+#define DEFAULT_KCM_FD_LIMIT 2048
bb7cd1
+
bb7cd1
+#ifndef SSS_KCM_SOCKET_NAME
bb7cd1
+#define SSS_KCM_SOCKET_NAME DEFAULT_KCM_SOCKET_PATH
bb7cd1
+#endif
bb7cd1
+
bb7cd1
+static int kcm_responder_ctx_destructor(void *ptr)
bb7cd1
+{
bb7cd1
+    struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx);
bb7cd1
+
bb7cd1
+    /* mark that we are shutting down the responder, so it is propagated
bb7cd1
+     * into underlying contexts that are freed right before rctx */
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "Responder is being shut down\n");
bb7cd1
+    rctx->shutting_down = true;
bb7cd1
+
bb7cd1
+    return 0;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static int kcm_get_config(struct kcm_ctx *kctx)
bb7cd1
+{
bb7cd1
+    int ret;
bb7cd1
+    char *sock_name;
bb7cd1
+
bb7cd1
+    ret = confdb_get_int(kctx->rctx->cdb,
bb7cd1
+                         CONFDB_KCM_CONF_ENTRY,
bb7cd1
+                         CONFDB_SERVICE_FD_LIMIT,
bb7cd1
+                         DEFAULT_KCM_FD_LIMIT,
bb7cd1
+                         &kctx->fd_limit);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE,
bb7cd1
+              "Failed to get file descriptors limit\n");
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = confdb_get_int(kctx->rctx->cdb,
bb7cd1
+                         kctx->rctx->confdb_service_path,
bb7cd1
+                         CONFDB_RESPONDER_CLI_IDLE_TIMEOUT,
bb7cd1
+                         CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT,
bb7cd1
+                         &kctx->rctx->client_idle_timeout);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
+              "Cannot get the client idle timeout [%d]: %s\n",
bb7cd1
+               ret, strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    /* Ensure that the client timeout is at least ten seconds */
bb7cd1
+    if (kctx->rctx->client_idle_timeout < 10) {
bb7cd1
+        kctx->rctx->client_idle_timeout = 10;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = confdb_get_string(kctx->rctx->cdb,
bb7cd1
+                            kctx->rctx,
bb7cd1
+                            kctx->rctx->confdb_service_path,
bb7cd1
+                            CONFDB_KCM_SOCKET,
bb7cd1
+                            SSS_KCM_SOCKET_NAME,
bb7cd1
+                            &sock_name);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
+              "Cannot get the client idle timeout [%d]: %s\n",
bb7cd1
+               ret, strerror(ret));
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+    kctx->rctx->sock_name = sock_name;
bb7cd1
+
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static int kcm_data_destructor(void *ptr)
bb7cd1
+{
bb7cd1
+    struct kcm_resp_ctx *kcm_data = talloc_get_type(ptr, struct kcm_resp_ctx);
bb7cd1
+
bb7cd1
+    if (kcm_data != NULL) {
bb7cd1
+        krb5_free_context(kcm_data->k5c);
bb7cd1
+    }
bb7cd1
+    return 0;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx)
bb7cd1
+{
bb7cd1
+    struct kcm_resp_ctx *kcm_data;
bb7cd1
+    krb5_error_code kret;
bb7cd1
+
bb7cd1
+    kcm_data = talloc_zero(mem_ctx, struct kcm_resp_ctx);
bb7cd1
+    if (kcm_data == NULL) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing kcm data\n");
bb7cd1
+        return NULL;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    kret = krb5_init_context(&kcm_data->k5c);
bb7cd1
+    if (kret != EOK) {
bb7cd1
+        talloc_free(kcm_data);
bb7cd1
+        return NULL;
bb7cd1
+    }
bb7cd1
+    talloc_set_destructor((TALLOC_CTX*)kcm_data, kcm_data_destructor);
bb7cd1
+
bb7cd1
+    return kcm_data;
bb7cd1
+}
bb7cd1
+
bb7cd1
+static int kcm_process_init(TALLOC_CTX *mem_ctx,
bb7cd1
+                            struct tevent_context *ev,
bb7cd1
+                            struct confdb_ctx *cdb)
bb7cd1
+{
bb7cd1
+    struct resp_ctx *rctx;
bb7cd1
+    struct kcm_ctx *kctx;
bb7cd1
+    int ret;
bb7cd1
+
bb7cd1
+    rctx = talloc_zero(mem_ctx, struct resp_ctx);
bb7cd1
+    if (rctx == NULL) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resp_ctx\n");
bb7cd1
+        return ENOMEM;
bb7cd1
+    }
bb7cd1
+    rctx->ev = ev;
bb7cd1
+    rctx->cdb = cdb;
bb7cd1
+    rctx->confdb_service_path = CONFDB_KCM_CONF_ENTRY;
bb7cd1
+    rctx->shutting_down = false;
bb7cd1
+    rctx->lfd = -1;
bb7cd1
+    rctx->priv_lfd = -1;
bb7cd1
+
bb7cd1
+    talloc_set_destructor((TALLOC_CTX*)rctx, kcm_responder_ctx_destructor);
bb7cd1
+
bb7cd1
+    kctx = talloc_zero(rctx, struct kcm_ctx);
bb7cd1
+    if (kctx == NULL) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing kcm_ctx\n");
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto fail;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    kctx->rctx = rctx;
bb7cd1
+    kctx->rctx->pvt_ctx = kctx;
bb7cd1
+
bb7cd1
+    ret = kcm_get_config(kctx);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE, "fatal error getting KCM config\n");
bb7cd1
+        goto fail;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    kctx->kcm_data = kcm_data_setup(kctx);
bb7cd1
+    if (kctx->kcm_data == NULL) {
bb7cd1
+        DEBUG(SSSDBG_FATAL_FAILURE,
bb7cd1
+              "fatal error initializing responder data\n");
bb7cd1
+        ret = EIO;
bb7cd1
+        goto fail;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    /* Set up file descriptor limits */
bb7cd1
+    responder_set_fd_limit(kctx->fd_limit);
bb7cd1
+
bb7cd1
+    ret = activate_unix_sockets(rctx, kcm_connection_setup);
bb7cd1
+    if (ret != EOK) goto fail;
bb7cd1
+
bb7cd1
+    DEBUG(SSSDBG_TRACE_FUNC, "KCM Initialization complete\n");
bb7cd1
+
bb7cd1
+    return EOK;
bb7cd1
+
bb7cd1
+fail:
bb7cd1
+    talloc_free(rctx);
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
+int main(int argc, const char *argv[])
bb7cd1
+{
bb7cd1
+    int opt;
bb7cd1
+    poptContext pc;
bb7cd1
+    struct main_context *main_ctx;
bb7cd1
+    int ret;
bb7cd1
+    uid_t uid;
bb7cd1
+    gid_t gid;
bb7cd1
+
bb7cd1
+    struct poptOption long_options[] = {
bb7cd1
+        POPT_AUTOHELP
bb7cd1
+        SSSD_MAIN_OPTS
bb7cd1
+        SSSD_SERVER_OPTS(uid, gid)
bb7cd1
+        POPT_TABLEEND
bb7cd1
+    };
bb7cd1
+
bb7cd1
+    /* Set debug level to invalid value so we can deside if -d 0 was used. */
bb7cd1
+    debug_level = SSSDBG_INVALID;
bb7cd1
+
bb7cd1
+    umask(DFL_RSP_UMASK);
bb7cd1
+
bb7cd1
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
bb7cd1
+    while((opt = poptGetNextOpt(pc)) != -1) {
bb7cd1
+        switch(opt) {
bb7cd1
+        default:
bb7cd1
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
bb7cd1
+                  poptBadOption(pc, 0), poptStrerror(opt));
bb7cd1
+            poptPrintUsage(pc, stderr, 0);
bb7cd1
+            return 1;
bb7cd1
+        }
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    poptFreeContext(pc);
bb7cd1
+
bb7cd1
+    DEBUG_INIT(debug_level);
bb7cd1
+
bb7cd1
+    /* set up things like debug, signals, daemonization, etc... */
bb7cd1
+    debug_log_file = "sssd_kcm";
bb7cd1
+
bb7cd1
+    ret = server_setup("sssd[kcm]", 0, uid, gid, CONFDB_KCM_CONF_ENTRY,
bb7cd1
+                       &main_ctx);
bb7cd1
+    if (ret != EOK) return 2;
bb7cd1
+
bb7cd1
+    ret = die_if_parent_died();
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        /* This is not fatal, don't return */
bb7cd1
+        DEBUG(SSSDBG_OP_FAILURE,
bb7cd1
+              "Could not set up to exit when parent process does\n");
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = kcm_process_init(main_ctx,
bb7cd1
+                           main_ctx->event_ctx,
bb7cd1
+                           main_ctx->confdb_ctx);
bb7cd1
+    if (ret != EOK) return 3;
bb7cd1
+
bb7cd1
+    /* loop on main */
bb7cd1
+    server_loop(main_ctx);
bb7cd1
+
bb7cd1
+    return 0;
bb7cd1
+}
bb7cd1
diff --git a/src/responder/kcm/kcm.h b/src/responder/kcm/kcm.h
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..1ea7e9bbca754dca2eeb72a08830fa2f95713b4f
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/responder/kcm/kcm.h
bb7cd1
@@ -0,0 +1,97 @@
bb7cd1
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
bb7cd1
+/* include/kcm.h - Kerberos cache manager protocol declarations */
bb7cd1
+/*
bb7cd1
+ * Copyright (C) 2014 by the Massachusetts Institute of Technology.
bb7cd1
+ * All rights reserved.
bb7cd1
+ *
bb7cd1
+ * Redistribution and use in source and binary forms, with or without
bb7cd1
+ * modification, are permitted provided that the following conditions
bb7cd1
+ * are met:
bb7cd1
+ *
bb7cd1
+ * * Redistributions of source code must retain the above copyright
bb7cd1
+ *   notice, this list of conditions and the following disclaimer.
bb7cd1
+ *
bb7cd1
+ * * Redistributions in binary form must reproduce the above copyright
bb7cd1
+ *   notice, this list of conditions and the following disclaimer in
bb7cd1
+ *   the documentation and/or other materials provided with the
bb7cd1
+ *   distribution.
bb7cd1
+ *
bb7cd1
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
bb7cd1
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
bb7cd1
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
bb7cd1
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
bb7cd1
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
bb7cd1
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
bb7cd1
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
bb7cd1
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
bb7cd1
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
bb7cd1
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
bb7cd1
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
bb7cd1
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
bb7cd1
+ */
bb7cd1
+
bb7cd1
+#ifndef KCM_H
bb7cd1
+#define KCM_H
bb7cd1
+
bb7cd1
+#define KCM_PROTOCOL_VERSION_MAJOR 2
bb7cd1
+#define KCM_PROTOCOL_VERSION_MINOR 0
bb7cd1
+
bb7cd1
+#define KCM_UUID_LEN 16
bb7cd1
+
bb7cd1
+/* This should ideally be in RUNSTATEDIR, but Heimdal uses a hardcoded
bb7cd1
+ * /var/run, and we need to use the same default path. */
bb7cd1
+#define DEFAULT_KCM_SOCKET_PATH "/var/run/.heim_org.h5l.kcm-socket"
bb7cd1
+#define DEFAULT_KCM_MACH_SERVICE "org.h5l.kcm"
bb7cd1
+
bb7cd1
+/*
bb7cd1
+ * All requests begin with:
bb7cd1
+ *   major version (1 bytes)
bb7cd1
+ *   minor version (1 bytes)
bb7cd1
+ *   opcode (16-bit big-endian)
bb7cd1
+ *
bb7cd1
+ * All replies begin with a 32-bit big-endian reply code.
bb7cd1
+ *
bb7cd1
+ * Parameters are appended to the request or reply with no delimiters.  Flags
bb7cd1
+ * and time offsets are stored as 32-bit big-endian integers.  Names are
bb7cd1
+ * marshalled as zero-terminated strings.  Principals and credentials are
bb7cd1
+ * marshalled in the v4 FILE ccache format.  UUIDs are 16 bytes.  UUID lists
bb7cd1
+ * are not delimited, so nothing can come after them.
bb7cd1
+ */
bb7cd1
+
bb7cd1
+/* Opcodes without comments are currently unused in the MIT client
bb7cd1
+ * implementation. */
bb7cd1
+typedef enum kcm_opcode {
bb7cd1
+    KCM_OP_NOOP,
bb7cd1
+    KCM_OP_GET_NAME,
bb7cd1
+    KCM_OP_RESOLVE,
bb7cd1
+    KCM_OP_GEN_NEW,             /* 0x3                 () -> (name)      */
bb7cd1
+    KCM_OP_INITIALIZE,          /* 0x4      (name, princ) -> ()          */
bb7cd1
+    KCM_OP_DESTROY,             /* 0x4             (name) -> ()          */
bb7cd1
+    KCM_OP_STORE,               /* 0x6       (name, cred) -> ()          */
bb7cd1
+    KCM_OP_RETRIEVE,
bb7cd1
+    KCM_OP_GET_PRINCIPAL,       /* 0x8             (name) -> (princ)     */
bb7cd1
+    KCM_OP_GET_CRED_UUID_LIST,  /* 0x9             (name) -> (uuid, ...) */
bb7cd1
+    KCM_OP_GET_CRED_BY_UUID,    /* 0xa       (name, uuid) -> (cred)      */
bb7cd1
+    KCM_OP_REMOVE_CRED,         /* (name, flags, credtag) -> ()          */
bb7cd1
+    KCM_OP_SET_FLAGS,
bb7cd1
+    KCM_OP_CHOWN,
bb7cd1
+    KCM_OP_CHMOD,
bb7cd1
+    KCM_OP_GET_INITIAL_TICKET,
bb7cd1
+    KCM_OP_GET_TICKET,
bb7cd1
+    KCM_OP_MOVE_CACHE,
bb7cd1
+    KCM_OP_GET_CACHE_UUID_LIST, /* 0x12                () -> (uuid, ...) */
bb7cd1
+    KCM_OP_GET_CACHE_BY_UUID,   /* 0x13            (uuid) -> (name)      */
bb7cd1
+    KCM_OP_GET_DEFAULT_CACHE,   /* 0x14                () -> (name)      */
bb7cd1
+    KCM_OP_SET_DEFAULT_CACHE,   /* 0x15            (name) -> ()          */
bb7cd1
+    KCM_OP_GET_KDC_OFFSET,      /* 0x16            (name) -> (offset)    */
bb7cd1
+    KCM_OP_SET_KDC_OFFSET,      /* 0x17    (name, offset) -> ()          */
bb7cd1
+    KCM_OP_ADD_NTLM_CRED,
bb7cd1
+    KCM_OP_HAVE_NTLM_CRED,
bb7cd1
+    KCM_OP_DEL_NTLM_CRED,
bb7cd1
+    KCM_OP_DO_NTLM_AUTH,
bb7cd1
+    KCM_OP_GET_NTLM_USER_LIST,
bb7cd1
+
bb7cd1
+    KCM_OP_SENTINEL,            /* SSSD addition, not in the MIT header */
bb7cd1
+} kcm_opcode;
bb7cd1
+
bb7cd1
+#endif /* KCM_H */
bb7cd1
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..e9a03cbd41169c93e00b0630dc1e05e205881ec9
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/responder/kcm/kcmsrv_cmd.c
bb7cd1
@@ -0,0 +1,65 @@
bb7cd1
+/*
bb7cd1
+   SSSD
bb7cd1
+
bb7cd1
+   KCM Server - the KCM server request and reply parsing and dispatching
bb7cd1
+
bb7cd1
+   Copyright (C) Red Hat, 2016
bb7cd1
+
bb7cd1
+   This program is free software; you can redistribute it and/or modify
bb7cd1
+   it under the terms of the GNU General Public License as published by
bb7cd1
+   the Free Software Foundation; either version 3 of the License, or
bb7cd1
+   (at your option) any later version.
bb7cd1
+
bb7cd1
+   This program is distributed in the hope that it will be useful,
bb7cd1
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
bb7cd1
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bb7cd1
+   GNU General Public License for more details.
bb7cd1
+
bb7cd1
+   You should have received a copy of the GNU General Public License
bb7cd1
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
bb7cd1
+*/
bb7cd1
+
bb7cd1
+#include "config.h"
bb7cd1
+#include "util/util.h"
bb7cd1
+#include "responder/common/responder.h"
bb7cd1
+
bb7cd1
+struct kcm_proto_ctx {
bb7cd1
+    void *unused;
bb7cd1
+};
bb7cd1
+
bb7cd1
+static void kcm_fd_handler(struct tevent_context *ev,
bb7cd1
+                           struct tevent_fd *fde,
bb7cd1
+                           uint16_t flags, void *ptr)
bb7cd1
+{
bb7cd1
+    errno_t ret;
bb7cd1
+    struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx);
bb7cd1
+
bb7cd1
+    /* Always reset the idle timer on any activity */
bb7cd1
+    ret = reset_client_idle_timer(cctx);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        DEBUG(SSSDBG_CRIT_FAILURE,
bb7cd1
+              "Could not create idle timer for client. "
bb7cd1
+               "This connection may not auto-terminate\n");
bb7cd1
+        /* Non-fatal, continue */
bb7cd1
+    }
bb7cd1
+}
bb7cd1
+
bb7cd1
+int kcm_connection_setup(struct cli_ctx *cctx)
bb7cd1
+{
bb7cd1
+    struct kcm_proto_ctx *protocol_ctx;
bb7cd1
+
bb7cd1
+    protocol_ctx = talloc_zero(cctx, struct kcm_proto_ctx);
bb7cd1
+    if (protocol_ctx == NULL) {
bb7cd1
+        return ENOMEM;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    cctx->protocol_ctx = protocol_ctx;
bb7cd1
+    cctx->cfd_handler = kcm_fd_handler;
bb7cd1
+    return EOK;
bb7cd1
+}
bb7cd1
+
bb7cd1
+/* Dummy, not used here but required to link to other responder files */
bb7cd1
+struct cli_protocol_version *register_cli_protocol_version(void)
bb7cd1
+{
bb7cd1
+    return NULL;
bb7cd1
+}
bb7cd1
diff --git a/src/responder/kcm/kcmsrv_pvt.h b/src/responder/kcm/kcmsrv_pvt.h
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..a7c9d062c17f09986d894064176c3a461d396ac0
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/responder/kcm/kcmsrv_pvt.h
bb7cd1
@@ -0,0 +1,58 @@
bb7cd1
+/*
bb7cd1
+   SSSD
bb7cd1
+
bb7cd1
+   KCM Server - private header file
bb7cd1
+
bb7cd1
+   Copyright (C) Red Hat, 2016
bb7cd1
+
bb7cd1
+   This program is free software; you can redistribute it and/or modify
bb7cd1
+   it under the terms of the GNU General Public License as published by
bb7cd1
+   the Free Software Foundation; either version 3 of the License, or
bb7cd1
+   (at your option) any later version.
bb7cd1
+
bb7cd1
+   This program is distributed in the hope that it will be useful,
bb7cd1
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
bb7cd1
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
bb7cd1
+   GNU General Public License for more details.
bb7cd1
+
bb7cd1
+   You should have received a copy of the GNU General Public License
bb7cd1
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
bb7cd1
+*/
bb7cd1
+
bb7cd1
+#ifndef __KCMSRV_PVT_H__
bb7cd1
+#define __KCMSRV_PVT_H__
bb7cd1
+
bb7cd1
+#include "config.h"
bb7cd1
+
bb7cd1
+#include <sys/types.h>
bb7cd1
+#include "responder/common/responder.h"
bb7cd1
+
bb7cd1
+/* KCM IO structure */
bb7cd1
+struct kcm_data {
bb7cd1
+    uint8_t *data;
bb7cd1
+    size_t length;
bb7cd1
+};
bb7cd1
+
bb7cd1
+/* To avoid leaking the sssd-specific responder data to other
bb7cd1
+ * modules, the ccache databases and other KCM specific data
bb7cd1
+ * are kept separately
bb7cd1
+ */
bb7cd1
+struct kcm_resp_ctx {
bb7cd1
+    krb5_context k5c;
bb7cd1
+};
bb7cd1
+
bb7cd1
+/* responder context that contains both the responder data,
bb7cd1
+ * like the ccaches and the sssd-specific stuff like the
bb7cd1
+ * generic responder ctx
bb7cd1
+ */
bb7cd1
+struct kcm_ctx {
bb7cd1
+    struct resp_ctx *rctx;
bb7cd1
+    int fd_limit;
bb7cd1
+    char *socket_path;
bb7cd1
+
bb7cd1
+    struct kcm_resp_ctx *kcm_data;
bb7cd1
+};
bb7cd1
+
bb7cd1
+int kcm_connection_setup(struct cli_ctx *cctx);
bb7cd1
+
bb7cd1
+#endif /* __KCMSRV_PVT_H__ */
bb7cd1
diff --git a/src/sysv/systemd/sssd-kcm.service.in b/src/sysv/systemd/sssd-kcm.service.in
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..1e2bee12dc3bedd17d41b86f91c9b2b52d985c40
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/sysv/systemd/sssd-kcm.service.in
bb7cd1
@@ -0,0 +1,9 @@
bb7cd1
+[Unit]
bb7cd1
+Description=SSSD Kerberos Cache Manager
bb7cd1
+Documentation=man:sssd-kcm(5)
bb7cd1
+
bb7cd1
+[Install]
bb7cd1
+Also=sssd-kcm.socket
bb7cd1
+
bb7cd1
+[Service]
bb7cd1
+ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 --debug-to-files
bb7cd1
diff --git a/src/sysv/systemd/sssd-kcm.socket.in b/src/sysv/systemd/sssd-kcm.socket.in
bb7cd1
new file mode 100644
bb7cd1
index 0000000000000000000000000000000000000000..80ec1c0c8f190e83de0b603df8e90aa49d2ec181
bb7cd1
--- /dev/null
bb7cd1
+++ b/src/sysv/systemd/sssd-kcm.socket.in
bb7cd1
@@ -0,0 +1,10 @@
bb7cd1
+[Unit]
bb7cd1
+Description=SSSD Secrets Service responder socket
bb7cd1
+Documentation=man:sssd-kcm(8)
bb7cd1
+Requires=sssd-secrets.socket
bb7cd1
+
bb7cd1
+[Socket]
bb7cd1
+ListenStream=@localstatedir@/run/.heim_org.h5l.kcm-socket
bb7cd1
+
bb7cd1
+[Install]
bb7cd1
+WantedBy=sockets.target
bb7cd1
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
bb7cd1
index 17388c997db5315c2491af1021e75aff07632488..23cfdf9c6116a2c8e569a041e8289b65a112fd08 100644
bb7cd1
--- a/src/util/util_errors.c
bb7cd1
+++ b/src/util/util_errors.c
bb7cd1
@@ -40,6 +40,7 @@ struct err_string error_to_str[] = {
bb7cd1
     { "Credentials are expired, old ccache was removed" }, /* ERR_CREDS_EXPIRED_CCACHE */
bb7cd1
     { "Failure setting user credentials"}, /* ERR_CREDS_INVALID */
bb7cd1
     { "No cached credentials available" }, /* ERR_NO_CACHED_CREDS */
bb7cd1
+    { "No matching credentials found" }, /* ERR_NO_MATCHING_CREDS */
bb7cd1
     { "Cached credentials are expired" }, /* ERR_CACHED_CREDS_EXPIRED */
bb7cd1
     { "Authentication Denied" }, /* ERR_AUTH_DENIED */
bb7cd1
     { "Authentication Failed" }, /* ERR_AUTH_FAILED */
bb7cd1
@@ -104,6 +105,10 @@ struct err_string error_to_str[] = {
bb7cd1
     { "The secret payload size is too large" }, /* ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE */
bb7cd1
     { "No authentication methode available" }, /* ERR_NO_AUTH_METHOD_AVAILABLE */
bb7cd1
     { "Smartcard authentication not supported" }, /* ERR_SC_AUTH_NOT_SUPPORTED */
bb7cd1
+    { "Malformed input KCM packet" }, /* ERR_KCM_MALFORMED_IN_PKT */
bb7cd1
+    { "KCM operation not implemented" }, /* ERR_KCM_OP_NOT_IMPLEMENTED */
bb7cd1
+    { "End of credential cache reached" }, /* ERR_KCM_CC_END */
bb7cd1
+    { "Credential cache name not allowed" }, /* ERR_KCM_WRONG_CCNAME_FORMAT */
bb7cd1
     { "ERR_LAST" } /* ERR_LAST */
bb7cd1
 };
bb7cd1
 
bb7cd1
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
bb7cd1
index 7aacad26084a3a2af6333988f07db865f6a4d299..387d481616db1ed5e22b73fae82632a582fae946 100644
bb7cd1
--- a/src/util/util_errors.h
bb7cd1
+++ b/src/util/util_errors.h
bb7cd1
@@ -62,6 +62,7 @@ enum sssd_errors {
bb7cd1
     ERR_CREDS_EXPIRED_CCACHE,
bb7cd1
     ERR_CREDS_INVALID,
bb7cd1
     ERR_NO_CACHED_CREDS,
bb7cd1
+    ERR_NO_MATCHING_CREDS,
bb7cd1
     ERR_CACHED_CREDS_EXPIRED,
bb7cd1
     ERR_AUTH_DENIED,
bb7cd1
     ERR_AUTH_FAILED,
bb7cd1
@@ -126,6 +127,10 @@ enum sssd_errors {
bb7cd1
     ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE,
bb7cd1
     ERR_NO_AUTH_METHOD_AVAILABLE,
bb7cd1
     ERR_SC_AUTH_NOT_SUPPORTED,
bb7cd1
+    ERR_KCM_MALFORMED_IN_PKT,
bb7cd1
+    ERR_KCM_OP_NOT_IMPLEMENTED,
bb7cd1
+    ERR_KCM_CC_END,
bb7cd1
+    ERR_KCM_WRONG_CCNAME_FORMAT,
bb7cd1
     ERR_LAST            /* ALWAYS LAST */
bb7cd1
 };
bb7cd1
 
bb7cd1
-- 
bb7cd1
2.9.3
bb7cd1