diff --git a/SOURCES/0001-Kerberos-add-default_domain-and-udp_preference_limit.patch b/SOURCES/0001-Kerberos-add-default_domain-and-udp_preference_limit.patch new file mode 100644 index 0000000..7688f29 --- /dev/null +++ b/SOURCES/0001-Kerberos-add-default_domain-and-udp_preference_limit.patch @@ -0,0 +1,392 @@ +From 2fa90caf4ad38541615446b80dbeaccd0d0e6a6f Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 28 Oct 2020 13:40:03 +0100 +Subject: [PATCH] Kerberos: add default_domain and udp_preference_limit + +When joining an Active Directory domain realmd will set the +default_domain and udp_preference_limit in the Kerberos configuration to +avoid errors and make Kerberos handling in the AD domain more easy. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1791016 +--- + doc/manual/realmd.conf.xml | 69 +++++++++++++++++++ + service/Makefile.am | 2 + + service/realm-kerberos-config.c | 116 ++++++++++++++++++++++++++++++++ + service/realm-kerberos-config.h | 35 ++++++++++ + service/realm-samba.c | 12 ++++ + service/realm-sssd-ad.c | 12 ++++ + service/realmd-debian.conf | 1 + + service/realmd-defaults.conf | 1 + + service/realmd-redhat.conf | 1 + + service/realmd-suse.conf | 1 + + 10 files changed, 250 insertions(+) + create mode 100644 service/realm-kerberos-config.c + create mode 100644 service/realm-kerberos-config.h + +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index 9062252..97d2e8d 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -304,6 +304,75 @@ DOMAIN\user:*:13445:13446:Name:/home/DOMAIN/user:/bin/bash + + + ++ ++ paths ++ ++ These options should go in an ++ section of the /etc/realmd.conf file. Only ++ specify the settings you wish to override. ++ ++ ++ ++ ++ ++ Path to the Kerberos configuration file, typically ++ /etc/krb5.conf. It can also be the path of ++ a file included by /etc/krb5.conf, e.g. ++ /etc/krb5.conf.d/realmd_settings, if the ++ file does not exist if will be created. ++ ++ ++ ++[paths] ++krb5.conf = /etc/krb5.conf.d/realmd_settings ++ ++ ++ ++ ++ When joining an Active Directory domain ++ realmd will set the ++ and ++ options in the Kerberos ++ configuration: ++ ++ ++ ++default_realm = DOMAIN.EXAMPLE.COM ++udp_preference_limit = 0 ++ ++ ++ ++ ++ The option is e.g. needed ++ when trying to resolve enterprise principals and makes it more ++ convenient to request Kerberos tickets for users of the default ++ realm. Instead of specifying the whole principal just ++ kinit username can be used. ++ ++ With always TCP ++ will be used to send Kerberos request to domain controller. This ++ is useful in Active Directory environments because Kerberos will ++ typically switch to TCP after initially starting with UDP ++ because AD Kerberos tickets are often larger than UDP can handle. ++ Using TCP by default will avoid those extra UDP round trips. ++ Additionally it helps to avoid issues with password changes when ++ the DC does not reply soon enough and the client will send a ++ second UDP request. The DC might reply with a reply error to the ++ second request although the original password change request was ++ successful and the client will no know if the request was ++ successful or not. When using TCP this cannot happen because the ++ client will never send a second request but waits on the ++ connection until the server replies. ++ ++ Please note that realmd will not remove ++ those options while leaving the domain since they are useful in ++ general. When joining a new domain realmd ++ will of course overwrite . ++ ++ ++ ++ ++ + + Realm specific settings + These options should go in an section with the same name +diff --git a/service/Makefile.am b/service/Makefile.am +index 88ee780..031cd1d 100644 +--- a/service/Makefile.am ++++ b/service/Makefile.am +@@ -57,6 +57,8 @@ realmd_SOURCES = \ + service/realm-invocation.h \ + service/realm-kerberos.c \ + service/realm-kerberos.h \ ++ service/realm-kerberos-config.c \ ++ service/realm-kerberos-config.h \ + service/realm-kerberos-membership.c \ + service/realm-kerberos-membership.h \ + service/realm-kerberos-provider.c \ +diff --git a/service/realm-kerberos-config.c b/service/realm-kerberos-config.c +new file mode 100644 +index 0000000..447a452 +--- /dev/null ++++ b/service/realm-kerberos-config.c +@@ -0,0 +1,116 @@ ++/* realmd -- Realm configuration service ++ * ++ * Copyright 2020 Red Hat Inc ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as published ++ * by the Free Software Foundation; either version 2 of the licence or (at ++ * your option) any later version. ++ * ++ * See the included COPYING file for more information. ++ * ++ * Author: Sumit Bose ++ */ ++ ++#include "config.h" ++ ++#include "realm-ini-config.h" ++#include "realm-kerberos-config.h" ++#include "realm-settings.h" ++ ++#include ++ ++RealmIniConfig * ++realm_kerberos_config_new_with_flags (RealmIniFlags flags, ++ GError **error) ++{ ++ RealmIniConfig *config; ++ const gchar *filename; ++ GError *err = NULL; ++ ++ config = realm_ini_config_new (REALM_INI_LINE_CONTINUATIONS | flags); ++ ++ filename = realm_settings_path ("krb5.conf"); ++ ++ realm_ini_config_read_file (config, filename, &err); ++ ++ if (err != NULL) { ++ /* If the caller wants errors, then don't return an invalid samba config */ ++ if (error) { ++ g_propagate_error (error, err); ++ g_object_unref (config); ++ config = NULL; ++ ++ /* If the caller doesn't care, then warn but continue */ ++ } else { ++ g_warning ("Couldn't load config file: %s: %s", filename, ++ err->message); ++ g_error_free (err); ++ } ++ } ++ ++ return config; ++} ++ ++RealmIniConfig * ++realm_kerberos_config_new (GError **error) ++{ ++ return realm_kerberos_config_new_with_flags (REALM_INI_NONE, error); ++} ++ ++gboolean ++configure_krb5_conf_for_domain (const gchar *realm, GError **error ) ++{ ++ RealmIniConfig *config; ++ gboolean res; ++ GFile *gfile; ++ GFileInfo *file_info = NULL; ++ ++ config = realm_kerberos_config_new (error); ++ if (config == NULL) { ++ return FALSE; ++ } ++ ++ /* When writing to a file glib will replace the original file with a ++ * new one. To make sure permissions and other attributes like e.g. ++ * SELinux labels stay the same this information is saved before the ++ * change and applied to the new file afterwards. */ ++ gfile = g_file_new_for_path (realm_ini_config_get_filename (config)); ++ file_info = g_file_query_info (gfile, "*", 0, NULL, error); ++ g_object_unref (gfile); ++ if (*error != NULL) { ++ g_warning ("Couldn't load file attributes, " ++ "will continue without: %s: %s", ++ realm_ini_config_get_filename (config), ++ (*error)->message); ++ g_clear_error (error); ++ } ++ ++ if (!realm_ini_config_begin_change (config, error)) { ++ g_object_unref (config); ++ return FALSE; ++ } ++ ++ realm_ini_config_set (config, "libdefaults", ++ "default_realm", realm, ++ "udp_preference_limit", "0", ++ NULL); ++ ++ res = realm_ini_config_finish_change (config, error); ++ ++ if (file_info != NULL) { ++ gfile = g_file_new_for_path (realm_ini_config_get_filename (config)); ++ if (!g_file_set_attributes_from_info (gfile, file_info, ++ 0, NULL, error)) { ++ g_warning ("Couldn't set file attributes: %s: %s", ++ realm_ini_config_get_filename (config), ++ (*error)->message); ++ } ++ g_object_unref (file_info); ++ g_object_unref (gfile); ++ } ++ ++ g_object_unref (config); ++ ++ return res; ++} +diff --git a/service/realm-kerberos-config.h b/service/realm-kerberos-config.h +new file mode 100644 +index 0000000..791aa98 +--- /dev/null ++++ b/service/realm-kerberos-config.h +@@ -0,0 +1,35 @@ ++/* realmd -- Realm configuration service ++ * ++ * Copyright 2020 Red Hat Inc ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU Lesser General Public License as published ++ * by the Free Software Foundation; either version 2 of the licence or (at ++ * your option) any later version. ++ * ++ * See the included COPYING file for more information. ++ * ++ * Author: Sumit Bose ++ */ ++ ++#include "config.h" ++ ++#ifndef __REALM_KERBEROS_CONFIG_H__ ++#define __REALM_KERBEROS_CONFIG_H__ ++ ++#include ++ ++#include "realm-ini-config.h" ++ ++ ++RealmIniConfig * realm_kerberos_config_new (GError **error); ++ ++RealmIniConfig * realm_kerberos_config_new_with_flags (RealmIniFlags flags, ++ GError **error); ++ ++gboolean configure_krb5_conf_for_domain (const gchar *realm, ++ GError **error ); ++ ++G_END_DECLS ++ ++#endif /* __REALM_KERBEROS_CONFIG_H__ */ +diff --git a/service/realm-samba.c b/service/realm-samba.c +index fe33600..e7b80a0 100644 +--- a/service/realm-samba.c ++++ b/service/realm-samba.c +@@ -21,6 +21,7 @@ + #include "realm-disco.h" + #include "realm-errors.h" + #include "realm-kerberos.h" ++#include "realm-kerberos-config.h" + #include "realm-kerberos-membership.h" + #include "realm-options.h" + #include "realm-packages.h" +@@ -210,6 +211,17 @@ on_join_do_winbind (GObject *source, + NULL); + } + ++ if (error == NULL) { ++ configure_krb5_conf_for_domain (enroll->disco->kerberos_realm, &error); ++ if (error != NULL) { ++ realm_diagnostics_error (enroll->invocation, error, ++ "Failed to update Kerberos " ++ "configuration, not fatal, " ++ "please check manually"); ++ g_clear_error (&error); ++ } ++ } ++ + if (error == NULL) { + name = realm_kerberos_get_name (REALM_KERBEROS (self)); + realm_samba_winbind_configure_async (self->config, name, enroll->options, +diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c +index de7ce30..6b2f9f8 100644 +--- a/service/realm-sssd-ad.c ++++ b/service/realm-sssd-ad.c +@@ -19,6 +19,7 @@ + #include "realm-dbus-constants.h" + #include "realm-diagnostics.h" + #include "realm-errors.h" ++#include "realm-kerberos-config.h" + #include "realm-kerberos-membership.h" + #include "realm-options.h" + #include "realm-packages.h" +@@ -256,6 +257,17 @@ on_join_do_sssd (GObject *source, + join->options, join->use_adcli, &error); + } + ++ if (error == NULL) { ++ configure_krb5_conf_for_domain (join->disco->kerberos_realm, &error); ++ if (error != NULL) { ++ realm_diagnostics_error (join->invocation, error, ++ "Failed to update Kerberos " ++ "configuration, not fatal, " ++ "please check manually"); ++ g_clear_error (&error); ++ } ++ } ++ + if (error == NULL) { + realm_service_enable_and_restart ("sssd", join->invocation, + on_sssd_enable_nss, g_object_ref (task)); +diff --git a/service/realmd-debian.conf b/service/realmd-debian.conf +index 3e93d60..6cfdcef 100644 +--- a/service/realmd-debian.conf ++++ b/service/realmd-debian.conf +@@ -1,6 +1,7 @@ + # Distro specific overrides for debian + [paths] + smb.conf = /etc/samba/smb.conf ++krb5.conf = /etc/krb5.conf + + # + # Normally in these packages sections we can specify a file +diff --git a/service/realmd-defaults.conf b/service/realmd-defaults.conf +index 6d7ccf8..ac4b436 100644 +--- a/service/realmd-defaults.conf ++++ b/service/realmd-defaults.conf +@@ -11,6 +11,7 @@ sssd.conf = /etc/sssd/sssd.conf + adcli = /usr/sbin/adcli + ipa-client-install = /usr/sbin/ipa-client-install + pam_winbind.conf = /etc/security/pam_winbind.conf ++krb5.conf = /etc/krb5.conf + + [active-directory] + default-client = sssd +diff --git a/service/realmd-redhat.conf b/service/realmd-redhat.conf +index e39fad5..46e61b1 100644 +--- a/service/realmd-redhat.conf ++++ b/service/realmd-redhat.conf +@@ -1,6 +1,7 @@ + # Distro specific overrides for redhat + [paths] + smb.conf = /etc/samba/smb.conf ++krb5.conf = /etc/krb5.conf + + [samba-packages] + samba-common-tools = /usr/bin/net +diff --git a/service/realmd-suse.conf b/service/realmd-suse.conf +index 052b4dc..3165efa 100644 +--- a/service/realmd-suse.conf ++++ b/service/realmd-suse.conf +@@ -1,6 +1,7 @@ + # Distro specific overrides for SuSE + [paths] + smb.conf = /etc/samba/smb.conf ++krb5.conf = /etc/krb5.conf + + [samba-packages] + samba-client = /usr/bin/net +-- +2.26.2 + diff --git a/SOURCES/0001-Use-startTLS-with-FreeIPA.patch b/SOURCES/0001-Use-startTLS-with-FreeIPA.patch new file mode 100644 index 0000000..eade269 --- /dev/null +++ b/SOURCES/0001-Use-startTLS-with-FreeIPA.patch @@ -0,0 +1,74 @@ +From b53c3e5fb5c90813ce1b47ddc570dd9c800232f9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 3 Jul 2020 17:18:27 +0200 +Subject: [PATCH] Use startTLS with FreeIPA + +FreeIPA is planning to required a minimal security strength factor (ssf) +in an upcoming version. This basically means that communication should +be encrypted. The most straight forward way is use TLS by doing a +StartLS operation after the rootDSE lookup. Since FreeIPA supports TLS +since the initial release we will call StartTLS unconditionally but try +without if it fails. + +Resolves: https://gitlab.freedesktop.org/realmd/realmd/-/issues/23 +--- + service/realm-disco-rootdse.c | 23 +++++++++++++++++++++++ + service/realm-ldap.c | 4 +++- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/service/realm-disco-rootdse.c b/service/realm-disco-rootdse.c +index 3100650..7614071 100644 +--- a/service/realm-disco-rootdse.c ++++ b/service/realm-disco-rootdse.c +@@ -226,10 +226,33 @@ request_domain_info (GTask *task, + LDAP *ldap) + { + const char *attrs[] = { "info", "associatedDomain", NULL }; ++ int ret; ++ int ldap_opt_val; + + clo->request = NULL; + clo->result = result_domain_info; + ++ /* Trying to setup a TLS tunnel in the case the IPA server requires an ++ * encrypted connected. Trying without in case of an error. Since we ++ * most probably do not have the IPA CA certificate we will not check ++ * the server certificate. */ ++ ldap_opt_val = LDAP_OPT_X_TLS_NEVER; ++ ret = ldap_set_option (ldap, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_opt_val); ++ if (ret != LDAP_OPT_SUCCESS) { ++ g_debug ("Failed to disable certificate checking, trying without"); ++ } ++ ++ ldap_opt_val = 0; ++ ret = ldap_set_option (ldap, LDAP_OPT_X_TLS_NEWCTX, &ldap_opt_val); ++ if (ret != LDAP_OPT_SUCCESS) { ++ g_debug ("Failed to refresh LDAP context for TLS, trying without"); ++ } ++ ++ ret = ldap_start_tls_s (ldap, NULL, NULL); ++ if (ret != LDAP_SUCCESS) { ++ g_debug ("Failed to setup TLS tunnel, trying without"); ++ } ++ + return search_ldap (task, clo, ldap, clo->default_naming_context, + LDAP_SCOPE_BASE, NULL, attrs); + } +diff --git a/service/realm-ldap.c b/service/realm-ldap.c +index 59817fb..7831b5b 100644 +--- a/service/realm-ldap.c ++++ b/service/realm-ldap.c +@@ -238,7 +238,9 @@ realm_ldap_connect_anonymous (GSocketAddress *address, + if (!g_unix_set_fd_nonblocking (ls->sock, FALSE, NULL)) + g_warning ("couldn't set to blocking"); + +- rc = ldap_init_fd (ls->sock, 1, NULL, &ls->ldap); ++ url = g_strdup_printf ("ldap://%s:%d", addrname, port); ++ rc = ldap_init_fd (ls->sock, 1, url, &ls->ldap); ++ g_free (url); + + g_free (native); + +-- +2.26.2 + diff --git a/SOURCES/0001-service-add-REALM_DBUS_OPTION_USE_LDAPS-and-realm_ge.patch b/SOURCES/0001-service-add-REALM_DBUS_OPTION_USE_LDAPS-and-realm_ge.patch new file mode 100644 index 0000000..241ee39 --- /dev/null +++ b/SOURCES/0001-service-add-REALM_DBUS_OPTION_USE_LDAPS-and-realm_ge.patch @@ -0,0 +1,69 @@ +From cf40987b7f847be70ef3a5a0fa359116c0259477 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 13:19:09 +0100 +Subject: [PATCH 1/6] service: add REALM_DBUS_OPTION_USE_LDAPS and + realm_get_use_ldaps + +Add a new option to the realmd service to use ldaps where possible and +supported. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1826964 +--- + dbus/realm-dbus-constants.h | 1 + + service/realm-options.c | 17 +++++++++++++++++ + service/realm-options.h | 2 ++ + 3 files changed, 20 insertions(+) + +diff --git a/dbus/realm-dbus-constants.h b/dbus/realm-dbus-constants.h +index 40ffa2d..0bd7a5d 100644 +--- a/dbus/realm-dbus-constants.h ++++ b/dbus/realm-dbus-constants.h +@@ -70,6 +70,7 @@ G_BEGIN_DECLS + #define REALM_DBUS_OPTION_OS_NAME "os-name" + #define REALM_DBUS_OPTION_OS_VERSION "os-version" + #define REALM_DBUS_OPTION_LEGACY_SMB_CONF "legacy-samba-config" ++#define REALM_DBUS_OPTION_USE_LDAPS "use-ldaps" + + #define REALM_DBUS_IDENTIFIER_ACTIVE_DIRECTORY "active-directory" + #define REALM_DBUS_IDENTIFIER_WINBIND "winbind" +diff --git a/service/realm-options.c b/service/realm-options.c +index 34a209f..d42eb7c 100644 +--- a/service/realm-options.c ++++ b/service/realm-options.c +@@ -199,3 +199,20 @@ realm_options_ad_specific (GVariant *options, + + return g_strdup (value); + } ++ ++gboolean realm_option_use_ldaps (GVariant *options) ++{ ++ gchar *use_ldaps_str; ++ ++ use_ldaps_str = realm_options_ad_specific (options, ++ REALM_DBUS_OPTION_USE_LDAPS); ++ if (use_ldaps_str != NULL ++ && ( g_ascii_strcasecmp (use_ldaps_str, "True") == 0 ++ || g_ascii_strcasecmp (use_ldaps_str, "Yes") == 0)) { ++ g_free (use_ldaps_str); ++ return TRUE; ++ } ++ g_free (use_ldaps_str); ++ ++ return FALSE; ++} +diff --git a/service/realm-options.h b/service/realm-options.h +index b71d219..bc13cd7 100644 +--- a/service/realm-options.h ++++ b/service/realm-options.h +@@ -48,6 +48,8 @@ const gchar * realm_options_computer_name (GVariant *options, + const gchar * realm_options_ad_specific (GVariant *options, + const gchar *option_name); + ++gboolean realm_option_use_ldaps (GVariant *options); ++ + G_END_DECLS + + #endif /* __REALM_OPTIONS_H__ */ +-- +2.26.2 + diff --git a/SOURCES/0001-tools-Update-the-usage-help-text-of-the-realm-comman.patch b/SOURCES/0001-tools-Update-the-usage-help-text-of-the-realm-comman.patch new file mode 100644 index 0000000..a0d62d0 --- /dev/null +++ b/SOURCES/0001-tools-Update-the-usage-help-text-of-the-realm-comman.patch @@ -0,0 +1,93 @@ +From 3bdf6f25923c3a3bd8404f4a1228053d6a7551b2 Mon Sep 17 00:00:00 2001 +From: Stef Walter +Date: Mon, 6 Feb 2017 12:32:20 +0100 +Subject: [PATCH] tools: Update the usage help text of the realm commands + +Add better synopsis, sort arguments appropriately, and include +missing arguments. +--- + tools/realm-discover.c | 4 ++-- + tools/realm-join.c | 30 +++++++++++++++--------------- + 2 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/tools/realm-discover.c b/tools/realm-discover.c +index cec3fd0..8dde4ed 100644 +--- a/tools/realm-discover.c ++++ b/tools/realm-discover.c +@@ -186,7 +186,7 @@ realm_discover (RealmClient *client, + { NULL, } + }; + +- context = g_option_context_new ("realm-or-domain"); ++ context = g_option_context_new ("discover REALM-OR-DOMAIN"); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, option_entries, NULL); + g_option_context_add_main_entries (context, realm_global_options, NULL); +@@ -274,7 +274,7 @@ realm_list (RealmClient *client, + { NULL, } + }; + +- context = g_option_context_new ("realm"); ++ context = g_option_context_new ("list"); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + g_option_context_add_main_entries (context, option_entries, NULL); + g_option_context_add_main_entries (context, realm_global_options, NULL); +diff --git a/tools/realm-join.c b/tools/realm-join.c +index 8e46c20..249f502 100644 +--- a/tools/realm-join.c ++++ b/tools/realm-join.c +@@ -286,28 +286,28 @@ realm_join (RealmClient *client, + gint ret = 0; + + GOptionEntry option_entries[] = { +- { "user", 'U', 0, G_OPTION_ARG_STRING, &args.user, +- N_("User name to use for enrollment"), NULL }, +- { "computer-ou", 0, 0, G_OPTION_ARG_STRING, &args.computer_ou, +- N_("Computer OU DN to join"), NULL }, +- { "computer-name", 0, 0, G_OPTION_ARG_STRING, &args.computer_name, +- N_("Use specific computer name instead of hostname"), NULL }, +- { "os-name", 0, 0, G_OPTION_ARG_STRING, &args.os_name, +- N_("Use specific operation system name"), NULL }, +- { "os-version", 0, 0, G_OPTION_ARG_STRING, &args.os_version, +- N_("Use specific operation system version"), NULL }, ++ { "automatic-id-mapping", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, ++ realm_join_arg_id_mapping, N_("Turn off automatic id mapping"), "no" }, + { "client-software", 0, 0, G_OPTION_ARG_STRING, &args.client_software, + N_("Use specific client software"), NULL }, +- { "server-software", 0, 0, G_OPTION_ARG_STRING, &args.server_software, +- N_("Use specific server software"), NULL }, ++ { "computer-name", 0, 0, G_OPTION_ARG_STRING, &args.computer_name, ++ N_("Use specific computer name instead of hostname"), NULL }, ++ { "computer-ou", 0, 0, G_OPTION_ARG_STRING, &args.computer_ou, ++ N_("Computer OU DN to join"), NULL }, + { "membership-software", 0, 0, G_OPTION_ARG_STRING, &args.membership_software, + N_("Use specific membership software"), NULL }, + { "no-password", 0, 0, G_OPTION_ARG_NONE, &args.no_password, + N_("Join automatically without a password"), NULL }, + { "one-time-password", 0, 0, G_OPTION_ARG_STRING, &args.one_time_password, + N_("Join using a preset one time password"), NULL }, +- { "automatic-id-mapping", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, +- realm_join_arg_id_mapping, N_("Turn off automatic id mapping"), "no" }, ++ { "os-name", 0, 0, G_OPTION_ARG_STRING, &args.os_name, ++ N_("Use specific operation system name"), NULL }, ++ { "os-version", 0, 0, G_OPTION_ARG_STRING, &args.os_version, ++ N_("Use specific operation system version"), NULL }, ++ { "server-software", 0, 0, G_OPTION_ARG_STRING, &args.server_software, ++ N_("Use specific server software"), NULL }, ++ { "user", 'U', 0, G_OPTION_ARG_STRING, &args.user, ++ N_("User name to use for enrollment"), NULL }, + { "user-principal", 0, 0, G_OPTION_ARG_STRING, &args.user_principal, + N_("Set the user principal for the computer account"), NULL }, + { NULL, } +@@ -315,7 +315,7 @@ realm_join (RealmClient *client, + + memset (&args, 0, sizeof (args)); + +- context = g_option_context_new ("realm"); ++ context = g_option_context_new ("join REALM"); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); + + group = g_option_group_new (NULL, NULL, NULL, &args, realm_join_args_clear); +-- +2.26.2 + diff --git a/SOURCES/0002-service-allow-to-use-ldaps-for-rootDSE-lookup.patch b/SOURCES/0002-service-allow-to-use-ldaps-for-rootDSE-lookup.patch new file mode 100644 index 0000000..d730483 --- /dev/null +++ b/SOURCES/0002-service-allow-to-use-ldaps-for-rootDSE-lookup.patch @@ -0,0 +1,271 @@ +From 20adfff6c0db657d302bd96f986f2e79a8b2d791 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 13:20:46 +0100 +Subject: [PATCH 2/6] service: allow to use ldaps for rootDSE lookup + +Let the realmd service use ldaps for the rootDSE lookup when requested. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1826964 +--- + service/realm-disco-dns.c | 10 +++++++--- + service/realm-disco-dns.h | 1 + + service/realm-disco-domain.c | 8 +++++++- + service/realm-disco-domain.h | 1 + + service/realm-disco-mscldap.c | 2 +- + service/realm-disco-rootdse.c | 3 ++- + service/realm-disco-rootdse.h | 1 + + service/realm-ldap.c | 5 ++++- + service/realm-ldap.h | 1 + + service/realm-samba-provider.c | 5 ++++- + service/realm-sssd-provider.c | 5 ++++- + 11 files changed, 33 insertions(+), 9 deletions(-) + +diff --git a/service/realm-disco-dns.c b/service/realm-disco-dns.c +index 446010c..77d5034 100644 +--- a/service/realm-disco-dns.c ++++ b/service/realm-disco-dns.c +@@ -32,6 +32,7 @@ typedef struct { + GQueue addresses; + GQueue targets; + gint current_port; ++ gboolean use_ldaps; + gint returned; + DiscoPhase phase; + GResolver *resolver; +@@ -180,7 +181,7 @@ return_or_resolve (RealmDiscoDns *self, + + target = g_queue_pop_head (&self->targets); + if (target) { +- self->current_port = g_srv_target_get_port (target); ++ self->current_port = self->use_ldaps ? 636 : g_srv_target_get_port (target); + g_resolver_lookup_by_name_async (self->resolver, g_srv_target_get_hostname (target), + g_task_get_cancellable (task), on_name_resolved, + g_object_ref (task)); +@@ -201,7 +202,7 @@ return_or_resolve (RealmDiscoDns *self, + g_resolver_lookup_by_name_async (self->resolver, self->name, + g_task_get_cancellable (task), on_name_resolved, + g_object_ref (task)); +- self->current_port = 389; ++ self->current_port = self->use_ldaps ? 636 : 389; + self->phase = PHASE_HOST; + break; + case PHASE_HOST: +@@ -251,6 +252,7 @@ realm_disco_dns_class_init (RealmDiscoDnsClass *klass) + + GSocketAddressEnumerator * + realm_disco_dns_enumerate_servers (const gchar *domain_or_server, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation) + { + RealmDiscoDns *self; +@@ -262,12 +264,14 @@ realm_disco_dns_enumerate_servers (const gchar *domain_or_server, + + self = g_object_new (REALM_TYPE_DISCO_DNS, NULL); + self->name = g_hostname_to_ascii (input); ++ self->use_ldaps = use_ldaps; + self->invocation = g_object_ref (invocation); + + /* If is an IP, skip resolution */ + if (g_hostname_is_ip_address (input)) { + inet = g_inet_address_new_from_string (input); +- g_queue_push_head (&self->addresses, g_inet_socket_address_new (inet, 389)); ++ g_queue_push_head (&self->addresses, ++ g_inet_socket_address_new (inet, use_ldaps ? 636 : 389)); + g_object_unref (inet); + self->phase = PHASE_HOST; + } else { +diff --git a/service/realm-disco-dns.h b/service/realm-disco-dns.h +index a51777f..5b20fe9 100644 +--- a/service/realm-disco-dns.h ++++ b/service/realm-disco-dns.h +@@ -26,6 +26,7 @@ typedef enum { + G_BEGIN_DECLS + + GSocketAddressEnumerator * realm_disco_dns_enumerate_servers (const gchar *domain_or_server, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation); + + RealmDiscoDnsHint realm_disco_dns_get_hint (GSocketAddressEnumerator *enumerator); +diff --git a/service/realm-disco-domain.c b/service/realm-disco-domain.c +index 3f0ccb5..fdda8f6 100644 +--- a/service/realm-disco-domain.c ++++ b/service/realm-disco-domain.c +@@ -37,6 +37,7 @@ typedef struct _Callback { + typedef struct { + GObject parent; + gchar *input; ++ gboolean use_ldaps; + GCancellable *cancellable; + GDBusMethodInvocation *invocation; + GSocketAddressEnumerator *enumerator; +@@ -206,6 +207,7 @@ on_discover_next_address (GObject *source, + + realm_diagnostics_info (self->invocation, "Performing LDAP DSE lookup on: %s", string); + realm_disco_rootdse_async (address, explicit_host, ++ self->use_ldaps, + self->invocation, self->cancellable, + on_discover_rootdse, g_object_ref (self)); + self->outstanding++; +@@ -248,6 +250,7 @@ on_cancel_propagate (GCancellable *source, + + void + realm_disco_domain_async (const gchar *string, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data) +@@ -267,8 +270,11 @@ realm_disco_domain_async (const gchar *string, + if (self == NULL) { + self = g_object_new (REALM_TYPE_DISCO_DOMAIN, NULL); + self->input = g_strdup (string); ++ self->use_ldaps = use_ldaps; + self->invocation = g_object_ref (invocation); +- self->enumerator = realm_disco_dns_enumerate_servers (string, invocation); ++ self->enumerator = realm_disco_dns_enumerate_servers (string, ++ use_ldaps, ++ invocation); + + g_hash_table_insert (discover_cache, self->input, self); + g_assert (!self->completed); +diff --git a/service/realm-disco-domain.h b/service/realm-disco-domain.h +index 27dcc6c..02d4998 100644 +--- a/service/realm-disco-domain.h ++++ b/service/realm-disco-domain.h +@@ -24,6 +24,7 @@ + G_BEGIN_DECLS + + void realm_disco_domain_async (const gchar *string, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data); +diff --git a/service/realm-disco-mscldap.c b/service/realm-disco-mscldap.c +index d3d3c10..2504904 100644 +--- a/service/realm-disco-mscldap.c ++++ b/service/realm-disco-mscldap.c +@@ -348,7 +348,7 @@ realm_disco_mscldap_async (GSocketAddress *address, + return; + } + +- clo->source = realm_ldap_connect_anonymous (address, protocol, cancellable); ++ clo->source = realm_ldap_connect_anonymous (address, protocol, FALSE, cancellable); + g_source_set_callback (clo->source, (GSourceFunc)on_ldap_io, + g_object_ref (task), g_object_unref); + g_source_attach (clo->source, g_task_get_context (task)); +diff --git a/service/realm-disco-rootdse.c b/service/realm-disco-rootdse.c +index 7614071..4ed19e5 100644 +--- a/service/realm-disco-rootdse.c ++++ b/service/realm-disco-rootdse.c +@@ -452,6 +452,7 @@ on_ldap_io (LDAP *ldap, + void + realm_disco_rootdse_async (GSocketAddress *address, + const gchar *explicit_server, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GCancellable *cancellable, + GAsyncReadyCallback callback, +@@ -473,7 +474,7 @@ realm_disco_rootdse_async (GSocketAddress *address, + g_task_set_task_data (task, clo, closure_free); + + clo->source = realm_ldap_connect_anonymous (address, G_SOCKET_PROTOCOL_TCP, +- cancellable); ++ use_ldaps, cancellable); + g_source_set_callback (clo->source, (GSourceFunc)on_ldap_io, + g_object_ref (task), g_object_unref); + g_source_attach (clo->source, g_task_get_context (task)); +diff --git a/service/realm-disco-rootdse.h b/service/realm-disco-rootdse.h +index e024c84..7b21960 100644 +--- a/service/realm-disco-rootdse.h ++++ b/service/realm-disco-rootdse.h +@@ -21,6 +21,7 @@ + + void realm_disco_rootdse_async (GSocketAddress *address, + const gchar *explicit_server, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GCancellable *cancellable, + GAsyncReadyCallback callback, +diff --git a/service/realm-ldap.c b/service/realm-ldap.c +index 7831b5b..28c5c8a 100644 +--- a/service/realm-ldap.c ++++ b/service/realm-ldap.c +@@ -183,6 +183,7 @@ int ldap_init_fd (ber_socket_t fd, int proto, LDAP_CONST char *url, struct ldap + GSource * + realm_ldap_connect_anonymous (GSocketAddress *address, + GSocketProtocol protocol, ++ gboolean use_ldaps, + GCancellable *cancellable) + { + GSource *source; +@@ -238,7 +239,9 @@ realm_ldap_connect_anonymous (GSocketAddress *address, + if (!g_unix_set_fd_nonblocking (ls->sock, FALSE, NULL)) + g_warning ("couldn't set to blocking"); + +- url = g_strdup_printf ("ldap://%s:%d", addrname, port); ++ url = g_strdup_printf ("%s://%s:%d", ++ use_ldaps ? "ldaps" : "ldap", ++ addrname, port); + rc = ldap_init_fd (ls->sock, 1, url, &ls->ldap); + g_free (url); + +diff --git a/service/realm-ldap.h b/service/realm-ldap.h +index 263f72a..0f9f40e 100644 +--- a/service/realm-ldap.h ++++ b/service/realm-ldap.h +@@ -37,6 +37,7 @@ typedef GIOCondition (* RealmLdapCallback) (LDAP *ldap, + + GSource * realm_ldap_connect_anonymous (GSocketAddress *address, + GSocketProtocol protocol, ++ gboolean use_ldaps, + GCancellable *cancellable); + + void realm_ldap_set_condition (GSource *source, +diff --git a/service/realm-samba-provider.c b/service/realm-samba-provider.c +index 9b489ce..de9f5e6 100644 +--- a/service/realm-samba-provider.c ++++ b/service/realm-samba-provider.c +@@ -27,6 +27,7 @@ + #include "realm-samba-enroll.h" + #include "realm-samba-provider.h" + #include "realm-samba-winbind.h" ++#include "realm-options.h" + + #include + +@@ -121,7 +122,9 @@ realm_samba_provider_discover_async (RealmProvider *provider, + g_task_return_pointer (task, NULL, NULL); + + } else { +- realm_disco_domain_async (string, invocation, ++ realm_disco_domain_async (string, ++ realm_option_use_ldaps (options), ++ invocation, + on_ad_discover, g_object_ref (task)); + } + +diff --git a/service/realm-sssd-provider.c b/service/realm-sssd-provider.c +index 7ac0645..db183c0 100644 +--- a/service/realm-sssd-provider.c ++++ b/service/realm-sssd-provider.c +@@ -26,6 +26,7 @@ + #include "realm-sssd-ipa.h" + #include "realm-sssd-provider.h" + #include "realm-sssd-config.h" ++#include "realm-options.h" + + #include + +@@ -140,7 +141,9 @@ realm_sssd_provider_discover_async (RealmProvider *provider, + g_task_return_pointer (task, NULL, NULL); + + } else { +- realm_disco_domain_async (string, invocation, on_kerberos_discover, ++ realm_disco_domain_async (string, ++ realm_option_use_ldaps (options), ++ invocation, on_kerberos_discover, + g_object_ref (task)); + } + +-- +2.26.2 + diff --git a/SOURCES/0003-service-add-ldaps-support-when-using-adcli.patch b/SOURCES/0003-service-add-ldaps-support-when-using-adcli.patch new file mode 100644 index 0000000..bff6fd0 --- /dev/null +++ b/SOURCES/0003-service-add-ldaps-support-when-using-adcli.patch @@ -0,0 +1,186 @@ +From ae247ae2ad87858741d64341633cd4e74f72e873 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 13:28:52 +0100 +Subject: [PATCH 3/6] service: add ldaps support when using adcli + +Call adcli with the --use-ldaps option if the realmd service is +requested to do so. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1826964 +--- + service/realm-adcli-enroll.c | 10 ++++++++++ + service/realm-adcli-enroll.h | 2 ++ + service/realm-samba.c | 11 +++++++++-- + service/realm-sssd-ad.c | 27 ++++++++++++++++++++++++++- + 4 files changed, 47 insertions(+), 3 deletions(-) + +diff --git a/service/realm-adcli-enroll.c b/service/realm-adcli-enroll.c +index 05947fa..2731283 100644 +--- a/service/realm-adcli-enroll.c ++++ b/service/realm-adcli-enroll.c +@@ -68,6 +68,7 @@ void + realm_adcli_enroll_join_async (RealmDisco *disco, + RealmCredential *cred, + GVariant *options, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data) +@@ -102,6 +103,10 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + g_ptr_array_add (args, "--domain-realm"); + g_ptr_array_add (args, (gpointer)disco->kerberos_realm); + ++ if (use_ldaps) { ++ g_ptr_array_add (args, "--use-ldaps"); ++ } ++ + if (G_IS_INET_SOCKET_ADDRESS (disco->server_address)) { + address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (disco->server_address)); + server_arg = g_inet_address_to_string (address); +@@ -218,6 +223,7 @@ void + realm_adcli_enroll_delete_async (RealmDisco *disco, + RealmCredential *cred, + GVariant *options, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data) +@@ -246,6 +252,10 @@ realm_adcli_enroll_delete_async (RealmDisco *disco, + g_ptr_array_add (args, "--domain-realm"); + g_ptr_array_add (args, (gpointer)disco->kerberos_realm); + ++ if (use_ldaps) { ++ g_ptr_array_add (args, "--use-ldaps"); ++ } ++ + if (G_IS_INET_SOCKET_ADDRESS (disco->server_address)) { + address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (disco->server_address)); + server_arg = g_inet_address_to_string (address); +diff --git a/service/realm-adcli-enroll.h b/service/realm-adcli-enroll.h +index 855b2f7..3f535d0 100644 +--- a/service/realm-adcli-enroll.h ++++ b/service/realm-adcli-enroll.h +@@ -29,6 +29,7 @@ G_BEGIN_DECLS + void realm_adcli_enroll_join_async (RealmDisco *disco, + RealmCredential *cred, + GVariant *options, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data); +@@ -39,6 +40,7 @@ gboolean realm_adcli_enroll_join_finish (GAsyncResult *result, + void realm_adcli_enroll_delete_async (RealmDisco *disco, + RealmCredential *cred, + GVariant *options, ++ gboolean use_ldaps, + GDBusMethodInvocation *invocation, + GAsyncReadyCallback callback, + gpointer user_data); +diff --git a/service/realm-samba.c b/service/realm-samba.c +index e7b80a0..7aa5416 100644 +--- a/service/realm-samba.c ++++ b/service/realm-samba.c +@@ -257,7 +257,8 @@ on_install_do_join (GObject *source, + } + + static gboolean +-validate_membership_options (GVariant *options, ++validate_membership_options (EnrollClosure *enroll, ++ GVariant *options, + GError **error) + { + const gchar *software; +@@ -271,6 +272,12 @@ validate_membership_options (GVariant *options, + } + } + ++ if (realm_option_use_ldaps (options)) { ++ realm_diagnostics_info (enroll->invocation, ++ "Membership software %s does " ++ "not support ldaps, trying without.", ++ software); ++ } + return TRUE; + } + +@@ -303,7 +310,7 @@ realm_samba_join_async (RealmKerberosMembership *membership, + g_task_return_new_error (task, REALM_ERROR, REALM_ERROR_ALREADY_CONFIGURED, + _("Already joined to a domain")); + +- } else if (!validate_membership_options (options, &error)) { ++ } else if (!validate_membership_options (enroll, options, &error)) { + g_task_return_error (task, error); + + } else { +diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c +index 6b2f9f8..00a9093 100644 +--- a/service/realm-sssd-ad.c ++++ b/service/realm-sssd-ad.c +@@ -98,6 +98,7 @@ typedef struct { + GVariant *options; + RealmDisco *disco; + gboolean use_adcli; ++ gboolean use_ldaps; + const gchar **packages; + } JoinClosure; + +@@ -294,6 +295,7 @@ on_install_do_join (GObject *source, + realm_adcli_enroll_join_async (join->disco, + join->cred, + join->options, ++ join->use_ldaps, + join->invocation, + on_join_do_sssd, + g_object_ref (task)); +@@ -347,6 +349,19 @@ parse_join_options (JoinClosure *join, + return FALSE; + } + ++ /* ++ * Check if ldaps should be used and if membership software supports ++ * it. ++ */ ++ join->use_ldaps = realm_option_use_ldaps (options); ++ if (join->use_ldaps && ++ g_str_equal (software, REALM_DBUS_IDENTIFIER_SAMBA)) { ++ realm_diagnostics_info (join->invocation, ++ "Membership software %s does " ++ "not support ldaps, trying " ++ "without.", software); ++ } ++ + /* + * If we are enrolling with a user password, then we have to use samba, + * adcli only supports admin passwords. +@@ -523,6 +538,7 @@ realm_sssd_ad_leave_async (RealmKerberosMembership *membership, + GTask *task; + LeaveClosure *leave; + gchar *tags; ++ gboolean use_ldaps = FALSE; + + task = g_task_new (self, NULL, callback, user_data); + +@@ -551,10 +567,19 @@ realm_sssd_ad_leave_async (RealmKerberosMembership *membership, + leave->invocation = g_object_ref (invocation); + leave->use_adcli = strstr (tags ? tags : "", "joined-with-adcli") ? TRUE : FALSE; + g_task_set_task_data (task, leave, leave_closure_free); ++ ++ use_ldaps = realm_option_use_ldaps (options); + if (leave->use_adcli) { +- realm_adcli_enroll_delete_async (disco, cred, options, invocation, ++ realm_adcli_enroll_delete_async (disco, cred, options, ++ use_ldaps, invocation, + on_leave_do_deconfigure, g_object_ref (task)); + } else { ++ if (use_ldaps) { ++ realm_diagnostics_info (leave->invocation, ++ "Membership software does " ++ "not support ldaps, trying " ++ "without."); ++ } + realm_samba_enroll_leave_async (disco, cred, options, invocation, + on_leave_do_deconfigure, g_object_ref (task)); + } +-- +2.26.2 + diff --git a/SOURCES/0004-service-do-not-copy-option-values-to-avoid-memory-le.patch b/SOURCES/0004-service-do-not-copy-option-values-to-avoid-memory-le.patch new file mode 100644 index 0000000..9834783 --- /dev/null +++ b/SOURCES/0004-service-do-not-copy-option-values-to-avoid-memory-le.patch @@ -0,0 +1,88 @@ +From 7daf5993995baad0f5c7f7ae3822dae37eb9f46f Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 16:44:23 +0100 +Subject: [PATCH 4/6] service: do not copy option values to avoid memory leaks + +--- + service/realm-adcli-enroll.c | 15 ++++++++------- + service/realm-options.c | 8 +++----- + 2 files changed, 11 insertions(+), 12 deletions(-) + +diff --git a/service/realm-adcli-enroll.c b/service/realm-adcli-enroll.c +index 2731283..e0d752b 100644 +--- a/service/realm-adcli-enroll.c ++++ b/service/realm-adcli-enroll.c +@@ -80,7 +80,8 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + GBytes *input = NULL; + const gchar *upn; + GPtrArray *args; +- const gchar *os; ++ const gchar *os_n = NULL; ++ const gchar *os_v = NULL; + gchar *ccache_arg = NULL; + gchar *upn_arg = NULL; + gchar *server_arg = NULL; +@@ -144,16 +145,16 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + g_ptr_array_add (args, (gpointer)computer_ou); + } + +- os = realm_options_ad_specific (options, "os-name"); +- if (os != NULL && !g_str_equal (os, "")) { ++ os_n = realm_options_ad_specific (options, "os-name"); ++ if (os_n != NULL && !g_str_equal (os_n, "")) { + g_ptr_array_add (args, "--os-name"); +- g_ptr_array_add (args, (gpointer)os); ++ g_ptr_array_add (args, (gpointer)os_n); + } + +- os = realm_options_ad_specific (options, "os-version"); +- if (os != NULL && !g_str_equal (os, "")) { ++ os_v = realm_options_ad_specific (options, "os-version"); ++ if (os_v != NULL && !g_str_equal (os_v, "")) { + g_ptr_array_add (args, "--os-version"); +- g_ptr_array_add (args, (gpointer)os); ++ g_ptr_array_add (args, (gpointer)os_v); + } + + switch (cred->type) { +diff --git a/service/realm-options.c b/service/realm-options.c +index d42eb7c..4ebd6c0 100644 +--- a/service/realm-options.c ++++ b/service/realm-options.c +@@ -179,7 +179,7 @@ realm_options_computer_name (GVariant *options, + g_free (section); + } + +- return g_strdup (computer_name); ++ return computer_name; + } + + const gchar * +@@ -197,22 +197,20 @@ realm_options_ad_specific (GVariant *options, + value = realm_settings_value ("active-directory", option_name); + } + +- return g_strdup (value); ++ return value; + } + + gboolean realm_option_use_ldaps (GVariant *options) + { +- gchar *use_ldaps_str; ++ const gchar *use_ldaps_str; + + use_ldaps_str = realm_options_ad_specific (options, + REALM_DBUS_OPTION_USE_LDAPS); + if (use_ldaps_str != NULL + && ( g_ascii_strcasecmp (use_ldaps_str, "True") == 0 + || g_ascii_strcasecmp (use_ldaps_str, "Yes") == 0)) { +- g_free (use_ldaps_str); + return TRUE; + } +- g_free (use_ldaps_str); + + return FALSE; + } +-- +2.26.2 + diff --git a/SOURCES/0005-tools-add-use-ldaps-option-for-discover-join-and-lea.patch b/SOURCES/0005-tools-add-use-ldaps-option-for-discover-join-and-lea.patch new file mode 100644 index 0000000..aaa8648 --- /dev/null +++ b/SOURCES/0005-tools-add-use-ldaps-option-for-discover-join-and-lea.patch @@ -0,0 +1,305 @@ +From 13f302652f6069490dfde41dd33e5aaa17efa5e7 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 17:22:13 +0100 +Subject: [PATCH 5/6] tools: add --use-ldaps option for discover, join and + leave + +Add --use-ldaps option to the realm command to be able to ask the realmd +service to use ldaps where possible. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1826964 +--- + doc/manual/realm.xml | 34 ++++++++++++++++++++++++++++++++++ + doc/manual/realmd.conf.xml | 21 +++++++++++++++++++++ + tools/realm-client.c | 2 ++ + tools/realm-client.h | 1 + + tools/realm-discover.c | 7 ++++++- + tools/realm-join.c | 6 +++++- + tools/realm-leave.c | 15 +++++++++++---- + 7 files changed, 80 insertions(+), 6 deletions(-) + +diff --git a/doc/manual/realm.xml b/doc/manual/realm.xml +index e5d4608..01af62e 100644 +--- a/doc/manual/realm.xml ++++ b/doc/manual/realm.xml +@@ -134,6 +134,11 @@ $ realm discover domain.example.com + Possible values include samba or + adcli. + ++ ++ ++ See option description in ++ . ++ + + + +@@ -276,6 +281,30 @@ $ realm join --user=admin --computer-ou=OU=Special domain.example.com + principal besides the AD default user principal can be + set. + ++ ++ ++ Use the ldaps port when connecting to AD ++ where possible. In general this option is not needed ++ because realmd itself only read ++ public information from the Active Directory domain ++ controller which is available anonymously. The ++ supported membership software products will use ++ encrypted connections protected with GSS-SPNEGO/GSSAPI ++ which offers a comparable level of security than ldaps. ++ This option is only needed if the standard LDAP port ++ (389/tcp) is blocked by a firewall and only the LDAPS ++ port (636/tcp) is available. ++ ++ If this option is set to ++ yes realmd ++ will use the ldaps port when reading the rootDSE and ++ call the adcli membership software ++ with the option . The Samba ++ base membership currently offers only deprecated ways ++ to enable ldaps. Support will be added in ++ realmd when a new way is available. ++ ++ + + + +@@ -326,6 +355,11 @@ $ realm leave domain.example.com + with when leaving the realm. You will be prompted for a + password. Implies . + ++ ++ ++ See option description in ++ . ++ + + + +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index 97d2e8d..72b706c 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -141,6 +141,27 @@ domain.example.com + + + ++ ++ ++ Use the ldaps port when connecting to AD where possible. ++ In general this option is not needed because realmd ++ itself only read public information from the Active Directory domain ++ controller which is available anonymously. The supported membership ++ software products will use encrypted connections protected with ++ GSS-SPNEGO/GSSAPI which offers a comparable level of security than ++ ldaps. This option is only needed if the standard LDAP port (389/tcp) ++ is blocked by a firewall and only the LDAPS port (636/tcp) is ++ available. ++ ++ If this option is set to yes ++ realmd will use the ldaps port when reading the ++ rootDSE and call the adcli membership software with ++ the option . The Samba base membership ++ currently offers only deprecated ways to enable ldaps. Support will be ++ added in realmd when a new way is available. ++ ++ ++ + + + (see below) +diff --git a/tools/realm-client.c b/tools/realm-client.c +index 2f102db..c386e64 100644 +--- a/tools/realm-client.c ++++ b/tools/realm-client.c +@@ -353,6 +353,7 @@ realm_client_get_provider (RealmClient *self) + GList * + realm_client_discover (RealmClient *self, + const gchar *string, ++ gboolean use_ldaps, + const gchar *client_software, + const gchar *server_software, + const gchar *membership_software, +@@ -381,6 +382,7 @@ realm_client_discover (RealmClient *self, + options = realm_build_options (REALM_DBUS_OPTION_CLIENT_SOFTWARE, client_software, + REALM_DBUS_OPTION_SERVER_SOFTWARE, server_software, + REALM_DBUS_OPTION_MEMBERSHIP_SOFTWARE, membership_software, ++ REALM_DBUS_OPTION_USE_LDAPS, use_ldaps ? "True" : "False", + NULL); + + /* Start actual operation */ +diff --git a/tools/realm-client.h b/tools/realm-client.h +index 5ecf2de..e9e50cd 100644 +--- a/tools/realm-client.h ++++ b/tools/realm-client.h +@@ -40,6 +40,7 @@ RealmDbusProvider * realm_client_get_provider (RealmClien + + GList * realm_client_discover (RealmClient *self, + const gchar *string, ++ gboolean use_ldaps, + const gchar *client_software, + const gchar *server_software, + const gchar *membership_software, +diff --git a/tools/realm-discover.c b/tools/realm-discover.c +index 8dde4ed..c0acd79 100644 +--- a/tools/realm-discover.c ++++ b/tools/realm-discover.c +@@ -116,6 +116,7 @@ perform_discover (RealmClient *client, + const gchar *string, + gboolean all, + gboolean name_only, ++ gboolean use_ldaps, + const gchar *server_software, + const gchar *client_software, + const gchar *membership_software) +@@ -127,7 +128,7 @@ perform_discover (RealmClient *client, + GList *realms; + GList *l; + +- realms = realm_client_discover (client, string, client_software, ++ realms = realm_client_discover (client, string, use_ldaps, client_software, + server_software, membership_software, + REALM_DBUS_REALM_INTERFACE, NULL, &error); + +@@ -173,6 +174,7 @@ realm_discover (RealmClient *client, + GError *error = NULL; + gboolean arg_all = FALSE; + gboolean arg_name_only = FALSE; ++ gboolean arg_use_ldaps = FALSE; + gint result = 0; + gint ret; + gint i; +@@ -183,6 +185,7 @@ realm_discover (RealmClient *client, + { "client-software", 0, 0, G_OPTION_ARG_STRING, &arg_client_software, N_("Use specific client software"), NULL }, + { "membership-software", 0, 0, G_OPTION_ARG_STRING, &arg_membership_software, N_("Use specific membership software"), NULL }, + { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software, N_("Use specific server software"), NULL }, ++ { "use-ldaps", 0, 0, G_OPTION_ARG_NONE, &arg_use_ldaps, N_("Use ldaps to connect to LDAP"), NULL }, + { NULL, } + }; + +@@ -200,6 +203,7 @@ realm_discover (RealmClient *client, + } else if (argc == 1) { + result = perform_discover (client, NULL, arg_all, + arg_name_only, ++ arg_use_ldaps, + arg_server_software, + arg_client_software, + arg_membership_software); +@@ -209,6 +213,7 @@ realm_discover (RealmClient *client, + for (i = 1; i < argc; i++) { + ret = perform_discover (client, argv[i], arg_all, + arg_name_only, ++ arg_use_ldaps, + arg_server_software, + arg_client_software, + arg_membership_software); +diff --git a/tools/realm-join.c b/tools/realm-join.c +index 249f502..dbe6197 100644 +--- a/tools/realm-join.c ++++ b/tools/realm-join.c +@@ -179,6 +179,7 @@ typedef struct { + gchar *user_principal; + gboolean automatic_id_mapping_set; + gboolean automatic_id_mapping; ++ gboolean use_ldaps; + } RealmJoinArgs; + + static void +@@ -218,7 +219,7 @@ perform_join (RealmClient *client, + GList *realms; + gint ret; + +- realms = realm_client_discover (client, string, args->client_software, ++ realms = realm_client_discover (client, string, args->use_ldaps, args->client_software, + args->server_software, args->membership_software, + REALM_DBUS_KERBEROS_MEMBERSHIP_INTERFACE, + &had_mismatched, &error); +@@ -247,6 +248,7 @@ perform_join (RealmClient *client, + REALM_DBUS_OPTION_OS_VERSION, args->os_version, + REALM_DBUS_OPTION_MEMBERSHIP_SOFTWARE, args->membership_software, + REALM_DBUS_OPTION_USER_PRINCIPAL, args->user_principal, ++ REALM_DBUS_OPTION_USE_LDAPS, args->use_ldaps ? "True" : "False", + args->automatic_id_mapping_set ? + REALM_DBUS_OPTION_AUTOMATIC_ID_MAPPING : NULL, + args->automatic_id_mapping, +@@ -310,6 +312,8 @@ realm_join (RealmClient *client, + N_("User name to use for enrollment"), NULL }, + { "user-principal", 0, 0, G_OPTION_ARG_STRING, &args.user_principal, + N_("Set the user principal for the computer account"), NULL }, ++ { "use-ldaps", 0, 0, G_OPTION_ARG_NONE, &args.use_ldaps, ++ N_("Use ldaps to connect to LDAP"), NULL }, + { NULL, } + }; + +diff --git a/tools/realm-leave.c b/tools/realm-leave.c +index 45a9c46..c88a110 100644 +--- a/tools/realm-leave.c ++++ b/tools/realm-leave.c +@@ -185,6 +185,7 @@ perform_deconfigure (RealmClient *client, + + static int + perform_user_leave (RealmClient *client, ++ gboolean use_ldaps, + RealmDbusKerberosMembership *membership, + const gchar *user_name) + { +@@ -201,7 +202,8 @@ perform_user_leave (RealmClient *client, + return 1; + } + +- options = realm_build_options(NULL, NULL); ++ options = realm_build_options (REALM_DBUS_OPTION_USE_LDAPS, use_ldaps ? "True" : "False", ++ NULL); + ret = call_leave (membership, credentials, options, &error); + + if (error != NULL) +@@ -213,6 +215,7 @@ perform_user_leave (RealmClient *client, + static int + perform_leave (RealmClient *client, + const gchar *realm_name, ++ gboolean use_ldaps, + gboolean remove, + const gchar *user_name, + const gchar *client_software, +@@ -239,7 +242,8 @@ perform_leave (RealmClient *client, + if (!remove) + ret = perform_deconfigure (client, realm); + else +- ret = perform_user_leave (client, membership, user_name); ++ ret = perform_user_leave (client, use_ldaps, membership, ++ user_name); + + g_object_unref (membership); + g_object_unref (realm); +@@ -259,6 +263,7 @@ realm_leave (RealmClient *client, + gchar *arg_server_software = NULL; + GError *error = NULL; + const gchar *realm_name; ++ gboolean arg_use_ldaps = FALSE; + gint ret = 0; + + GOptionEntry option_entries[] = { +@@ -268,6 +273,7 @@ realm_leave (RealmClient *client, + { "server-software", 0, 0, G_OPTION_ARG_STRING, &arg_server_software, + N_("Use specific server software"), NULL }, + { "user", 'U', 0, G_OPTION_ARG_STRING, &arg_user, N_("User name to use for removal"), NULL }, ++ { "use-ldaps", 0, 0, G_OPTION_ARG_NONE, &arg_use_ldaps, N_("Use ldaps to connect to LDAP"), NULL }, + { NULL, } + }; + +@@ -283,8 +289,9 @@ realm_leave (RealmClient *client, + + } else { + realm_name = argc < 2 ? NULL : argv[1]; +- ret = perform_leave (client, realm_name, arg_remove, arg_user, +- arg_client_software, arg_server_software); ++ ret = perform_leave (client, realm_name, arg_use_ldaps, ++ arg_remove, arg_user, arg_client_software, ++ arg_server_software); + } + + g_free (arg_user); +-- +2.26.2 + diff --git a/SOURCES/0006-ldap-generate-proper-ldap-uri-for-IPv6-addresses.patch b/SOURCES/0006-ldap-generate-proper-ldap-uri-for-IPv6-addresses.patch new file mode 100644 index 0000000..f79c86e --- /dev/null +++ b/SOURCES/0006-ldap-generate-proper-ldap-uri-for-IPv6-addresses.patch @@ -0,0 +1,56 @@ +From 8cddf81199e96c7edc701bcb7ca782d7bcddbddd Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 30 Oct 2020 19:24:40 +0100 +Subject: [PATCH 6/6] ldap: generate proper ldap uri for IPv6 addresses + +When using IPv6 addresses the address must be put into brackets. + +Resolves: https://gitlab.freedesktop.org/realmd/realmd/-/issues/23 +--- + service/realm-ldap.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/service/realm-ldap.c b/service/realm-ldap.c +index 28c5c8a..2076d1e 100644 +--- a/service/realm-ldap.c ++++ b/service/realm-ldap.c +@@ -190,6 +190,7 @@ realm_ldap_connect_anonymous (GSocketAddress *address, + LdapSource *ls; + gchar *addrname; + GInetSocketAddress *inet; ++ GSocketFamily family; + struct berval cred; + Sockbuf *sb = NULL; + gsize native_len; +@@ -204,6 +205,7 @@ realm_ldap_connect_anonymous (GSocketAddress *address, + inet = G_INET_SOCKET_ADDRESS (address); + addrname = g_inet_address_to_string (g_inet_socket_address_get_address (inet)); + port = g_inet_socket_address_get_port (inet); ++ family = g_inet_address_get_family (g_inet_socket_address_get_address (inet)); + if (port == 0) + port = 389; + +@@ -239,9 +241,17 @@ realm_ldap_connect_anonymous (GSocketAddress *address, + if (!g_unix_set_fd_nonblocking (ls->sock, FALSE, NULL)) + g_warning ("couldn't set to blocking"); + +- url = g_strdup_printf ("%s://%s:%d", +- use_ldaps ? "ldaps" : "ldap", +- addrname, port); ++ if (family == G_SOCKET_FAMILY_IPV4) { ++ url = g_strdup_printf ("%s://%s:%d", ++ use_ldaps ? "ldaps" : "ldap", ++ addrname, port); ++ } else if (family == G_SOCKET_FAMILY_IPV6) { ++ url = g_strdup_printf ("%s://[%s]:%d", ++ use_ldaps ? "ldaps" : "ldap", ++ addrname, port); ++ } else { ++ url = NULL; ++ } + rc = ldap_init_fd (ls->sock, 1, url, &ls->ldap); + g_free (url); + +-- +2.26.2 + diff --git a/SPECS/realmd.spec b/SPECS/realmd.spec index 86db8b5..e97d86f 100644 --- a/SPECS/realmd.spec +++ b/SPECS/realmd.spec @@ -1,6 +1,6 @@ Name: realmd Version: 0.16.3 -Release: 19%{?dist} +Release: 20%{?dist} Summary: Kerberos realm enrollment service License: LGPLv2+ URL: http://cgit.freedesktop.org/realmd/realmd/ @@ -47,6 +47,19 @@ Patch22: 0001-service-use-net-ads-join-with-k-for-user-join-as-wel.patch # rhbz#1867912 - realm command to use option like dnshostname=fqdn Patch23: 0001-service-use-additional-dns-hostnames-with-net-ads-jo.patch +# rhbz#1791016 - realmd should handle default_realm in krb5.conf +Patch24: 0001-Kerberos-add-default_domain-and-udp_preference_limit.patch + +# rhbz#1826964 - [RFE] Enable LDAPS functionality in realmd join +Patch25: 0001-tools-Update-the-usage-help-text-of-the-realm-comman.patch +Patch26: 0001-Use-startTLS-with-FreeIPA.patch +Patch27: 0001-service-add-REALM_DBUS_OPTION_USE_LDAPS-and-realm_ge.patch +Patch28: 0002-service-allow-to-use-ldaps-for-rootDSE-lookup.patch +Patch29: 0003-service-add-ldaps-support-when-using-adcli.patch +Patch30: 0004-service-do-not-copy-option-values-to-avoid-memory-le.patch +Patch31: 0005-tools-add-use-ldaps-option-for-discover-join-and-lea.patch +Patch32: 0006-ldap-generate-proper-ldap-uri-for-IPv6-addresses.patch + BuildRequires: gcc BuildRequires: automake BuildRequires: autoconf @@ -114,6 +127,12 @@ make install DESTDIR=%{buildroot} %doc ChangeLog %changelog +* Thu Nov 05 2020 Sumit Bose - 0.16.3-20 +- realmd should handle default_realm in krb5.conf + Resolves: rhbz#1791016 +- [RFE] Enable LDAPS functionality in realmd join + Resolves: rhbz#1826964 + * Thu Aug 13 2020 Sumit Bose - 0.16.3-19 - Realm join fails with error 'Failed to join domain: failed to lookup DC info ...'