URL: https://github.com/freeipa/freeipa/pull/2147
Author: frozencemetery
 Title: #2147: Add a skeleton kdcpolicy plugin
Action: opened

PR body:
"""
Signed-off-by: Robbie Harwood <rharw...@redhat.com>

Back in krb5-1.16 (and in RHEL-7.5), I added the [kdcpolicy 
plugin](http://web.mit.edu/kerberos/krb5-devel/doc/plugindev/kdcpolicy.html) to 
krb5.  This interface allows a module to hook all AS and TGS requests, 
potentially reject them, and manipulate ticket lifetimes.  This PR is a basic 
implementation of the interface, with all the plumbing IPA needs to get it 
loaded and installed.

There are two use cases I had in mind, though of course many more are possible 
(this is a very powerful place to have a hook into the KDC):

- Reduced ticket lifetimes based on [auth 
indicator](http://web.mit.edu/kerberos/krb5-devel/doc/admin/auth_indicator.html)
- Adding (well, subtracting) random jitter from certain principal lifetimes to 
reduce contention from groups of tickets all needing renewal simultaneously

Since presumably we don't want any of that to be hardcoded behavior, the 
difficult part is now making it all configurable.  (As well as figuring out any 
behavior we want to control at the moment).  Per IRC conversation, I'm opening 
this PR so that we have something to look at while we discuss that.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/2147/head:pr2147
git checkout pr2147
From 22553638857dd3b600cfaf97839e56534b65276a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharw...@redhat.com>
Date: Wed, 11 Jul 2018 16:48:01 -0400
Subject: [PATCH] Add a skeleton kdcpolicy plugin

Signed-off-by: Robbie Harwood <rharw...@redhat.com>
---
 configure.ac                        |  3 ++
 daemons/ipa-kdb/Makefile.am         |  8 +++
 daemons/ipa-kdb/ipa_kdb.exports     |  1 +
 daemons/ipa-kdb/ipa_kdb_kdcpolicy.c | 97 +++++++++++++++++++++++++++++++++++++
 install/share/krb5.conf.template    |  4 ++
 ipaserver/install/server/upgrade.py | 33 +++++++++++++
 server.m4                           |  5 ++
 7 files changed, 151 insertions(+)
 create mode 100644 daemons/ipa-kdb/ipa_kdb_kdcpolicy.c

diff --git a/configure.ac b/configure.ac
index b8f635f8ca..6e3d760112 100644
--- a/configure.ac
+++ b/configure.ac
@@ -228,6 +228,9 @@ AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN], [
                [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
 ])
 
+AM_CONDITIONAL([BUILD_IPA_KDCPOLICY_PLUGIN],
+               [test x$have_kdcpolicy_plugin = xyes])
+
 dnl ---------------------------------------------------------------------------
 dnl - Check for program paths
 dnl ---------------------------------------------------------------------------
diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
index d7696fc37d..04d647d0a5 100644
--- a/daemons/ipa-kdb/Makefile.am
+++ b/daemons/ipa-kdb/Makefile.am
@@ -46,6 +46,10 @@ if BUILD_IPA_CERTAUTH_PLUGIN
 ipadb_la_SOURCES += ipa_kdb_certauth.c
 endif
 
+if BUILD_IPA_KDCPOLICY_PLUGIN
+ipadb_la_SOURCES += ipa_kdb_kdcpolicy.c
+endif
+
 ipadb_la_LDFLAGS = 		\
 	-avoid-version 		\
 	-module			\
@@ -85,6 +89,10 @@ if BUILD_IPA_CERTAUTH_PLUGIN
 ipa_kdb_tests_SOURCES += ipa_kdb_certauth.c
 endif
 
+if BUILD_IPA_KDCPOLICY_PLUGIN
+ipa_kdb_tests_SOURCES += ipa_kdb_kdcpolicy.c
+endif
+
 ipa_kdb_tests_CFLAGS = $(CMOCKA_CFLAGS)
 ipa_kdb_tests_LDADD =          \
        $(CMOCKA_LIBS)          \
diff --git a/daemons/ipa-kdb/ipa_kdb.exports b/daemons/ipa-kdb/ipa_kdb.exports
index 27ce92d2ed..a581e529ff 100644
--- a/daemons/ipa-kdb/ipa_kdb.exports
+++ b/daemons/ipa-kdb/ipa_kdb.exports
@@ -4,6 +4,7 @@ EXPORTED {
 	global:
 		kdb_function_table;
 		certauth_ipakdb_initvt;
+		kdcpolicy_ipakdb_initvt;
 
 	# everything else is local
 	local:
diff --git a/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
new file mode 100644
index 0000000000..7e64487157
--- /dev/null
+++ b/daemons/ipa-kdb/ipa_kdb_kdcpolicy.c
@@ -0,0 +1,97 @@
+/* 
+ * MIT Kerberos kdcpolicy plugin for FreeIPA
+ *
+ * Authors: Robbie Harwood <rharw...@redhat.com>
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ * see file 'COPYING' for use and warranty information
+ *
+ * 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 <errno.h>
+#include <syslog.h>
+#include <krb5/kdcpolicy_plugin.h>
+
+#include "ipa_krb5.h"
+#include "ipa_kdb.h"
+
+struct krb5_kdcpolicy_moddata_st {
+    ;
+};
+
+static krb5_error_code ipa_kdcpolicy_init(krb5_context context,
+                                          krb5_kdcpolicy_moddata *data_out)
+{
+    struct krb5_kdcpolicy_moddata_st *data = calloc(1, sizeof(*data));
+    if (data == NULL) {
+        return ENOMEM;
+    }
+
+    krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy plugin loaded.");
+    *data_out = data;
+    return 0;
+}
+
+static krb5_error_code ipa_kdcpolicy_fini(krb5_context context,
+                                          krb5_kdcpolicy_moddata moddata)
+{
+    free(moddata);
+    krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy plugin unloaded.");
+    return 0;
+}
+
+static krb5_error_code
+ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
+                       const krb5_kdc_req *request,
+                       const krb5_db_entry *client,
+                       const krb5_db_entry *server,
+                       const char *const *auth_indicators,
+                       const char **status, krb5_deltat *lifetime_out,
+                       krb5_deltat *renew_lifetime_out)
+{
+    krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy: checking AS-REQ.");
+    return 0;
+}
+
+static krb5_error_code
+ipa_kdcpolicy_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
+                        const krb5_kdc_req *request,
+                        const krb5_db_entry *server,
+                        const krb5_ticket *ticket,
+                        const char *const *auth_indicators,
+                        const char **status, krb5_deltat *lifetime_out,
+                        krb5_deltat *renew_lifetime_out)
+{
+    krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy: checking TGS-REQ.");
+    return 0;
+}
+
+krb5_error_code kdcpolicy_ipakdb_initvt(krb5_context context,
+                                        int maj_ver, int min_ver,
+                                        krb5_plugin_vtable vtable)
+{
+    krb5_kdcpolicy_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+
+    vt = (krb5_kdcpolicy_vtable)vtable;
+    vt->name = "ipakdb";
+    vt->init = ipa_kdcpolicy_init;
+    vt->fini = ipa_kdcpolicy_fini;
+    vt->check_as = ipa_kdcpolicy_check_as;
+    vt->check_tgs = ipa_kdcpolicy_check_tgs;
+    return 0;
+}
diff --git a/install/share/krb5.conf.template b/install/share/krb5.conf.template
index e3420e5376..f9370a82e1 100644
--- a/install/share/krb5.conf.template
+++ b/install/share/krb5.conf.template
@@ -40,3 +40,7 @@ $OTHER_DOMAIN_REALM_MAPS
   module = ipakdb:kdb/ipadb.so
   enable_only = ipakdb
  }
+ kdcpolicy = {
+  module = ipakdb:kdb/ipadb.so
+  enable_only = ipakdb
+ }
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index 96c95b7a07..165c2ae781 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1630,6 +1630,38 @@ def enable_certauth(krb):
         aug.close()
 
 
+def enable_kdcpolicy(krb):
+    logger.info("[Enable kdcpolicy]")
+
+    aug = Augeas(flags=Augeas.NO_LOAD | Augeas.NO_MODL_AUTOLOAD,
+                 loadpath=paths.USR_SHARE_IPA_DIR)
+    try:
+        aug.transform('IPAKrb5', paths.KRB5_CONF)
+        aug.load()
+
+        path = '/files{}/plugins/kdcpolicy'.format(paths.KRB5_CONF)
+        modified = False
+
+        if not aug.match(path):
+            aug.set('{}/module'.format(path), 'ipakdb:kdb/ipadb.so')
+            aug.set('{}/enable_only'.format(path), 'ipakdb')
+            modified = True
+
+        if modified:
+            try:
+                aug.save()
+            except IOError:
+                for error_path in aug.match('/augeas//error'):
+                    logger.error('augeas: %s', aug.get(error_path))
+                raise
+
+            if krb.is_running():
+                krb.stop()
+            krb.start()
+    finally:
+        aug.close()
+
+
 def ntpd_cleanup(fqdn, fstore):
     sstore = sysrestore.StateFile(paths.SYSRESTORE)
     timeconf.restore_forced_timeservices(sstore, 'ntpd')
@@ -2050,6 +2082,7 @@ def upgrade_configuration():
     setup_spake(krb)
     setup_pkinit(krb)
     enable_certauth(krb)
+    enable_kdcpolicy(krb)
 
     if not ds_running:
         ds.stop(ds_serverid)
diff --git a/server.m4 b/server.m4
index 9666b1f120..59d867ddc7 100644
--- a/server.m4
+++ b/server.m4
@@ -53,6 +53,11 @@ AC_CHECK_HEADER([krb5/certauth_plugin.h],
                 [have_certauth_plugin=yes],
                 [have_certauth_plugin=no])
 
+dnl -- Check if we can build the kdcpolicy plugin
+AC_CHECK_HEADER([krb5/kdcpolicy_plugin.h],
+                [have_kdcpolicy_plugin=yes],
+                [have_kdcpolicy_plugin=no])
+
 dnl ---------------------------------------------------------------------------
 dnl - Check for KRB5 krad
 dnl ---------------------------------------------------------------------------
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/freeipa-devel@lists.fedorahosted.org/message/CDR3V3PJ43KO3CR2BD5LCV67ZTK74LC6/

Reply via email to