Blame SOURCES/0001-Kerberos-add-default_domain-and-udp_preference_limit.patch

cd9052
From 2fa90caf4ad38541615446b80dbeaccd0d0e6a6f Mon Sep 17 00:00:00 2001
cd9052
From: Sumit Bose <sbose@redhat.com>
cd9052
Date: Wed, 28 Oct 2020 13:40:03 +0100
cd9052
Subject: [PATCH] Kerberos: add default_domain and udp_preference_limit
cd9052
cd9052
When joining an Active Directory domain realmd will set the
cd9052
default_domain and udp_preference_limit in the Kerberos configuration to
cd9052
avoid errors and make Kerberos handling in the AD domain more easy.
cd9052
cd9052
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791016
cd9052
---
cd9052
 doc/manual/realmd.conf.xml      |  69 +++++++++++++++++++
cd9052
 service/Makefile.am             |   2 +
cd9052
 service/realm-kerberos-config.c | 116 ++++++++++++++++++++++++++++++++
cd9052
 service/realm-kerberos-config.h |  35 ++++++++++
cd9052
 service/realm-samba.c           |  12 ++++
cd9052
 service/realm-sssd-ad.c         |  12 ++++
cd9052
 service/realmd-debian.conf      |   1 +
cd9052
 service/realmd-defaults.conf    |   1 +
cd9052
 service/realmd-redhat.conf      |   1 +
cd9052
 service/realmd-suse.conf        |   1 +
cd9052
 10 files changed, 250 insertions(+)
cd9052
 create mode 100644 service/realm-kerberos-config.c
cd9052
 create mode 100644 service/realm-kerberos-config.h
cd9052
cd9052
diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml
cd9052
index 9062252..97d2e8d 100644
cd9052
--- a/doc/manual/realmd.conf.xml
cd9052
+++ b/doc/manual/realmd.conf.xml
cd9052
@@ -304,6 +304,75 @@ DOMAIN\user:*:13445:13446:Name:/home/DOMAIN/user:/bin/bash
cd9052
 
cd9052
 </refsect1>
cd9052
 
cd9052
+<refsect1 id="realmd-conf-paths">
cd9052
+	<title>paths</title>
cd9052
+
cd9052
+	<para>These options should go in an <option>[paths]</option>
cd9052
+	section of the <filename>/etc/realmd.conf</filename> file. Only
cd9052
+	specify the settings you wish to override.</para>
cd9052
+
cd9052
+	<variablelist>
cd9052
+	<varlistentry>
cd9052
+	<term><option>krb5.conf</option></term>
cd9052
+	<listitem>
cd9052
+		<para>Path to the Kerberos configuration file, typically
cd9052
+		<filename>/etc/krb5.conf</filename>. It can also be the path of
cd9052
+		a file included by <filename>/etc/krb5.conf</filename>, e.g.
cd9052
+		<filename>/etc/krb5.conf.d/realmd_settings</filename>, if the
cd9052
+		file does not exist if will be created.</para>
cd9052
+
cd9052
+		<informalexample>
cd9052
+<programlisting language="js">
cd9052
+[paths]
cd9052
+krb5.conf = /etc/krb5.conf.d/realmd_settings
cd9052
+
cd9052
+</programlisting>
cd9052
+		</informalexample>
cd9052
+
cd9052
+		<para>When joining an Active Directory domain
cd9052
+		<command>realmd</command> will set the
cd9052
+		<option>default_realm</option> and
cd9052
+		<option>udp_preference_limit</option> options in the Kerberos
cd9052
+		configuration:</para>
cd9052
+
cd9052
+		<informalexample>
cd9052
+<programlisting language="js">
cd9052
+default_realm = DOMAIN.EXAMPLE.COM
cd9052
+udp_preference_limit = 0
cd9052
+
cd9052
+</programlisting>
cd9052
+		</informalexample>
cd9052
+
cd9052
+		<para>The <option>default_realm</option> option is e.g. needed
cd9052
+		when trying to resolve enterprise principals and makes it more
cd9052
+		convenient to request Kerberos tickets for users of the default
cd9052
+		realm. Instead of specifying the whole principal just
cd9052
+		<command>kinit username</command> can be used.</para>
cd9052
+
cd9052
+		<para>With <option>udp_preference_limit = 0</option> always TCP
cd9052
+		will be used to send Kerberos request to domain controller. This
cd9052
+		is useful in Active Directory environments because Kerberos will
cd9052
+		typically switch to TCP after initially starting with UDP
cd9052
+		because AD Kerberos tickets are often larger than UDP can handle.
cd9052
+		Using TCP by default will avoid those extra UDP round trips.
cd9052
+		Additionally it helps to avoid issues with password changes when
cd9052
+		the DC does not reply soon enough and the client will send a
cd9052
+		second UDP request. The DC might reply with a reply error to the
cd9052
+		second request although the original password change request was
cd9052
+		successful and the client will no know if the request was
cd9052
+		successful or not. When using TCP this cannot happen because the
cd9052
+		client will never send a second request but waits on the
cd9052
+		connection until the server replies.</para>
cd9052
+
cd9052
+		<para>Please note that <command>realmd</command> will not remove
cd9052
+		those options while leaving the domain since they are useful in
cd9052
+		general. When joining a new domain <command>realmd</command>
cd9052
+		will of course overwrite <option>default_realm</option>.</para>
cd9052
+	</listitem>
cd9052
+	</varlistentry>
cd9052
+	</variablelist>
cd9052
+</refsect1>
cd9052
+
cd9052
 <refsect1 id="realmd-conf-specific-settings">
cd9052
 	<title>Realm specific settings</title>
cd9052
 	<para>These options should go in an section with the same name
cd9052
diff --git a/service/Makefile.am b/service/Makefile.am
cd9052
index 88ee780..031cd1d 100644
cd9052
--- a/service/Makefile.am
cd9052
+++ b/service/Makefile.am
cd9052
@@ -57,6 +57,8 @@ realmd_SOURCES = \
cd9052
 	service/realm-invocation.h \
cd9052
 	service/realm-kerberos.c \
cd9052
 	service/realm-kerberos.h \
cd9052
+	service/realm-kerberos-config.c \
cd9052
+	service/realm-kerberos-config.h \
cd9052
 	service/realm-kerberos-membership.c \
cd9052
 	service/realm-kerberos-membership.h \
cd9052
 	service/realm-kerberos-provider.c \
cd9052
diff --git a/service/realm-kerberos-config.c b/service/realm-kerberos-config.c
cd9052
new file mode 100644
cd9052
index 0000000..447a452
cd9052
--- /dev/null
cd9052
+++ b/service/realm-kerberos-config.c
cd9052
@@ -0,0 +1,116 @@
cd9052
+/* realmd -- Realm configuration service
cd9052
+ *
cd9052
+ * Copyright 2020 Red Hat Inc
cd9052
+ *
cd9052
+ * This program is free software: you can redistribute it and/or modify
cd9052
+ * it under the terms of the GNU Lesser General Public License as published
cd9052
+ * by the Free Software Foundation; either version 2 of the licence or (at
cd9052
+ * your option) any later version.
cd9052
+ *
cd9052
+ * See the included COPYING file for more information.
cd9052
+ *
cd9052
+ * Author: Sumit Bose <sbose@redhat.com>
cd9052
+ */
cd9052
+
cd9052
+#include "config.h"
cd9052
+
cd9052
+#include "realm-ini-config.h"
cd9052
+#include "realm-kerberos-config.h"
cd9052
+#include "realm-settings.h"
cd9052
+
cd9052
+#include <string.h>
cd9052
+
cd9052
+RealmIniConfig *
cd9052
+realm_kerberos_config_new_with_flags (RealmIniFlags flags,
cd9052
+                                      GError **error)
cd9052
+{
cd9052
+	RealmIniConfig *config;
cd9052
+	const gchar *filename;
cd9052
+	GError *err = NULL;
cd9052
+
cd9052
+	config = realm_ini_config_new (REALM_INI_LINE_CONTINUATIONS | flags);
cd9052
+
cd9052
+	filename = realm_settings_path ("krb5.conf");
cd9052
+
cd9052
+	realm_ini_config_read_file (config, filename, &err;;
cd9052
+
cd9052
+	if (err != NULL) {
cd9052
+		/* If the caller wants errors, then don't return an invalid samba config */
cd9052
+		if (error) {
cd9052
+			g_propagate_error (error, err);
cd9052
+			g_object_unref (config);
cd9052
+			config = NULL;
cd9052
+
cd9052
+		/* If the caller doesn't care, then warn but continue */
cd9052
+		} else {
cd9052
+			g_warning ("Couldn't load config file: %s: %s", filename,
cd9052
+			           err->message);
cd9052
+			g_error_free (err);
cd9052
+		}
cd9052
+	}
cd9052
+
cd9052
+	return config;
cd9052
+}
cd9052
+
cd9052
+RealmIniConfig *
cd9052
+realm_kerberos_config_new (GError **error)
cd9052
+{
cd9052
+	return realm_kerberos_config_new_with_flags (REALM_INI_NONE, error);
cd9052
+}
cd9052
+
cd9052
+gboolean
cd9052
+configure_krb5_conf_for_domain (const gchar *realm, GError **error )
cd9052
+{
cd9052
+	RealmIniConfig *config;
cd9052
+	gboolean res;
cd9052
+	GFile *gfile;
cd9052
+	GFileInfo *file_info = NULL;
cd9052
+
cd9052
+	config = realm_kerberos_config_new (error);
cd9052
+	if (config == NULL) {
cd9052
+		return FALSE;
cd9052
+	}
cd9052
+
cd9052
+	/* When writing to a file glib will replace the original file with a
cd9052
+	 * new one. To make sure permissions and other attributes like e.g.
cd9052
+	 * SELinux labels stay the same this information is saved before the
cd9052
+	 * change and applied to the new file afterwards. */
cd9052
+	gfile = g_file_new_for_path (realm_ini_config_get_filename (config));
cd9052
+	file_info = g_file_query_info (gfile, "*", 0, NULL, error);
cd9052
+	g_object_unref (gfile);
cd9052
+	if (*error != NULL) {
cd9052
+		g_warning ("Couldn't load file attributes, "
cd9052
+		           "will continue without: %s: %s",
cd9052
+		           realm_ini_config_get_filename (config),
cd9052
+		           (*error)->message);
cd9052
+		g_clear_error (error);
cd9052
+	}
cd9052
+
cd9052
+	if (!realm_ini_config_begin_change (config, error)) {
cd9052
+		g_object_unref (config);
cd9052
+		return FALSE;
cd9052
+	}
cd9052
+
cd9052
+	realm_ini_config_set (config, "libdefaults",
cd9052
+	                              "default_realm", realm,
cd9052
+	                              "udp_preference_limit", "0",
cd9052
+	                               NULL);
cd9052
+
cd9052
+	res = realm_ini_config_finish_change (config, error);
cd9052
+
cd9052
+	if (file_info != NULL) {
cd9052
+		gfile = g_file_new_for_path (realm_ini_config_get_filename (config));
cd9052
+		if (!g_file_set_attributes_from_info (gfile, file_info,
cd9052
+		                                      0, NULL, error)) {
cd9052
+			g_warning ("Couldn't set file attributes: %s: %s",
cd9052
+			           realm_ini_config_get_filename (config),
cd9052
+			           (*error)->message);
cd9052
+		}
cd9052
+		g_object_unref (file_info);
cd9052
+		g_object_unref (gfile);
cd9052
+	}
cd9052
+
cd9052
+	g_object_unref (config);
cd9052
+
cd9052
+	return res;
cd9052
+}
cd9052
diff --git a/service/realm-kerberos-config.h b/service/realm-kerberos-config.h
cd9052
new file mode 100644
cd9052
index 0000000..791aa98
cd9052
--- /dev/null
cd9052
+++ b/service/realm-kerberos-config.h
cd9052
@@ -0,0 +1,35 @@
cd9052
+/* realmd -- Realm configuration service
cd9052
+ *
cd9052
+ * Copyright 2020 Red Hat Inc
cd9052
+ *
cd9052
+ * This program is free software: you can redistribute it and/or modify
cd9052
+ * it under the terms of the GNU Lesser General Public License as published
cd9052
+ * by the Free Software Foundation; either version 2 of the licence or (at
cd9052
+ * your option) any later version.
cd9052
+ *
cd9052
+ * See the included COPYING file for more information.
cd9052
+ *
cd9052
+ * Author: Sumit Bose <sbose@redhat.com>
cd9052
+ */
cd9052
+
cd9052
+#include "config.h"
cd9052
+
cd9052
+#ifndef __REALM_KERBEROS_CONFIG_H__
cd9052
+#define __REALM_KERBEROS_CONFIG_H__
cd9052
+
cd9052
+#include <gio/gio.h>
cd9052
+
cd9052
+#include "realm-ini-config.h"
cd9052
+
cd9052
+
cd9052
+RealmIniConfig *    realm_kerberos_config_new                      (GError **error);
cd9052
+
cd9052
+RealmIniConfig *    realm_kerberos_config_new_with_flags           (RealmIniFlags flags,
cd9052
+                                                                    GError **error);
cd9052
+
cd9052
+gboolean            configure_krb5_conf_for_domain                 (const gchar *realm,
cd9052
+                                                                    GError **error );
cd9052
+
cd9052
+G_END_DECLS
cd9052
+
cd9052
+#endif /* __REALM_KERBEROS_CONFIG_H__ */
cd9052
diff --git a/service/realm-samba.c b/service/realm-samba.c
cd9052
index fe33600..e7b80a0 100644
cd9052
--- a/service/realm-samba.c
cd9052
+++ b/service/realm-samba.c
cd9052
@@ -21,6 +21,7 @@
cd9052
 #include "realm-disco.h"
cd9052
 #include "realm-errors.h"
cd9052
 #include "realm-kerberos.h"
cd9052
+#include "realm-kerberos-config.h"
cd9052
 #include "realm-kerberos-membership.h"
cd9052
 #include "realm-options.h"
cd9052
 #include "realm-packages.h"
cd9052
@@ -210,6 +211,17 @@ on_join_do_winbind (GObject *source,
cd9052
 		                         NULL);
cd9052
 	}
cd9052
 
cd9052
+	if (error == NULL) {
cd9052
+		configure_krb5_conf_for_domain (enroll->disco->kerberos_realm, &error);
cd9052
+		if (error != NULL) {
cd9052
+			realm_diagnostics_error (enroll->invocation, error,
cd9052
+			                         "Failed to update Kerberos "
cd9052
+			                         "configuration, not fatal, "
cd9052
+			                         "please check manually");
cd9052
+			g_clear_error (&error);
cd9052
+		}
cd9052
+	}
cd9052
+
cd9052
 	if (error == NULL) {
cd9052
 		name = realm_kerberos_get_name (REALM_KERBEROS (self));
cd9052
 		realm_samba_winbind_configure_async (self->config, name, enroll->options,
cd9052
diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c
cd9052
index de7ce30..6b2f9f8 100644
cd9052
--- a/service/realm-sssd-ad.c
cd9052
+++ b/service/realm-sssd-ad.c
cd9052
@@ -19,6 +19,7 @@
cd9052
 #include "realm-dbus-constants.h"
cd9052
 #include "realm-diagnostics.h"
cd9052
 #include "realm-errors.h"
cd9052
+#include "realm-kerberos-config.h"
cd9052
 #include "realm-kerberos-membership.h"
cd9052
 #include "realm-options.h"
cd9052
 #include "realm-packages.h"
cd9052
@@ -256,6 +257,17 @@ on_join_do_sssd (GObject *source,
cd9052
 		                           join->options, join->use_adcli, &error);
cd9052
 	}
cd9052
 
cd9052
+	if (error == NULL) {
cd9052
+		configure_krb5_conf_for_domain (join->disco->kerberos_realm, &error);
cd9052
+		if (error != NULL) {
cd9052
+			realm_diagnostics_error (join->invocation, error,
cd9052
+			                         "Failed to update Kerberos "
cd9052
+			                         "configuration, not fatal, "
cd9052
+			                         "please check manually");
cd9052
+			g_clear_error (&error);
cd9052
+		}
cd9052
+	}
cd9052
+
cd9052
 	if (error == NULL) {
cd9052
 		realm_service_enable_and_restart ("sssd", join->invocation,
cd9052
 		                                  on_sssd_enable_nss, g_object_ref (task));
cd9052
diff --git a/service/realmd-debian.conf b/service/realmd-debian.conf
cd9052
index 3e93d60..6cfdcef 100644
cd9052
--- a/service/realmd-debian.conf
cd9052
+++ b/service/realmd-debian.conf
cd9052
@@ -1,6 +1,7 @@
cd9052
 # Distro specific overrides for debian
cd9052
 [paths]
cd9052
 smb.conf = /etc/samba/smb.conf
cd9052
+krb5.conf = /etc/krb5.conf
cd9052
 
cd9052
 #
cd9052
 # Normally in these packages sections we can specify a file
cd9052
diff --git a/service/realmd-defaults.conf b/service/realmd-defaults.conf
cd9052
index 6d7ccf8..ac4b436 100644
cd9052
--- a/service/realmd-defaults.conf
cd9052
+++ b/service/realmd-defaults.conf
cd9052
@@ -11,6 +11,7 @@ sssd.conf = /etc/sssd/sssd.conf
cd9052
 adcli = /usr/sbin/adcli
cd9052
 ipa-client-install = /usr/sbin/ipa-client-install
cd9052
 pam_winbind.conf = /etc/security/pam_winbind.conf
cd9052
+krb5.conf = /etc/krb5.conf
cd9052
 
cd9052
 [active-directory]
cd9052
 default-client = sssd
cd9052
diff --git a/service/realmd-redhat.conf b/service/realmd-redhat.conf
cd9052
index e39fad5..46e61b1 100644
cd9052
--- a/service/realmd-redhat.conf
cd9052
+++ b/service/realmd-redhat.conf
cd9052
@@ -1,6 +1,7 @@
cd9052
 # Distro specific overrides for redhat
cd9052
 [paths]
cd9052
 smb.conf = /etc/samba/smb.conf
cd9052
+krb5.conf = /etc/krb5.conf
cd9052
 
cd9052
 [samba-packages]
cd9052
 samba-common-tools = /usr/bin/net
cd9052
diff --git a/service/realmd-suse.conf b/service/realmd-suse.conf
cd9052
index 052b4dc..3165efa 100644
cd9052
--- a/service/realmd-suse.conf
cd9052
+++ b/service/realmd-suse.conf
cd9052
@@ -1,6 +1,7 @@
cd9052
 # Distro specific overrides for SuSE
cd9052
 [paths]
cd9052
 smb.conf = /etc/samba/smb.conf
cd9052
+krb5.conf = /etc/krb5.conf
cd9052
 
cd9052
 [samba-packages]
cd9052
 samba-client = /usr/bin/net
cd9052
-- 
cd9052
2.26.2
cd9052