stefw pushed to realmd (f21). "Fixes for security issues (..more)"

notifications at fedoraproject.org notifications at fedoraproject.org
Tue Apr 14 11:06:55 UTC 2015


>From 4151226054b058f7fbea8f35b70b117e3a3aa197 Mon Sep 17 00:00:00 2001
From: Stef Walter <stefw at redhat.com>
Date: Tue, 14 Apr 2015 13:04:34 +0200
Subject: Fixes for security issues

rhbz#1205752
rhbz#1205753

diff --git a/disable-automatic-ad-joins.patch b/disable-automatic-ad-joins.patch
new file mode 100644
index 0000000..219ab64
--- /dev/null
+++ b/disable-automatic-ad-joins.patch
@@ -0,0 +1,560 @@
+From d3b84368adefddc9bac7abda3b536d38f8b636d7 Mon Sep 17 00:00:00 2001
+From: Stef Walter <stefw at redhat.com>
+Date: Fri, 20 Feb 2015 22:05:32 +0100
+Subject: [PATCH 2/2] service: Fix for automatic AD join problems
+
+We only offer them as an option to clients if they have been configured
+in the realmd.conf file.
+
+This is because automatic AD joins do not have the mutual authentication
+we usually expect with kerberos. The computer account secret is
+predictable and not secure enough to be on by default.
+
+Also refactor to support per domain supported cred types
+
+This is so specific domains can be configured to support things
+like automatic authentication.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=89205
+---
+ doc/manual/realm.xml                         |  5 +-
+ doc/manual/realmd-guide-active-directory.xml |  1 -
+ doc/manual/realmd.conf.xml                   | 20 ++++++++
+ service/realm-example.c                      | 38 +++++++++-----
+ service/realm-kerberos-membership.h          |  4 +-
+ service/realm-kerberos.c                     | 23 +++++----
+ service/realm-options.c                      | 13 +++++
+ service/realm-options.h                      |  2 +
+ service/realm-samba.c                        | 50 +++++++++++--------
+ service/realm-sssd-ad.c                      | 75 ++++++++++++++++++----------
+ service/realm-sssd-ipa.c                     | 48 +++++++++++-------
+ 11 files changed, 185 insertions(+), 94 deletions(-)
+
+diff --git a/doc/manual/realm.xml b/doc/manual/realm.xml
+index 4b19766..aa79ec6 100644
+--- a/doc/manual/realm.xml
++++ b/doc/manual/realm.xml
+@@ -160,9 +160,8 @@ $ realm join --user=admin --computer-ou=OU=Special domain.example.com
+ 	must have a supported mechanism for joining from a client machine, such
+ 	as Active Directory or IPA.</para>
+ 
+-	<para>Unless a <literal>--user</literal> is explicitly specified, an
+-	automatic join is attempted first. Automatic joins require pre-configuration
+-	on the domain side, and may not be supported by all domains.</para>
++	<para>If the domain has been preconfigured, and unless <literal>--user</literal>
++	is explicitly specified, an automatic join is attempted first.</para>
+ 
+ 	<para>Note that the <literal>--user </literal>, <literal>--no-password</literal>,
+ 	and <literal>--one-time-password </literal> options are mutually exclusive.
+diff --git a/doc/manual/realmd-guide-active-directory.xml b/doc/manual/realmd-guide-active-directory.xml
+index 401d299..9b4535d 100644
+--- a/doc/manual/realmd-guide-active-directory.xml
++++ b/doc/manual/realmd-guide-active-directory.xml
+@@ -139,7 +139,6 @@ $ <command>realm join --verbose domain.example.com</command>
+ 		<itemizedlist>
+ 			<listitem><para>Discovers information about the domain.</para></listitem>
+ 			<listitem><para>Installs the necessary software to join the domain, such as SSSD or Winbind.</para></listitem>
+-			<listitem><para>Tries to join the domain automatically, without administrative credentials.</para></listitem>
+ 			<listitem><para>If administrative credentials are required, a password will be prompted for.</para></listitem>
+ 			<listitem><para>A computer account in the domain will be created, and or updated.</para></listitem>
+ 			<listitem><para>A host keytab file at <filename>/etc/krb5.keytab</filename> is created.</para></listitem>
+diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml
+index b85c057..7f969fa 100644
+--- a/doc/manual/realmd.conf.xml
++++ b/doc/manual/realmd.conf.xml
+@@ -339,6 +339,26 @@ user-principal = yes
+ 	</varlistentry>
+ 
+ 	<varlistentry>
++	<term><option>automatic-join</option></term>
++	<listitem>
++		<para>This option only applies to Active Directory realms. This option
++		is off by default. In Active Directory domains, a computer account can
++		be preset with a known computer account password. This can be used for
++		automatic joins without authentication.</para>
++
++		<para>When automatic joins are used there is no mutual authentication
++		between the machine and the domain during the join process.</para>
++
++		<informalexample>
++<programlisting>
++[domain.example.com]
++automatic-join = yes
++</programlisting>
++		</informalexample>
++	</listitem>
++	</varlistentry>
++
++	<varlistentry>
+ 	<term><option>automatic-id-mapping</option></term>
+ 	<listitem>
+ 		<para>This option is on by default for Active Directory realms.
+diff --git a/service/realm-example.c b/service/realm-example.c
+index 37a7dd5..2a8d4aa 100644
+--- a/service/realm-example.c
++++ b/service/realm-example.c
+@@ -186,6 +186,17 @@ realm_example_join_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_example_join_creds (RealmKerberosMembership *membership)
++{
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ 0, }
++	};
++
++	return creds;
++}
++
+ static void
+ on_leave_sleep_done (GObject *source,
+                      GAsyncResult *res,
+@@ -319,6 +330,18 @@ realm_example_leave_async (RealmKerberosMembership *membership,
+ 	}
+ }
+ 
++static const RealmCredential *
++realm_example_leave_creds (RealmKerberosMembership *membership)
++{
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE },
++		{ 0, }
++	};
++
++	return creds;
++}
++
+ static void
+ realm_example_logins_async (RealmKerberos *realm,
+                             GDBusMethodInvocation *invocation,
+@@ -496,24 +519,13 @@ realm_example_class_init (RealmExampleClass *klass)
+ static void
+ realm_example_kerberos_membership_iface (RealmKerberosMembershipIface *iface)
+ {
+-	static const RealmCredential join_creds[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ 0, }
+-	};
+-
+-	static const RealmCredential leave_creds[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE },
+-		{ 0, }
+-	};
+-
+ 	iface->join_async = realm_example_join_async;
+ 	iface->join_finish = realm_example_membership_generic_finish;
+-	iface->join_creds_supported = join_creds;
++	iface->join_creds = realm_example_join_creds;
+ 
+ 	iface->leave_async = realm_example_leave_async;
+ 	iface->leave_finish = realm_example_membership_generic_finish;
+-	iface->leave_creds_supported = leave_creds;
++	iface->leave_creds = realm_example_leave_creds;
+ }
+ 
+ RealmKerberos *
+diff --git a/service/realm-kerberos-membership.h b/service/realm-kerberos-membership.h
+index 9b1e395..50eea53 100644
+--- a/service/realm-kerberos-membership.h
++++ b/service/realm-kerberos-membership.h
+@@ -48,7 +48,7 @@ struct _RealmKerberosMembershipIface {
+ 	                                         GAsyncResult *result,
+ 	                                         GError **error);
+ 
+-	const RealmCredential *join_creds_supported;
++	const RealmCredential * (* join_creds)  (RealmKerberosMembership *realm);
+ 
+ 	void       (* leave_async)              (RealmKerberosMembership *realm,
+ 	                                         RealmCredential *cred,
+@@ -61,7 +61,7 @@ struct _RealmKerberosMembershipIface {
+ 	                                         GAsyncResult *result,
+ 	                                         GError **error);
+ 
+-	const RealmCredential *leave_creds_supported;
++	const RealmCredential * (* leave_creds) (RealmKerberosMembership *realm);
+ };
+ 
+ GType               realm_kerberos_membership_get_type        (void) G_GNUC_CONST;
+diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c
+index e7f2f20..54d1ed7 100644
+--- a/service/realm-kerberos.c
++++ b/service/realm-kerberos.c
+@@ -241,6 +241,7 @@ on_unenroll_complete (GObject *source,
+ 
+ static gboolean
+ is_credential_supported (RealmKerberosMembershipIface *iface,
++                         RealmKerberosMembership *membership,
+                          RealmCredential *cred,
+                          gboolean join,
+                          GError **error)
+@@ -250,7 +251,10 @@ is_credential_supported (RealmKerberosMembershipIface *iface,
+ 	gboolean found = FALSE;
+ 	gint i;
+ 
+-	supported = join ? iface->join_creds_supported : iface->leave_creds_supported;
++	g_assert (iface->join_creds != NULL);
++	g_assert (iface->leave_creds != NULL);
++
++	supported = (join ? iface->join_creds (membership) : iface->leave_creds (membership));
+ 	if (supported) {
+ 		for (i = 0; supported[i].type != 0; i++) {
+ 			if (cred->type == supported[i].type) {
+@@ -294,6 +298,7 @@ join_or_leave (RealmKerberos *self,
+                gboolean join)
+ {
+ 	RealmKerberosMembershipIface *iface = REALM_KERBEROS_MEMBERSHIP_GET_IFACE (self);
++	RealmKerberosMembership *membership = REALM_KERBEROS_MEMBERSHIP (self);
+ 	RealmCredential *cred;
+ 	MethodClosure *method;
+ 	GError *error = NULL;
+@@ -315,7 +320,7 @@ join_or_leave (RealmKerberos *self,
+ 		return;
+ 	}
+ 
+-	if (!is_credential_supported (iface, cred, join, &error)) {
++	if (!is_credential_supported (iface, membership, cred, join, &error)) {
+ 		g_dbus_method_invocation_return_gerror (invocation, error);
+ 		realm_credential_unref (cred);
+ 		g_error_free (error);
+@@ -333,12 +338,10 @@ join_or_leave (RealmKerberos *self,
+ 
+ 	if (join) {
+ 		g_return_if_fail (iface->join_finish != NULL);
+-		(iface->join_async) (REALM_KERBEROS_MEMBERSHIP (self), cred,
+-		                     options, invocation, on_enroll_complete, method);
++		(iface->join_async) (membership, cred, options, invocation, on_enroll_complete, method);
+ 	} else {
+ 		g_return_if_fail (iface->leave_finish != NULL);
+-		(iface->leave_async) (REALM_KERBEROS_MEMBERSHIP (self), cred,
+-		                      options, invocation, on_unenroll_complete, method);
++		(iface->leave_async) (membership, cred, options, invocation, on_unenroll_complete, method);
+ 	}
+ }
+ 
+@@ -543,6 +546,7 @@ static void
+ realm_kerberos_constructed (GObject *obj)
+ {
+ 	RealmKerberosMembershipIface *iface;
++	RealmKerberosMembership *membership;
+ 	RealmKerberos *self = REALM_KERBEROS (obj);
+ 	const gchar *supported_interfaces[3];
+ 	GVariant *supported;
+@@ -561,11 +565,12 @@ realm_kerberos_constructed (GObject *obj)
+ 		                                      G_DBUS_INTERFACE_SKELETON (self->pv->membership_iface));
+ 
+ 		iface = REALM_KERBEROS_MEMBERSHIP_GET_IFACE (self);
+-		supported = realm_credential_build_supported (iface->join_creds_supported);
++		membership = REALM_KERBEROS_MEMBERSHIP (self);
++
++		supported = realm_credential_build_supported (iface->join_creds (membership));
+ 		realm_dbus_kerberos_membership_set_supported_join_credentials (self->pv->membership_iface, supported);
+ 
+-		iface = REALM_KERBEROS_MEMBERSHIP_GET_IFACE (self);
+-		supported = realm_credential_build_supported (iface->leave_creds_supported);
++		supported = realm_credential_build_supported (iface->leave_creds (membership));
+ 		realm_dbus_kerberos_membership_set_supported_leave_credentials (self->pv->membership_iface, supported);
+ 	}
+ 
+diff --git a/service/realm-options.c b/service/realm-options.c
+index f7a473c..6f7d915 100644
+--- a/service/realm-options.c
++++ b/service/realm-options.c
+@@ -96,6 +96,19 @@ realm_options_automatic_mapping (const gchar *realm_name)
+ }
+ 
+ gboolean
++realm_options_automatic_join (const gchar *realm_name)
++{
++	gchar *section;
++	gboolean mapping;
++
++	section = g_utf8_casefold (realm_name, -1);
++	mapping = realm_settings_boolean (realm_name, "automatic-join", FALSE);
++	g_free (section);
++
++	return mapping;
++}
++
++gboolean
+ realm_options_qualify_names (const gchar *realm_name)
+ {
+ 	gchar *section;
+diff --git a/service/realm-options.h b/service/realm-options.h
+index 4c95927..10af386 100644
+--- a/service/realm-options.h
++++ b/service/realm-options.h
+@@ -26,6 +26,8 @@ gboolean       realm_options_manage_system            (GVariant *options,
+ 
+ gboolean       realm_options_automatic_install        (GVariant *options);
+ 
++gboolean       realm_options_automatic_join           (const gchar *realm_name);
++
+ const gchar *  realm_options_computer_ou              (GVariant *options,
+                                                        const gchar *realm_name);
+ 
+diff --git a/service/realm-samba.c b/service/realm-samba.c
+index 3a8ce87..9bf7872 100644
+--- a/service/realm-samba.c
++++ b/service/realm-samba.c
+@@ -293,6 +293,19 @@ realm_samba_join_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_samba_join_creds (RealmKerberosMembership *self)
++{
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER },
++		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ 0, },
++	};
++
++	return creds;
++}
++
+ typedef struct {
+ 	GDBusMethodInvocation *invocation;
+ 	RealmDisco *disco;
+@@ -425,6 +438,19 @@ realm_samba_leave_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_samba_leave_creds (RealmKerberosMembership *self)
++{
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER },
++		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE },
++		{ 0, },
++	};
++
++	return creds;
++}
++
+ static gboolean
+ realm_samba_change_logins (RealmKerberos *realm,
+                            GDBusMethodInvocation *invocation,
+@@ -674,33 +700,13 @@ realm_samba_class_init (RealmSambaClass *klass)
+ static void
+ realm_samba_kerberos_membership_iface (RealmKerberosMembershipIface *iface)
+ {
+-	/*
+-	 * Each line is a combination of owner and what kind of credentials are supported,
+-	 * same for enroll/leave. We can't accept a ccache, because samba3 needs
+-	 * to have credentials limited to RC4.
+-	 */
+-
+-	static const RealmCredential join_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER },
+-		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ 0, },
+-	};
+-
+-	static const RealmCredential leave_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER },
+-		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE },
+-		{ 0, },
+-	};
+-
+ 	iface->join_async = realm_samba_join_async;
+ 	iface->join_finish = realm_samba_membership_generic_finish;
+-	iface->join_creds_supported = join_supported;
++	iface->join_creds = realm_samba_join_creds;
+ 
+ 	iface->leave_async = realm_samba_leave_async;
+ 	iface->leave_finish = realm_samba_membership_generic_finish;
+-	iface->leave_creds_supported = leave_supported;
++	iface->leave_creds = realm_samba_leave_creds;
+ }
+ 
+ RealmKerberos *
+diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c
+index cc488fc..abd7fa7 100644
+--- a/service/realm-sssd-ad.c
++++ b/service/realm-sssd-ad.c
+@@ -426,6 +426,39 @@ realm_sssd_ad_join_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_sssd_ad_join_creds (RealmKerberosMembership *membership)
++{
++	/*
++	 * Each line is a combination of owner and what kind of credentials are supported,
++	 * same for enroll/leave. We can't accept a ccache with samba because of certain
++	 * corner cases. However we do accept ccache for an admin user, and then we use
++	 * adcli with that ccache.
++	 */
++
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER, },
++		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
++		{ REALM_CREDENTIAL_SECRET, REALM_CREDENTIAL_OWNER_NONE, },
++		{ 0, },
++	};
++
++	static const RealmCredential creds_no_auto[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER, },
++		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_SECRET, REALM_CREDENTIAL_OWNER_NONE, },
++		{ 0, }
++	};
++
++	const gchar *name;
++
++	name = realm_kerberos_get_name (REALM_KERBEROS (membership));
++	return realm_options_automatic_join (name) ? creds : creds_no_auto;
++}
++
+ typedef struct {
+ 	GDBusMethodInvocation *invocation;
+ 	gchar *realm_name;
+@@ -527,6 +560,20 @@ realm_sssd_ad_leave_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_sssd_ad_leave_creds (RealmKerberosMembership *membership)
++{
++	/* For leave, we don't support one-time-password (ie: secret/none) */
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
++		{ 0, },
++	};
++
++	return creds;
++}
++
+ static gboolean
+ realm_sssd_ad_generic_finish (RealmKerberosMembership *realm,
+                               GAsyncResult *result,
+@@ -594,35 +641,11 @@ realm_sssd_ad_class_init (RealmSssdAdClass *klass)
+ static void
+ realm_sssd_ad_kerberos_membership_iface (RealmKerberosMembershipIface *iface)
+ {
+-	/*
+-	 * Each line is a combination of owner and what kind of credentials are supported,
+-	 * same for enroll/leave. We can't accept a ccache with samba because of certain
+-	 * corner cases. However we do accept ccache for an admin user, and then we use
+-	 * adcli with that ccache.
+-	 */
+-
+-	static const RealmCredential join_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_USER, },
+-		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN, },
+-		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
+-		{ REALM_CREDENTIAL_SECRET, REALM_CREDENTIAL_OWNER_NONE, },
+-		{ 0, },
+-	};
+-
+-	/* For leave, we don't support one-time-password (ie: secret/none) */
+-	static const RealmCredential leave_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
+-		{ REALM_CREDENTIAL_CCACHE, REALM_CREDENTIAL_OWNER_ADMIN, },
+-		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
+-		{ 0, },
+-	};
+-
+ 	iface->join_async = realm_sssd_ad_join_async;
+ 	iface->join_finish = realm_sssd_ad_generic_finish;
+-	iface->join_creds_supported = join_supported;
++	iface->join_creds = realm_sssd_ad_join_creds;
+ 
+ 	iface->leave_async = realm_sssd_ad_leave_async;
+ 	iface->leave_finish = realm_sssd_ad_generic_finish;
+-	iface->leave_creds_supported = leave_supported;
++	iface->leave_creds = realm_sssd_ad_leave_creds;
+ }
+diff --git a/service/realm-sssd-ipa.c b/service/realm-sssd-ipa.c
+index ecf5026..a697223 100644
+--- a/service/realm-sssd-ipa.c
++++ b/service/realm-sssd-ipa.c
+@@ -390,6 +390,22 @@ realm_sssd_ipa_join_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_sssd_ipa_join_creds (RealmKerberosMembership *membership)
++{
++	/*
++	 * NOTE: The ipa-client-install service requires that we pass a password directly
++	 * to the process, and not a ccache. It also accepts a one time password.
++	 */
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
++		{ REALM_CREDENTIAL_SECRET, REALM_CREDENTIAL_OWNER_NONE, },
++		{ 0, }
++	};
++
++	return creds;
++}
++
+ static void
+ on_ipa_client_do_disable (GObject *source,
+                           GAsyncResult *result,
+@@ -489,6 +505,18 @@ realm_sssd_ipa_leave_async (RealmKerberosMembership *membership,
+ 	g_object_unref (task);
+ }
+ 
++static const RealmCredential *
++realm_sssd_ipa_leave_creds (RealmKerberosMembership *membership)
++{
++	static const RealmCredential creds[] = {
++		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
++		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
++		{ 0, }
++	};
++
++	return creds;
++}
++
+ static gboolean
+ realm_sssd_ipa_generic_finish (RealmKerberosMembership *realm,
+                                GAsyncResult *result,
+@@ -501,27 +529,11 @@ static void
+ realm_sssd_ipa_kerberos_membership_iface (RealmKerberosMembershipIface *iface)
+ {
+ 
+-	/*
+-	 * NOTE: The ipa-client-install service requires that we pass a password directly
+-	 * to the process, and not a ccache. It also accepts a one time password.
+-	 */
+-	static const RealmCredential join_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN },
+-		{ REALM_CREDENTIAL_SECRET, REALM_CREDENTIAL_OWNER_NONE, },
+-		{ 0, }
+-	};
+-
+-	static const RealmCredential leave_supported[] = {
+-		{ REALM_CREDENTIAL_PASSWORD, REALM_CREDENTIAL_OWNER_ADMIN, },
+-		{ REALM_CREDENTIAL_AUTOMATIC, REALM_CREDENTIAL_OWNER_NONE, },
+-		{ 0, }
+-	};
+-
+ 	iface->join_async = realm_sssd_ipa_join_async;
+ 	iface->join_finish = realm_sssd_ipa_generic_finish;
+-	iface->join_creds_supported = join_supported;
++	iface->join_creds = realm_sssd_ipa_join_creds;
+ 
+ 	iface->leave_async = realm_sssd_ipa_leave_async;
+ 	iface->leave_finish = realm_sssd_ipa_generic_finish;
+-	iface->leave_creds_supported = leave_supported;
++	iface->leave_creds = realm_sssd_ipa_leave_creds;
+ }
+-- 
+2.3.5
+
diff --git a/ldap-validate-text.patch b/ldap-validate-text.patch
new file mode 100644
index 0000000..e73d815
--- /dev/null
+++ b/ldap-validate-text.patch
@@ -0,0 +1,124 @@
+From 77a255356efa20ab1a445b061d1adfe9f5042aa2 Mon Sep 17 00:00:00 2001
+From: Stef Walter <stefw at redhat.com>
+Date: Tue, 14 Apr 2015 11:30:53 +0200
+Subject: [PATCH 1/2] service: Limit the characters we read from LDAP and
+ MSCLDAP
+
+We strictly limit this to characters expected in domain names.
+
+This provides an extra layer of protection against injecting
+odd characters into configuration files.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=89207
+---
+ service/realm-disco-mscldap.c | 11 ++++++++++-
+ service/realm-disco-rootdse.c | 21 ++++++++++++++++-----
+ 2 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/service/realm-disco-mscldap.c b/service/realm-disco-mscldap.c
+index 6ffa105..1ed4063 100644
+--- a/service/realm-disco-mscldap.c
++++ b/service/realm-disco-mscldap.c
+@@ -40,6 +40,8 @@ typedef struct {
+ #define HOST_NAME_MAX 255
+ #endif
+ 
++#define DOMAIN_NAME_VALID "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."
++
+ static void
+ closure_free (gpointer data)
+ {
+@@ -98,14 +100,21 @@ get_string (guchar *beg,
+             guchar **at)
+ {
+ 	gchar buffer[HOST_NAME_MAX];
++	gsize len;
+ 	int n;
+ 
+ 	n = dn_expand (beg, end, *at, buffer, sizeof (buffer));
+ 	if (n < 0)
+ 		return NULL;
+ 
++	len = strlen (buffer);
++	if (strspn (buffer, DOMAIN_NAME_VALID) != len) {
++		g_message ("received invalid NetLogon string characters");
++		return NULL;
++	}
++
+ 	(*at) += n;
+-	return g_strdup (buffer);
++	return g_strndup (buffer, len);
+ }
+ 
+ static gboolean
+diff --git a/service/realm-disco-rootdse.c b/service/realm-disco-rootdse.c
+index f1ae7bb..1a80d98 100644
+--- a/service/realm-disco-rootdse.c
++++ b/service/realm-disco-rootdse.c
+@@ -24,6 +24,8 @@
+ 
+ #include <resolv.h>
+ 
++#define DOMAIN_NAME_VALID "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-."
++
+ typedef struct _Closure Closure;
+ 
+ struct _Closure {
+@@ -89,7 +91,8 @@ entry_has_attribute (LDAP *ldap,
+ static gchar *
+ entry_get_attribute (LDAP *ldap,
+                      LDAPMessage *entry,
+-                     const gchar *field)
++                     const gchar *field,
++                     const gchar *valid)
+ {
+ 	struct berval **bvs = NULL;
+ 	gchar *value = NULL;
+@@ -97,8 +100,16 @@ entry_get_attribute (LDAP *ldap,
+ 	if (entry != NULL)
+ 		bvs = ldap_get_values_len (ldap, entry, field);
+ 
+-	if (bvs && bvs[0])
++	if (bvs && bvs[0]) {
+ 		value = g_strndup (bvs[0]->bv_val, bvs[0]->bv_len);
++		if (valid) {
++		       if (strspn (value, valid) != bvs[0]->bv_len) {
++			       g_free (value);
++			       g_message ("Invalid value in LDAP %s field", field);
++			       value = NULL;
++		       }
++		}
++	}
+ 
+ 	ldap_value_free_len (bvs);
+ 
+@@ -144,7 +155,7 @@ result_krb_realm (GTask *task,
+ 	entry = ldap_first_entry (ldap, message);
+ 
+ 	g_free (clo->disco->kerberos_realm);
+-	clo->disco->kerberos_realm = entry_get_attribute (ldap, entry, "cn");
++	clo->disco->kerberos_realm = entry_get_attribute (ldap, entry, "cn", DOMAIN_NAME_VALID);
+ 
+ 	g_debug ("Found realm: %s", clo->disco->kerberos_realm);
+ 
+@@ -200,7 +211,7 @@ result_domain_info (GTask *task,
+ 
+ 	/* What is the domain name? */
+ 	g_free (clo->disco->domain_name);
+-	clo->disco->domain_name = entry_get_attribute (ldap, entry, "associatedDomain");
++	clo->disco->domain_name = entry_get_attribute (ldap, entry, "associatedDomain", DOMAIN_NAME_VALID);
+ 
+ 	g_debug ("Got associatedDomain: %s", clo->disco->domain_name);
+ 
+@@ -299,7 +310,7 @@ result_root_dse (GTask *task,
+ 	entry = ldap_first_entry (ldap, message);
+ 
+ 	/* Parse out the default naming context */
+-	clo->default_naming_context = entry_get_attribute (ldap, entry, "defaultNamingContext");
++	clo->default_naming_context = entry_get_attribute (ldap, entry, "defaultNamingContext", NULL);
+ 
+ 	g_debug ("Got defaultNamingContext: %s", clo->default_naming_context);
+ 
+-- 
+2.3.5
+
diff --git a/realmd.spec b/realmd.spec
index dfd35bb..e33a73c 100644
--- a/realmd.spec
+++ b/realmd.spec
@@ -1,11 +1,14 @@
 Name:		realmd
 Version:	0.15.2
-Release:	1%{?dist}
+Release:	2%{?dist}
 Summary:	Kerberos realm enrollment service
 License:	LGPLv2+
 URL:		http://cgit.freedesktop.org/realmd/realmd/
 Source0:	http://www.freedesktop.org/software/realmd/releases/realmd-%{version}.tar.gz
 
+Patch11:        disable-automatic-ad-joins.patch
+Patch12:        ldap-validate-text.patch
+
 BuildRequires:	intltool pkgconfig
 BuildRequires:	gettext-devel
 BuildRequires:	glib2-devel >= 2.32.0
@@ -35,6 +38,8 @@ applications that use %{name}.
 
 %prep
 %setup -q
+%patch11 -p 1
+%patch12 -p 1
 
 %build
 %configure --disable-silent-rules
@@ -68,6 +73,9 @@ make install DESTDIR=%{buildroot}
 %doc ChangeLog
 
 %changelog
+* Tue Apr 14 2015 Stef Walter <stefw at redhat.com> - 0.15.2-2
+- Fixes for security issues: rhbz#1205752 rhbz#1205753
+
 * Mon Oct 06 2014 Stef Walter <stefw at redhat.com> - 0.15.2-1
 - Update to upstream 0.15.2
 
-- 
cgit v0.10.2


	http://pkgs.fedoraproject.org/cgit/realmd.git/commit/?h=f21&id=4151226054b058f7fbea8f35b70b117e3a3aa197


More information about the scm-commits mailing list