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

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