Blame SOURCES/0055-krb5_locator-always-use-port-88-for-master-KDC.patch

64f1a1
From 941a381d7a7be2af73e41bd584aca4d22675d765 Mon Sep 17 00:00:00 2001
64f1a1
From: Sumit Bose <sbose@redhat.com>
64f1a1
Date: Fri, 15 Feb 2019 16:54:19 +0100
64f1a1
Subject: [PATCH] krb5_locator: always use port 88 for master KDC
64f1a1
64f1a1
If the kpasswdinfo file exists and the found IP address includes a port
64f1a1
number as well the master KDC lookup will use this port number which is
64f1a1
most probably wrong. Better use the default port 88 always for master
64f1a1
KDC lookups.
64f1a1
64f1a1
This patch also updates the man page for the locator plugin which was
64f1a1
quite outdated.
64f1a1
64f1a1
Related to https://pagure.io/SSSD/sssd/issue/3958
64f1a1
64f1a1
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
64f1a1
(cherry picked from commit 05350abdf2ab98770ca296b9485578218644a2a7)
64f1a1
---
64f1a1
 src/krb5_plugin/sssd_krb5_locator_plugin.c    |  43 +++--
64f1a1
 src/man/sssd_krb5_locator_plugin.8.xml        |  76 +++++----
64f1a1
 .../cmocka/test_sssd_krb5_locator_plugin.c    | 156 ++++++++++++++++++
64f1a1
 3 files changed, 233 insertions(+), 42 deletions(-)
64f1a1
64f1a1
diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
64f1a1
index 952d487c2..fc5a4235d 100644
64f1a1
--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
64f1a1
+++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
64f1a1
@@ -80,6 +80,7 @@ struct sssd_ctx {
64f1a1
     struct addr_port *kpasswd_addr;
64f1a1
     bool debug;
64f1a1
     bool disabled;
64f1a1
+    bool kpasswdinfo_used;
64f1a1
 };
64f1a1
 
64f1a1
 void plugin_debug_fn(const char *format, ...)
64f1a1
@@ -411,6 +412,7 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
64f1a1
         ctx->disabled = true;
64f1a1
         PLUGIN_DEBUG(("SSSD KRB5 locator plugin is disabled.\n"));
64f1a1
     }
64f1a1
+    ctx->kpasswdinfo_used = false;
64f1a1
 
64f1a1
     *private_data = ctx;
64f1a1
 
64f1a1
@@ -451,6 +453,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
64f1a1
     struct addr_port *addr = NULL;
64f1a1
     char port_str[PORT_STR_SIZE];
64f1a1
     size_t c;
64f1a1
+    bool force_port = false;
64f1a1
 
64f1a1
     if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE;
64f1a1
     ctx = (struct sssd_ctx *) private_data;
64f1a1
@@ -478,20 +481,24 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
64f1a1
             return KRB5_PLUGIN_NO_HANDLE;
64f1a1
         }
64f1a1
 
64f1a1
-        if (svc == locate_service_kadmin || svc == locate_service_kpasswd ||
64f1a1
-            svc == locate_service_master_kdc) {
64f1a1
-            ret = get_krb5info(realm, ctx, locate_service_kpasswd);
64f1a1
+    }
64f1a1
+
64f1a1
+    if (ctx->kpasswd_addr == NULL
64f1a1
+            && (svc == locate_service_kadmin || svc == locate_service_kpasswd ||
64f1a1
+                svc == locate_service_master_kdc)) {
64f1a1
+        ret = get_krb5info(realm, ctx, locate_service_kpasswd);
64f1a1
+        if (ret != EOK) {
64f1a1
+            PLUGIN_DEBUG(("reading kpasswd address failed, "
64f1a1
+                          "using kdc address.\n"));
64f1a1
+            free_addr_port_list(&(ctx->kpasswd_addr));
64f1a1
+            ret = copy_addr_port_list(ctx->kdc_addr, true,
64f1a1
+                                      &(ctx->kpasswd_addr));
64f1a1
             if (ret != EOK) {
64f1a1
-                PLUGIN_DEBUG(("reading kpasswd address failed, "
64f1a1
-                              "using kdc address.\n"));
64f1a1
-                free_addr_port_list(&(ctx->kpasswd_addr));
64f1a1
-                ret = copy_addr_port_list(ctx->kdc_addr, true,
64f1a1
-                                          &(ctx->kpasswd_addr));
64f1a1
-                if (ret != EOK) {
64f1a1
-                    PLUGIN_DEBUG(("copying address list failed.\n"));
64f1a1
-                    return KRB5_PLUGIN_NO_HANDLE;
64f1a1
-                }
64f1a1
+                PLUGIN_DEBUG(("copying address list failed.\n"));
64f1a1
+                return KRB5_PLUGIN_NO_HANDLE;
64f1a1
             }
64f1a1
+        } else {
64f1a1
+            ctx->kpasswdinfo_used = true;
64f1a1
         }
64f1a1
     }
64f1a1
 
64f1a1
@@ -507,6 +514,12 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
64f1a1
         case locate_service_master_kdc:
64f1a1
             addr = ctx->kpasswd_addr;
64f1a1
             default_port = DEFAULT_KERBEROS_PORT;
64f1a1
+            if (ctx->kpasswdinfo_used) {
64f1a1
+                /* Use default port if the addresses from the kpasswdinfo
64f1a1
+                 * files are used because the port numbers from the file will
64f1a1
+                 * most probably not be suitable. */
64f1a1
+                force_port = true;
64f1a1
+            }
64f1a1
             break;
64f1a1
         case locate_service_kadmin:
64f1a1
             addr = ctx->kpasswd_addr;
64f1a1
@@ -539,11 +552,13 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
64f1a1
             return KRB5_PLUGIN_NO_HANDLE;
64f1a1
     }
64f1a1
 
64f1a1
-    if (strcmp(realm, ctx->sssd_realm) != 0)
64f1a1
+    if (strcmp(realm, ctx->sssd_realm) != 0 || addr == NULL) {
64f1a1
         return KRB5_PLUGIN_NO_HANDLE;
64f1a1
+    }
64f1a1
 
64f1a1
     for (c = 0; addr[c].addr != NULL; c++) {
64f1a1
-        port = (addr[c].port == 0 ? default_port : addr[c].port);
64f1a1
+        port = ((addr[c].port == 0 || force_port) ? default_port
64f1a1
+                                                  : addr[c].port);
64f1a1
         memset(port_str, 0, PORT_STR_SIZE);
64f1a1
         ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port);
64f1a1
         if (ret < 0 || ret >= (PORT_STR_SIZE-1)) {
64f1a1
diff --git a/src/man/sssd_krb5_locator_plugin.8.xml b/src/man/sssd_krb5_locator_plugin.8.xml
64f1a1
index d28546012..d77f59d6a 100644
64f1a1
--- a/src/man/sssd_krb5_locator_plugin.8.xml
64f1a1
+++ b/src/man/sssd_krb5_locator_plugin.8.xml
64f1a1
@@ -20,40 +20,60 @@
64f1a1
         <title>DESCRIPTION</title>
64f1a1
         <para>
64f1a1
             The Kerberos locator plugin
64f1a1
-            <command>sssd_krb5_locator_plugin</command> is used by the Kerberos
64f1a1
-            provider of
64f1a1
-            <citerefentry>
64f1a1
-                <refentrytitle>sssd</refentrytitle>
64f1a1
-                <manvolnum>8</manvolnum>
64f1a1
-            </citerefentry>
64f1a1
-            to tell the Kerberos libraries what Realm and which KDC to use.
64f1a1
-            Typically this is done in
64f1a1
+            <command>sssd_krb5_locator_plugin</command> is used by libkrb5 to
64f1a1
+            find KDCs for a given Kerberos realm. SSSD provides such a plugin to
64f1a1
+            guide all Kerberos clients on a system to a single KDC. In general
64f1a1
+            it should not matter to which KDC a client process is talking to.
64f1a1
+            But there are cases, e.g. after a password change, where not all
64f1a1
+            KDCs are in the same state because the new data has to be replicated
64f1a1
+            first. To avoid unexpected authentication failures and maybe even
64f1a1
+            account lockings it would be good to talk to a single KDC as long as
64f1a1
+            possible.
64f1a1
+        </para>
64f1a1
+        <para>
64f1a1
+            libkrb5 will search the locator plugin in the libkrb5 sub-directory
64f1a1
+            of the Kerberos plugin directory, see plugin_base_dir in
64f1a1
             <citerefentry>
64f1a1
                 <refentrytitle>krb5.conf</refentrytitle>
64f1a1
                 <manvolnum>5</manvolnum>
64f1a1
             </citerefentry>
64f1a1
-            which is always read by the Kerberos libraries. To simplify the
64f1a1
-            configuration the Realm and the KDC can be defined in
64f1a1
-            <citerefentry>
64f1a1
-                <refentrytitle>sssd.conf</refentrytitle>
64f1a1
-                <manvolnum>5</manvolnum>
64f1a1
-            </citerefentry>
64f1a1
-            as described in
64f1a1
-            <citerefentry>
64f1a1
-                <refentrytitle>sssd-krb5</refentrytitle>
64f1a1
-                <manvolnum>5</manvolnum>
64f1a1
-            </citerefentry>
64f1a1
+            for details. The plugin can only be disabled by removing the plugin
64f1a1
+            file. There is no option in the Kerberos configuration to disable
64f1a1
+            it. But the SSSD_KRB5_LOCATOR_DISABLE environment variable can be
64f1a1
+            used to disable the plugin for individual commands. Alternatively
64f1a1
+            the SSSD option krb5_use_kdcinfo=False can be used to not generate
64f1a1
+            the data needed by the plugin. With this the plugin is still
64f1a1
+            called but will provide no data to the caller so that libkrb5 can
64f1a1
+            fall back to other methods defined in krb5.conf.
64f1a1
         </para>
64f1a1
         <para>
64f1a1
-            <citerefentry>
64f1a1
-                <refentrytitle>sssd</refentrytitle>
64f1a1
-                <manvolnum>8</manvolnum>
64f1a1
-            </citerefentry>
64f1a1
-            puts the Realm and the name or IP address of the KDC into the
64f1a1
-            environment variables SSSD_KRB5_REALM and SSSD_KRB5_KDC respectively.
64f1a1
-            When <command>sssd_krb5_locator_plugin</command> is called by the
64f1a1
-            kerberos libraries it reads and evaluates these variables and returns
64f1a1
-            them to the libraries.
64f1a1
+            The plugin reads the information about the KDCs of a given realm
64f1a1
+            from a file called <filename>kdcinfo.REALM</filename>. The file
64f1a1
+            should contain one or more IP addresses either in dotted-decimal
64f1a1
+            IPv4 notation or the hexadecimal IPv6 notation. An optional port
64f1a1
+            number can be added to the end separated with a colon, the IPv6
64f1a1
+            address has to be enclosed in squared brackets in this case as
64f1a1
+            usual. Valid entries are:
64f1a1
+            <itemizedlist>
64f1a1
+                <listitem><para>1.2.3.4</para></listitem>
64f1a1
+                <listitem><para>5.6.7.8:99</para></listitem>
64f1a1
+                <listitem><para>2001:db8:85a3::8a2e:370:7334</para></listitem>
64f1a1
+                <listitem><para>[2001:db8:85a3::8a2e:370:7334]:321</para></listitem>
64f1a1
+            </itemizedlist>
64f1a1
+            SSSD's krb5 auth-provider which is used by the IPA and AD providers
64f1a1
+            as well adds the address of the current KDC or domain controller
64f1a1
+            SSSD is using to this file.
64f1a1
+        </para>
64f1a1
+        <para>
64f1a1
+            In environments with read-only and read-write KDCs where clients are
64f1a1
+            expected to use the read-only instances for the general operations
64f1a1
+            and only the read-write KDC for config changes like password changes
64f1a1
+            a <filename>kpasswdinfo.REALM</filename> is used as well to identify
64f1a1
+            read-write KDCs. If this file exists for the given realm the content
64f1a1
+            will be used by the plugin to reply to requests for a kpasswd or
64f1a1
+            kadmin server or for the MIT Kerberos specific master KDC. If the
64f1a1
+            address contains a port number the default KDC port 88 will be used
64f1a1
+            for the latter.
64f1a1
         </para>
64f1a1
     </refsect1>
64f1a1
 
64f1a1
diff --git a/src/tests/cmocka/test_sssd_krb5_locator_plugin.c b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
64f1a1
index 3e7d00632..1b6838345 100644
64f1a1
--- a/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
64f1a1
+++ b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
64f1a1
@@ -44,6 +44,9 @@
64f1a1
 #define TEST_IP_1_WITH_SERVICE TEST_IP_1":"TEST_SERVICE_1
64f1a1
 #define TEST_IPV6_1_WITH_SERVICE TEST_IPV6_1":"TEST_SERVICE_2
64f1a1
 
64f1a1
+#define TEST_IP_1_WITH_SERVICE_2 TEST_IP_1":"TEST_SERVICE_2
64f1a1
+#define TEST_IPV6_1_WITH_SERVICE_1 TEST_IPV6_1":"TEST_SERVICE_1
64f1a1
+
64f1a1
 struct test_state {
64f1a1
     void *dummy;
64f1a1
 };
64f1a1
@@ -61,6 +64,7 @@ static int setup(void **state)
64f1a1
     *state = (void *)ts;
64f1a1
 
64f1a1
     unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
64f1a1
+    unlink(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM);
64f1a1
     rmdir(TEST_PUBCONF_PATH);
64f1a1
 
64f1a1
     return 0;
64f1a1
@@ -574,7 +578,157 @@ void test_service(void **state)
64f1a1
 
64f1a1
     k5_free_serverlist(&list);
64f1a1
 
64f1a1
+    /* locate_service_master_kdc should get the default port 88 if kpasswdinfo
64f1a1
+     * does not exists. */
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IP_1, host);
64f1a1
+    assert_string_equal("88", service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
+
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET6, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IPV6_1_PURE, host);
64f1a1
+    assert_string_equal("88", service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
+
64f1a1
+    unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
64f1a1
+    rmdir(TEST_PUBCONF_PATH);
64f1a1
+    sssd_krb5_locator_close(priv);
64f1a1
+
64f1a1
+    krb5_free_context(ctx);
64f1a1
+}
64f1a1
+
64f1a1
+void test_kpasswd_and_master_kdc(void **state)
64f1a1
+{
64f1a1
+    krb5_context ctx;
64f1a1
+    krb5_error_code kerr;
64f1a1
+    void *priv;
64f1a1
+    int fd;
64f1a1
+    struct serverlist list = SERVERLIST_INIT;
64f1a1
+    struct module_callback_data cbdata = { 0 };
64f1a1
+    ssize_t s;
64f1a1
+    int ret;
64f1a1
+    char host[NI_MAXHOST];
64f1a1
+    char service[NI_MAXSERV];
64f1a1
+
64f1a1
+    cbdata.list = &list;
64f1a1
+
64f1a1
+    kerr = krb5_init_context (&ctx;;
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+
64f1a1
+    kerr = sssd_krb5_locator_init(ctx, &priv;;
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+
64f1a1
+    mkdir(TEST_PUBCONF_PATH, 0777);
64f1a1
+    fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT|O_RDWR, 0777);
64f1a1
+    assert_int_not_equal(fd, -1);
64f1a1
+    s = write(fd, TEST_IP_1_WITH_SERVICE, sizeof(TEST_IP_1_WITH_SERVICE));
64f1a1
+    assert_int_equal(s, sizeof(TEST_IP_1_WITH_SERVICE));
64f1a1
+    s = write(fd, "\n", 1);
64f1a1
+    assert_int_equal(s, 1);
64f1a1
+    s = write(fd, TEST_IPV6_1_WITH_SERVICE, sizeof(TEST_IPV6_1_WITH_SERVICE));
64f1a1
+    assert_int_equal(s, sizeof(TEST_IPV6_1_WITH_SERVICE));
64f1a1
+    close(fd);
64f1a1
+    fd = open(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM, O_CREAT|O_RDWR, 0777);
64f1a1
+    assert_int_not_equal(fd, -1);
64f1a1
+    s = write(fd, TEST_IP_1_WITH_SERVICE_2, sizeof(TEST_IP_1_WITH_SERVICE_2));
64f1a1
+    assert_int_equal(s, sizeof(TEST_IP_1_WITH_SERVICE_2));
64f1a1
+    s = write(fd, "\n", 1);
64f1a1
+    assert_int_equal(s, 1);
64f1a1
+    s = write(fd, TEST_IPV6_1_WITH_SERVICE_1,
64f1a1
+              sizeof(TEST_IPV6_1_WITH_SERVICE_1));
64f1a1
+    assert_int_equal(s, sizeof(TEST_IPV6_1_WITH_SERVICE_1));
64f1a1
+    close(fd);
64f1a1
+
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_kpasswd, TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IP_1, host);
64f1a1
+    assert_string_equal(TEST_SERVICE_2, service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
+
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_kpasswd , TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET6, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IPV6_1_PURE, host);
64f1a1
+    assert_string_equal(TEST_SERVICE_1, service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
+
64f1a1
+    /* locate_service_master_kdc should use the default KDC port 88 and not
64f1a1
+     * the one set in the kpasswdinfo file. */
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IP_1, host);
64f1a1
+    assert_string_equal("88", service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
 
64f1a1
+    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
64f1a1
+                                    SOCK_DGRAM, AF_INET6, module_callback,
64f1a1
+                                    &cbdata);
64f1a1
+    assert_int_equal(kerr, 0);
64f1a1
+    assert_int_equal(list.nservers, 1);
64f1a1
+    assert_non_null(list.servers);
64f1a1
+    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
64f1a1
+                      list.servers[0].addrlen,
64f1a1
+                      host, sizeof(host), service, sizeof(service),
64f1a1
+                      NI_NUMERICHOST|NI_NUMERICSERV);
64f1a1
+    assert_int_equal(ret, 0);
64f1a1
+    assert_string_equal(TEST_IPV6_1_PURE, host);
64f1a1
+    assert_string_equal("88", service);
64f1a1
+
64f1a1
+    k5_free_serverlist(&list);
64f1a1
+
64f1a1
+    unlink(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM);
64f1a1
     unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
64f1a1
     rmdir(TEST_PUBCONF_PATH);
64f1a1
     sssd_krb5_locator_close(priv);
64f1a1
@@ -606,6 +760,8 @@ int main(int argc, const char *argv[])
64f1a1
                                         setup, teardown),
64f1a1
         cmocka_unit_test_setup_teardown(test_service,
64f1a1
                                         setup, teardown),
64f1a1
+        cmocka_unit_test_setup_teardown(test_kpasswd_and_master_kdc,
64f1a1
+                                        setup, teardown),
64f1a1
     };
64f1a1
 
64f1a1
     /* Set debug level to invalid value so we can decide if -d 0 was used. */
64f1a1
-- 
64f1a1
2.19.1
64f1a1