diff options
author | GoliathLabs | 2020-06-22 14:11:40 +0200 |
---|---|---|
committer | GoliathLabs | 2020-06-22 14:11:40 +0200 |
commit | f440bcd34523ad4b2f8a1cd7d3d70c6eb14f9b6c (patch) | |
tree | ec3f8bd39172114b8a37e7dafc5aa5b9c6e48e12 | |
parent | 3efd20d51255057cecd2d5b8852d923f0ad1d3a8 (diff) | |
download | aur-f440bcd34523ad4b2f8a1cd7d3d70c6eb14f9b6c.tar.gz |
Updated: patches
34 files changed, 4682 insertions, 7 deletions
@@ -1,7 +1,7 @@ pkgbase = realmd pkgdesc = DBus service for joining hosts to Active Directory and FreeIPA realms pkgver = 0.16.3 - pkgrel = 1 + pkgrel = 2 url = https://freedesktop.org/software/realmd/ arch = i686 arch = x86_64 @@ -21,9 +21,73 @@ pkgbase = realmd optdepends = samba: traditional Active Directory client source = https://www.freedesktop.org/software/realmd/releases/realmd-0.16.3.tar.gz source = https://www.freedesktop.org/software/realmd/releases/realmd-0.16.3.tar.gz.sig + source = 0001-Add-missing-xsl-file-to-Makefile.am.patch + source = 0001-doc-make-sure-cross-reference-ids-are-predictable.patch + source = 0001-Find-NetBIOS-name-in-keytab-while-leaving.patch + source = 0001-Fix-issues-found-by-Coverity.patch + source = 0001-Fix-man-page-reference-in-systemd-service-file.patch + source = 0001-IPA-do-not-call-sssd-enable-logins.patch + source = 0001-Kerberos-fall-back-to-tcp-SRV-lookup.patch + source = 0001-LDAP-don-t-close-LDAP-socket-twice.patch + source = 0001-Remove-support-for-deprecated-gtester-format.patch + source = 0001-service-Add-nss-and-pam-sssd.conf-services-after-joi.patch + source = 0001-service-Add-pam-and-nss-services-in-realm_sssd_confi.patch + source = 0001-Set-NEWEST-flag-when-resolving-packages-with-Package.patch + source = 0001-switch-to-authselect.patch + source = 0001-tests-ignore-order-in-test_update_domain.patch + source = 0001-tests-run-tests-with-python3.patch + source = 0001-Use-current-idmap-options-for-smb.conf.patch + source = 0002-Change-qualified-names-default-for-IPA.patch + source = 0002-configure-do-not-inherit-DISTRO-from-the-environment.patch + source = 0002-tools-remove-duplicated-va_start.patch + source = 0003-discover-try-to-get-domain-name-from-hostname.patch + source = 0003-doc-extend-user-principal-section.patch + source = 0003-service-remove-dead-code.patch + source = 0004-doc-fix-discover-name-only.patch + source = 0004-service-check-return-value-of-fcntl.patch + source = 0005-doc-add-see-also-to-man-pages.patch + source = 0005-service-avoid-dereference-of-a-null-pointer.patch + source = 0006-doc-extend-description-of-config-handling.patch + source = 0006-service-avoid-dereferencing-a-NULL-pointer.patch + source = 0007-service-use-kerberos-method-secrets-and-keytab.patch + source = computer-ou.patch + source = duplicate-test-path.patch + source = install-diagnostic.patch validpgpkeys = C0F67099B808FB063E2C81117BFB1108D92765AF sha256sums = d8943f66a2a666fee8be026d82a66904c0a5125aab7ef74504456ce269687dda sha256sums = SKIP + sha256sums = 6db7704e9342efd801ec24949f1002a8e26ac67c4f04638ca51977940ef3ac1d + sha256sums = ea5a2b311f76ebfea0c88c2cf333c007ea5db32316935bbd5dd6883450edd5a3 + sha256sums = faffd409b53b46c67d4f776e252e49025a63f9963796e12ef6f487d416310958 + sha256sums = 262764b9acbe2c84348d8f9a7b759bd08d10c04ef779c4f390c3f6650ef6d96a + sha256sums = cb376d3b6e90be4aa84a1d42d4d395f5a8f0aedfbf719277e549f08928e3a985 + sha256sums = 2c79e27e504d24b22a06bce567a3aa96348e1bb0682db4e042c96165f799c500 + sha256sums = a56748ad07b75e346dccedead2ec50053bfe3c3084f9c804b8fae6d961977236 + sha256sums = 65f4b0d4d8f51e55e9adc5b8d2896a3abf159f311fc9d3a99ae2df906181e04d + sha256sums = 440ae6ac9d7b4e08440dc1382cfc243e28d69dfcf010f8335e3699c40eda9d63 + sha256sums = f25dd08914fb493d8b8e6ff5bd44d8398d0498116a874effb314f2cd6e26446d + sha256sums = 6b3a36fdb36655940194ec0b53dcec7e97a4a79a0427863c8a905ad67c9c1714 + sha256sums = 512def4faeaa0cd283161fbb05f2bba16bd2d2373d681a99248e78ede958b0fe + sha256sums = 47d7a73329a7dbb4754ab7bd3ed436799cbd21b4f555a0a0ab50c27944817335 + sha256sums = f408dc7c2263b01e97b66ec068fc48ba5597a3d13e55a60d26008ae309a7787d + sha256sums = f3a584270e3e0d6a76c9aeb1dbf078c864b78d948c3277d6899b0b40f8a58030 + sha256sums = 8346081c5a8c1efbd5c33890e530fdd84906d394737a1a2cd5a8e2f5fb4f64b6 + sha256sums = d93b5ba71204cbcb70bab02bf990068d04d4be1888f23c251e2c512c8bb0caeb + sha256sums = 86640fbf9a7f5d7606529584902dcee96fd13cb50c673d785ec04ab525364119 + sha256sums = 1daa4159e6fe20131111112b6127ca823b2355a2ef7895840959168af00a5483 + sha256sums = e4922a6c16c7fd41a2903a5857876c679fd9c257569fe35a4b08ffaabfd016e7 + sha256sums = eeca4747df151ab624feeefdeda4274da3703681074f21789a69a2eb73da9ca4 + sha256sums = d594af102566775b4bb0cf59554c69c20721d7db935ac69a3fbc86f28f1226bc + sha256sums = 6fc569eb9641503352fb5f19cb2c5dd16a0e8c888c7e4ea652b55a8e9e69ff6e + sha256sums = a962c7b5f3cf2dba39d16195ad7bb1a9d2db9d2292d74d6e65879c220791b871 + sha256sums = 3ef0438e83ec4cefba482435d8c22d69bbb8e93b24032a83ad139481ecbda817 + sha256sums = 76e511fe1033f19c8499b4edcc3410eede375ceff968f4ac08cd6333c7e33c2a + sha256sums = 77bad53ed4f36ae51f3c81b0195fb898fa6c9f79a377550f51551423c12dcff0 + sha256sums = 682a5f7af3e4bdc0bfa5ed2f7ad654e9d311666995520ae2997898edb9264bdc + sha256sums = 950d252020635b4415551fcf9fcacc06ade8497a639b25661b138341b327ea24 + sha256sums = 5e43d034348bdf3cb3f06ebd56d811b3427e43f9220fee9a104f50d3972cb5cd + sha256sums = a659dfcf8e4f91123832ae89b9ac92bbcc9ea8d90a698533ca25dff9ec610d90 + sha256sums = e49fc613594d4fb540f0a562778e2fd45711548cbe3dc9769f5aa0773de16319 pkgname = realmd diff --git a/0001-Add-missing-xsl-file-to-Makefile.am.patch b/0001-Add-missing-xsl-file-to-Makefile.am.patch new file mode 100644 index 000000000000..33f26e6be15d --- /dev/null +++ b/0001-Add-missing-xsl-file-to-Makefile.am.patch @@ -0,0 +1,27 @@ +From 81b5e3478269ea47d66ddb98f7cbebd06fe950e6 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 2 Aug 2019 13:18:37 +0200 +Subject: [PATCH 1/7] Add missing xsl file to Makefile.am + +In commit 4f3c02dc14300c0b8e51a55d627c57f73c108f64 it was forgotten to +add the new file devhelp2.xsl to the Makefile to make sure it is +include in the tar ball. +--- + doc/manual/Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am +index 39e1581..8b33fdd 100644 +--- a/doc/manual/Makefile.am ++++ b/doc/manual/Makefile.am +@@ -37,6 +37,7 @@ MANUAL_XSLT = \ + doc/manual/gdbus-fix-bugs.xsl \ + doc/manual/gtk-doc.xsl \ + doc/manual/version-greater-or-equal.xsl \ ++ doc/manual/devhelp2.xsl \ + $(NULL) + + EXTRA_DIST += \ +-- +2.25.1 + diff --git a/0001-Find-NetBIOS-name-in-keytab-while-leaving.patch b/0001-Find-NetBIOS-name-in-keytab-while-leaving.patch new file mode 100644 index 000000000000..894fe9371948 --- /dev/null +++ b/0001-Find-NetBIOS-name-in-keytab-while-leaving.patch @@ -0,0 +1,168 @@ +From b11d891a50c2f70e3c02b880e0199583b8df186c Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Thu, 31 May 2018 16:16:08 +0200 +Subject: [PATCH] Find NetBIOS name in keytab while leaving + +If realmd is used with Samba as membership software, i.e. Samba's net +utility, the NetBIOS name must be known when leaving a domain. The most +reliable way to find it is by searching the keytab for NAME$@REALM type +entries and use the NAME as the NetBIOS name. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1370457 +--- + service/realm-kerberos.c | 64 ++++++++++++++++++++++++++++++++++++ + service/realm-kerberos.h | 2 ++ + service/realm-samba-enroll.c | 17 ++++++++-- + 3 files changed, 80 insertions(+), 3 deletions(-) + +diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c +index 54d1ed7..d6d109f 100644 +--- a/service/realm-kerberos.c ++++ b/service/realm-kerberos.c +@@ -1130,3 +1130,67 @@ realm_kerberos_flush_keytab (const gchar *realm_name, + return ret; + + } ++ ++gchar * ++realm_kerberos_get_netbios_name_from_keytab (const gchar *realm_name) ++{ ++ krb5_error_code code; ++ krb5_keytab keytab = NULL; ++ krb5_context ctx; ++ krb5_kt_cursor cursor = NULL; ++ krb5_keytab_entry entry; ++ krb5_principal realm_princ = NULL; ++ gchar *princ_name = NULL; ++ gchar *netbios_name = NULL; ++ krb5_data *name_data; ++ ++ code = krb5_init_context (&ctx); ++ if (code != 0) { ++ return NULL; ++ } ++ ++ princ_name = g_strdup_printf ("user@%s", realm_name); ++ code = krb5_parse_name (ctx, princ_name, &realm_princ); ++ g_free (princ_name); ++ ++ if (code == 0) { ++ code = krb5_kt_default (ctx, &keytab); ++ } ++ ++ if (code == 0) { ++ code = krb5_kt_start_seq_get (ctx, keytab, &cursor); ++ } ++ ++ if (code == 0) { ++ while (!krb5_kt_next_entry (ctx, keytab, &entry, &cursor) && netbios_name == NULL) { ++ if (krb5_realm_compare (ctx, realm_princ, entry.principal)) { ++ name_data = krb5_princ_component (ctx, entry.principal, 0); ++ if (name_data != NULL ++ && name_data->length > 0 ++ && name_data->data[name_data->length - 1] == '$') { ++ netbios_name = g_strndup (name_data->data, name_data->length - 1); ++ if (netbios_name == NULL) { ++ code = krb5_kt_free_entry (ctx, &entry); ++ warn_if_krb5_failed (ctx, code); ++ break; ++ } ++ } ++ } ++ code = krb5_kt_free_entry (ctx, &entry); ++ warn_if_krb5_failed (ctx, code); ++ } ++ } ++ ++ code = krb5_kt_end_seq_get (ctx, keytab, &cursor); ++ warn_if_krb5_failed (ctx, code); ++ ++ code = krb5_kt_close (ctx, keytab); ++ warn_if_krb5_failed (ctx, code); ++ ++ krb5_free_principal (ctx, realm_princ); ++ ++ krb5_free_context (ctx); ++ ++ return netbios_name; ++ ++} +diff --git a/service/realm-kerberos.h b/service/realm-kerberos.h +index 0447e4d..58cfe07 100644 +--- a/service/realm-kerberos.h ++++ b/service/realm-kerberos.h +@@ -88,6 +88,8 @@ gchar * realm_kerberos_format_login (RealmKerberos *self, + gboolean realm_kerberos_flush_keytab (const gchar *realm_name, + GError **error); + ++gchar * realm_kerberos_get_netbios_name_from_keytab (const gchar *realm_name); ++ + const gchar * realm_kerberos_get_name (RealmKerberos *self); + + const gchar * realm_kerberos_get_realm_name (RealmKerberos *self); +diff --git a/service/realm-samba-enroll.c b/service/realm-samba-enroll.c +index 76e7b79..f5edca3 100644 +--- a/service/realm-samba-enroll.c ++++ b/service/realm-samba-enroll.c +@@ -85,7 +85,8 @@ static JoinClosure * + join_closure_init (GTask *task, + RealmDisco *disco, + GVariant *options, +- GDBusMethodInvocation *invocation) ++ GDBusMethodInvocation *invocation, ++ gboolean do_join) + { + JoinClosure *join; + gchar *workgroup; +@@ -93,6 +94,7 @@ join_closure_init (GTask *task, + int temp_fd; + const gchar *explicit_computer_name = NULL; + const gchar *authid = NULL; ++ gchar *name_from_keytab = NULL; + + join = g_new0 (JoinClosure, 1); + join->disco = realm_disco_ref (disco); +@@ -106,6 +108,14 @@ join_closure_init (GTask *task, + else if (disco->explicit_netbios) + authid = disco->explicit_netbios; + ++ /* try to get the NetBIOS name from the keytab while leaving the domain */ ++ if (explicit_computer_name == NULL && !do_join) { ++ name_from_keytab = realm_kerberos_get_netbios_name_from_keytab(disco->kerberos_realm); ++ if (name_from_keytab != NULL) { ++ authid = name_from_keytab; ++ } ++ } ++ + join->config = realm_ini_config_new (REALM_INI_NO_WATCH | REALM_INI_PRIVATE); + realm_ini_config_set (join->config, REALM_SAMBA_CONFIG_GLOBAL, + "security", "ads", +@@ -151,6 +161,7 @@ join_closure_init (GTask *task, + g_warning ("Couldn't create temp file in: %s", g_get_tmp_dir ()); + } + ++ g_free (name_from_keytab); + return join; + } + +@@ -393,7 +404,7 @@ realm_samba_enroll_join_async (RealmDisco *disco, + g_return_if_fail (cred != NULL); + + task = g_task_new (NULL, NULL, callback, user_data); +- join = join_closure_init (task, disco, options, invocation); ++ join = join_closure_init (task, disco, options, invocation, TRUE); + explicit_computer_name = realm_options_computer_name (options, disco->domain_name); + if (explicit_computer_name != NULL) { + realm_diagnostics_info (invocation, "Joining using a manual netbios name: %s", +@@ -462,7 +473,7 @@ realm_samba_enroll_leave_async (RealmDisco *disco, + JoinClosure *join; + + task = g_task_new (NULL, NULL, callback, user_data); +- join = join_closure_init (task, disco, options, invocation); ++ join = join_closure_init (task, disco, options, invocation, FALSE); + + switch (cred->type) { + case REALM_CREDENTIAL_PASSWORD: +-- +2.17.1 + diff --git a/0001-Fix-issues-found-by-Coverity.patch b/0001-Fix-issues-found-by-Coverity.patch new file mode 100644 index 000000000000..abb678220f48 --- /dev/null +++ b/0001-Fix-issues-found-by-Coverity.patch @@ -0,0 +1,42 @@ +From 1831748847715a13f0cc911a9a491eb8614d6682 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Tue, 14 Aug 2018 14:09:48 +0200 +Subject: [PATCH 1/3] Fix issues found by Coverity + +--- + service/realm-kerberos.c | 5 ++++- + service/realm-packages.c | 2 +- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c +index d6d109f..252e256 100644 +--- a/service/realm-kerberos.c ++++ b/service/realm-kerberos.c +@@ -980,7 +980,10 @@ realm_kerberos_set_details (RealmKerberos *self, + if (name == NULL) + break; + value = va_arg (va, const gchar *); +- g_return_if_fail (value != NULL); ++ if (value == NULL) { ++ va_end (va); ++ g_return_if_reached (); ++ } + + values[0] = g_variant_new_string (name); + values[1] = g_variant_new_string (value); +diff --git a/service/realm-packages.c b/service/realm-packages.c +index 9a6984c..5976439 100644 +--- a/service/realm-packages.c ++++ b/service/realm-packages.c +@@ -567,7 +567,7 @@ lookup_required_files_and_packages (const gchar **package_sets, + g_ptr_array_add (packages, NULL); + *result_packages = (gchar **)g_ptr_array_free (packages, FALSE); + } else { +- g_ptr_array_free (files, TRUE); ++ g_ptr_array_free (packages, TRUE); + } + + if (result_files) { +-- +2.17.1 + diff --git a/0001-Fix-man-page-reference-in-systemd-service-file.patch b/0001-Fix-man-page-reference-in-systemd-service-file.patch new file mode 100644 index 000000000000..fe466209f1b2 --- /dev/null +++ b/0001-Fix-man-page-reference-in-systemd-service-file.patch @@ -0,0 +1,24 @@ +From e8d9d5e9817627dcf208ac742debcc9dc320752d Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Wed, 27 Jul 2016 19:06:29 +0200 +Subject: [PATCH] Fix man page reference in systemd service file + +--- + dbus/realmd.service.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dbus/realmd.service.in b/dbus/realmd.service.in +index b3bcf7a..64c1090 100644 +--- a/dbus/realmd.service.in ++++ b/dbus/realmd.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Realm and Domain Configuration +-Documentation=man:realmd(8) ++Documentation=man:realm(8) + + [Service] + Type=dbus +-- +2.7.4 + diff --git a/0001-IPA-do-not-call-sssd-enable-logins.patch b/0001-IPA-do-not-call-sssd-enable-logins.patch new file mode 100644 index 000000000000..01fdef86b305 --- /dev/null +++ b/0001-IPA-do-not-call-sssd-enable-logins.patch @@ -0,0 +1,62 @@ +From 373f2e03736dfd87d50f02208b99d462cf34d891 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Thu, 27 Sep 2018 13:04:47 +0200 +Subject: [PATCH] IPA: do not call sssd-enable-logins + +It is expected that ipa-client-install will do all PAM and NSS +configuration. To avoid changing IPA default realmd will not try to +update the related configuration. +--- + service/realm-sssd-ipa.c | 24 +----------------------- + 1 file changed, 1 insertion(+), 23 deletions(-) + +diff --git a/service/realm-sssd-ipa.c b/service/realm-sssd-ipa.c +index 5029f6b..70f8b0e 100644 +--- a/service/realm-sssd-ipa.c ++++ b/service/realm-sssd-ipa.c +@@ -109,41 +109,19 @@ enroll_closure_free (gpointer data) + g_free (enroll); + } + +-static void +-on_enable_nss_done (GObject *source, +- GAsyncResult *result, +- gpointer user_data) +-{ +- GTask *task = G_TASK (user_data); +- GError *error = NULL; +- gint status; +- +- status = realm_command_run_finish (result, NULL, &error); +- if (error == NULL && status != 0) +- g_set_error (&error, REALM_ERROR, REALM_ERROR_INTERNAL, +- _("Enabling SSSD in nsswitch.conf and PAM failed.")); +- if (error != NULL) +- g_task_return_error (task, error); +- else +- g_task_return_boolean (task, TRUE); +- g_object_unref (task); +-} +- + static void + on_restart_done (GObject *source, + GAsyncResult *result, + gpointer user_data) + { + GTask *task = G_TASK (user_data); +- EnrollClosure *enroll = g_task_get_task_data (task); + RealmSssd *sssd = g_task_get_source_object (task); + GError *error = NULL; + + realm_service_enable_and_restart_finish (result, &error); + if (error == NULL) { + realm_sssd_update_properties (sssd); +- realm_command_run_known_async ("sssd-enable-logins", NULL, enroll->invocation, +- on_enable_nss_done, g_object_ref (task)); ++ g_task_return_boolean (task, TRUE); + } else { + g_task_return_error (task, error); + } +-- +2.17.1 + diff --git a/0001-Kerberos-fall-back-to-tcp-SRV-lookup.patch b/0001-Kerberos-fall-back-to-tcp-SRV-lookup.patch new file mode 100644 index 000000000000..a61b602a2720 --- /dev/null +++ b/0001-Kerberos-fall-back-to-tcp-SRV-lookup.patch @@ -0,0 +1,112 @@ +From 6f0aa79c3e8dd93e723f29bf46e1b8b14403254f Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Mon, 5 Dec 2016 18:25:44 +0100 +Subject: [PATCH] Kerberos: fall back to tcp SRV lookup + +--- + service/realm-kerberos-provider.c | 48 +++++++++++++++++++++++++++++++-------- + 1 file changed, 39 insertions(+), 9 deletions(-) + +diff --git a/service/realm-kerberos-provider.c b/service/realm-kerberos-provider.c +index 2b3a0f8..1477ae8 100644 +--- a/service/realm-kerberos-provider.c ++++ b/service/realm-kerberos-provider.c +@@ -19,6 +19,7 @@ + #include "realm-kerberos-provider.h" + + #include <errno.h> ++#include <string.h> + + struct _RealmKerberosProvider { + RealmProvider parent; +@@ -38,28 +39,54 @@ realm_kerberos_provider_init (RealmKerberosProvider *self) + + } + ++typedef struct { ++ gchar *name; ++ const char *prot; ++} NameProtPair; ++ ++static void ++name_prot_pair_free (gpointer data) ++{ ++ NameProtPair *name_prot_pair = data; ++ g_free (name_prot_pair->name); ++ g_free (name_prot_pair); ++} ++ + static void + on_kerberos_discover (GObject *source, + GAsyncResult *result, + gpointer user_data) + { + GTask *task = G_TASK (user_data); +- const gchar *domain = g_task_get_task_data (task); ++ NameProtPair *name_prot_pair = g_task_get_task_data (task); + GError *error = NULL; + RealmDisco *disco; + GList *targets; ++ GResolver *resolver; + + targets = g_resolver_lookup_service_finish (G_RESOLVER (source), result, &error); + if (targets) { + g_list_free_full (targets, (GDestroyNotify)g_srv_target_free); +- disco = realm_disco_new (domain); +- disco->kerberos_realm = g_ascii_strup (domain, -1); ++ disco = realm_disco_new (name_prot_pair->name); ++ disco->kerberos_realm = g_ascii_strup (name_prot_pair->name, -1); + g_task_return_pointer (task, disco, realm_disco_unref); + + } else if (error) { +- g_debug ("Resolving %s failed: %s", domain, error->message); ++ g_debug ("Resolving %s failed: %s", name_prot_pair->name, error->message); + g_error_free (error); +- g_task_return_pointer (task, NULL, NULL); ++ ++ if (strcmp (name_prot_pair->prot, "tcp") == 0) { ++ g_task_return_pointer (task, NULL, NULL); ++ } else { ++ /* Try tcp */ ++ name_prot_pair->prot = "tcp"; ++ resolver = g_resolver_get_default (); ++ g_resolver_lookup_service_async (resolver, "kerberos", name_prot_pair->prot, ++ name_prot_pair->name, ++ g_task_get_cancellable (task), ++ on_kerberos_discover, g_object_ref (task)); ++ g_object_unref (resolver); ++ } + } + + g_object_unref (task); +@@ -76,7 +103,7 @@ realm_kerberos_provider_discover_async (RealmProvider *provider, + GTask *task; + const gchar *software; + GResolver *resolver; +- gchar *name; ++ NameProtPair *name_prot_pair; + + task = g_task_new (provider, NULL, callback, user_data); + +@@ -86,12 +113,15 @@ realm_kerberos_provider_discover_async (RealmProvider *provider, + g_task_return_pointer (task, NULL, NULL); + + } else { +- name = g_hostname_to_ascii (string); ++ name_prot_pair = g_new0 (NameProtPair, 1); ++ name_prot_pair->name = g_hostname_to_ascii (string); ++ name_prot_pair->prot = "udp"; + resolver = g_resolver_get_default (); +- g_resolver_lookup_service_async (resolver, "kerberos", "udp", name, ++ g_resolver_lookup_service_async (resolver, "kerberos", name_prot_pair->prot, ++ name_prot_pair->name, + realm_invocation_get_cancellable (invocation), + on_kerberos_discover, g_object_ref (task)); +- g_task_set_task_data (task, name, g_free); ++ g_task_set_task_data (task, name_prot_pair, name_prot_pair_free); + g_object_unref (resolver); + } + +-- +2.9.3 + diff --git a/0001-LDAP-don-t-close-LDAP-socket-twice.patch b/0001-LDAP-don-t-close-LDAP-socket-twice.patch new file mode 100644 index 000000000000..09e9ccf4760a --- /dev/null +++ b/0001-LDAP-don-t-close-LDAP-socket-twice.patch @@ -0,0 +1,41 @@ +From 895e5b37d14090541480cebcb297846cbd3662ce Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 25 Nov 2016 17:35:11 +0100 +Subject: [PATCH] LDAP: don't close LDAP socket twice + +ldap_destroy() will call close() on the LDAP socket so with an explicit +close() before the file descriptor will be closed twice. Even worse, +since the file descriptor can be reused after the explicit call of +close() by any other thread the close() called from ldap_destroy() might +close a file descriptor used by a different thread as seen e.g. in +https://bugzilla.redhat.com/show_bug.cgi?id=1398522. + +Additionally the patch makes sure that the closed connection cannot be +used again. + +https://bugzilla.redhat.com/show_bug.cgi?id=1398522 +--- + service/realm-ldap.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/service/realm-ldap.c b/service/realm-ldap.c +index 061ed61..59817fb 100644 +--- a/service/realm-ldap.c ++++ b/service/realm-ldap.c +@@ -159,10 +159,11 @@ ldap_source_finalize (GSource *source) + { + LdapSource *ls = (LdapSource *)source; + +- /* Yeah, this is pretty rough, but we don't want blocking here */ +- close (ls->sock); + ldap_destroy (ls->ldap); + ++ ls->sock = -1; ++ ls->ldap = NULL; ++ + if (ls->cancellable) { + g_cancellable_release_fd (ls->cancellable); + g_object_unref (ls->cancellable); +-- +2.9.3 + diff --git a/0001-Remove-support-for-deprecated-gtester-format.patch b/0001-Remove-support-for-deprecated-gtester-format.patch new file mode 100644 index 000000000000..1302a382cce3 --- /dev/null +++ b/0001-Remove-support-for-deprecated-gtester-format.patch @@ -0,0 +1,39 @@ +From 5ae42c176e7bb550fc6cf10f29e75f58c733ae4f Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 2 Aug 2019 12:10:43 +0200 +Subject: [PATCH] Remove support for deprecated gtester format + +Support for the already deprecated gtester format was remove from recent +versions of glib2 but the test still call the tab-gtester conversion +tool. + +This patch removes tab-gtester and the tab format is used directly. + +Related to https://gitlab.freedesktop.org/realmd/realmd/issues/21 +--- + Makefile.am | 3 +- + build/tap-gtester | 204 ---------------------------------------------- + 2 files changed, 1 insertion(+), 206 deletions(-) + delete mode 100755 build/tap-gtester + +diff --git a/Makefile.am b/Makefile.am +index 27e3494..4ffd5b4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -161,7 +161,7 @@ endif + # + + LOG_DRIVER = $(top_srcdir)/build/tap-driver +-LOG_COMPILER = $(top_srcdir)/build/tap-gtester ++LOG_COMPILER = sh -c '"$$0" "$$@" --tap' + + VALGRIND_ARGS = --trace-children=no --quiet --error-exitcode=33 \ + --suppressions=valgrind-suppressions --gen-suppressions=all \ +@@ -183,7 +183,6 @@ recheck-memory: valgrind-suppressions + + EXTRA_DIST += \ + $(LOG_DRIVER) \ +- $(LOG_COMPILER) \ + $(VALGRIND_SUPPRESSIONS) \ + $(NULL) + diff --git a/0001-Set-NEWEST-flag-when-resolving-packages-with-Package.patch b/0001-Set-NEWEST-flag-when-resolving-packages-with-Package.patch new file mode 100644 index 000000000000..e8ba689fd83a --- /dev/null +++ b/0001-Set-NEWEST-flag-when-resolving-packages-with-Package.patch @@ -0,0 +1,47 @@ +From fa6dd59c5eaabc8c7e540f2aa2ded6f785de0a13 Mon Sep 17 00:00:00 2001 +From: Adam Williamson <awilliam@redhat.com> +Date: Wed, 20 Feb 2019 11:12:04 -0800 +Subject: [PATCH] Set 'NEWEST' flag when resolving packages with PackageKit + +When resolving package names via PackageKit, realmd does not set +the PK_FILTER_ENUM_NEWEST flag that asks PK to only give the +*newest available* package for each package name. So if there +are three different versions of the package available in three +repositories, realmd winds up producing an array containing the +package IDs for all three of those packages and calling +InstallPackages on all of them. I don't know if PK's behaviour +in this case is defined or predictable, but in practice in at +least one case it reliably results in one of the older package +versions being installed. + +This does not seem desirable, we should always want to install +the newest available version. So let's set the NEWEST flag to +ensure this. + +A possible consequence here is that, if a newer version of the +package is not installable but an older version is, we will now +fail where previously we did not. But even in that case I don't +know if we would *reliably* succeed before, and silently +installing an older version still doesn't necessarily seem like +the right thing to do. + +Signed-off-by: Adam Williamson <awilliam@redhat.com> +--- + service/realm-packages.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/service/realm-packages.c b/service/realm-packages.c +index 5976439..0309c57 100644 +--- a/service/realm-packages.c ++++ b/service/realm-packages.c +@@ -343,6 +343,7 @@ packages_resolve_async (GDBusConnection *connection, + gpointer user_data) + { + guint64 flags = 1 << 18 /* PK_FILTER_ENUM_ARCH */; ++ flags |= 1 << 16 /* PK_FILTER_ENUM_NEWEST */; + package_transaction_create ("Resolve", g_variant_new ("(t^as)", flags, package_names), + connection, cancellable, callback, user_data); + } +-- +2.20.1 + diff --git a/0001-Use-current-idmap-options-for-smb.conf.patch b/0001-Use-current-idmap-options-for-smb.conf.patch new file mode 100644 index 000000000000..ea34960f8c32 --- /dev/null +++ b/0001-Use-current-idmap-options-for-smb.conf.patch @@ -0,0 +1,185 @@ +From e683fb573bc09893ec541be29751560cea30ce3f Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Wed, 30 May 2018 13:10:57 +0200 +Subject: [PATCH] Use current idmap options for smb.conf + +Samba change some time ago the way how to configure id-mapping. With +this patch realmd will use the current supported options when creating +smb.conf. + +A new option --legacy-samba-config is added to use the old options if +realmd is used with Samba 3.5 or earlier. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1484072 +--- + dbus/realm-dbus-constants.h | 1 + + doc/manual/realmd.conf.xml | 17 ++++++++++++ + service/realm-samba-enroll.c | 2 +- + service/realm-samba-enroll.h | 3 +++ + service/realm-samba-winbind.c | 63 ++++++++++++++++++++++++++++++++++--------- + 5 files changed, 72 insertions(+), 14 deletions(-) + +diff --git a/dbus/realm-dbus-constants.h b/dbus/realm-dbus-constants.h +index 9cd30ef..40ffa2d 100644 +--- a/dbus/realm-dbus-constants.h ++++ b/dbus/realm-dbus-constants.h +@@ -69,6 +69,7 @@ G_BEGIN_DECLS + #define REALM_DBUS_OPTION_COMPUTER_NAME "computer-name" + #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_IDENTIFIER_ACTIVE_DIRECTORY "active-directory" + #define REALM_DBUS_IDENTIFIER_WINBIND "winbind" +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index 7853230..a2b577c 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -192,6 +192,23 @@ automatic-install = no + </listitem> + </varlistentry> + ++ <varlistentry> ++ <term><option>legacy-samba-config</option></term> ++ <listitem> ++ <para>Set this to <parameter>yes</parameter> to create a Samba ++ configuration file with id-mapping options used by Samba-3.5 ++ and earlier version.</para> ++ ++ <informalexample> ++<programlisting language="js"> ++[service] ++legacy-samba-config = no ++# legacy-samba-config = yes ++</programlisting> ++ </informalexample> ++ </listitem> ++ </varlistentry> ++ + </variablelist> + </refsect1> + +diff --git a/service/realm-samba-enroll.c b/service/realm-samba-enroll.c +index c81aed2..76e7b79 100644 +--- a/service/realm-samba-enroll.c ++++ b/service/realm-samba-enroll.c +@@ -69,7 +69,7 @@ join_closure_free (gpointer data) + g_free (join); + } + +-static gchar * ++gchar * + fallback_workgroup (const gchar *realm) + { + const gchar *pos; +diff --git a/service/realm-samba-enroll.h b/service/realm-samba-enroll.h +index 84e8b2f..310ec65 100644 +--- a/service/realm-samba-enroll.h ++++ b/service/realm-samba-enroll.h +@@ -46,6 +46,9 @@ void realm_samba_enroll_leave_async (RealmDisco *disco, + gboolean realm_samba_enroll_leave_finish (GAsyncResult *result, + GError **error); + ++gchar * ++fallback_workgroup (const gchar *realm); ++ + G_END_DECLS + + #endif /* __REALM_SAMBA_ENROLL_H__ */ +diff --git a/service/realm-samba-winbind.c b/service/realm-samba-winbind.c +index a7ddec3..9335e26 100644 +--- a/service/realm-samba-winbind.c ++++ b/service/realm-samba-winbind.c +@@ -21,8 +21,10 @@ + #include "realm-options.h" + #include "realm-samba-config.h" + #include "realm-samba-winbind.h" ++#include "realm-samba-enroll.h" + #include "realm-settings.h" + #include "realm-service.h" ++#include "dbus/realm-dbus-constants.h" + + #include <glib/gstdio.h> + +@@ -80,6 +82,10 @@ realm_samba_winbind_configure_async (RealmIniConfig *config, + RealmIniConfig *pwc; + GTask *task; + GError *error = NULL; ++ gchar *workgroup = NULL; ++ gchar *idmap_config_backend = NULL; ++ gchar *idmap_config_range = NULL; ++ gchar *idmap_config_schema_mode = NULL; + + g_return_if_fail (config != NULL); + g_return_if_fail (invocation != NULL || G_IS_DBUS_METHOD_INVOCATION (invocation)); +@@ -100,23 +106,54 @@ realm_samba_winbind_configure_async (RealmIniConfig *config, + "template shell", realm_settings_string ("users", "default-shell"), + NULL); + +- if (realm_options_automatic_mapping (options, domain_name)) { +- realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, +- "idmap uid", "10000-2000000", +- "idmap gid", "10000-2000000", +- "idmap backend", "tdb", +- "idmap schema", NULL, +- NULL); ++ if (realm_settings_boolean ("service", REALM_DBUS_OPTION_LEGACY_SMB_CONF, FALSE)) { ++ if (realm_options_automatic_mapping (options, domain_name)) { ++ realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, ++ "idmap uid", "10000-2000000", ++ "idmap gid", "10000-2000000", ++ "idmap backend", "tdb", ++ "idmap schema", NULL, ++ NULL); ++ } else { ++ realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, ++ "idmap uid", "500-4294967296", ++ "idmap gid", "500-4294967296", ++ "idmap backend", "ad", ++ "idmap schema", "rfc2307", ++ NULL); ++ } + } else { +- realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, +- "idmap uid", "500-4294967296", +- "idmap gid", "500-4294967296", +- "idmap backend", "ad", +- "idmap schema", "rfc2307", +- NULL); ++ workgroup = realm_ini_config_get (config, REALM_SAMBA_CONFIG_GLOBAL, "workgroup"); ++ if (workgroup == NULL) { ++ workgroup = fallback_workgroup (domain_name); ++ } ++ idmap_config_backend = g_strdup_printf ("idmap config %s : backend", workgroup != NULL ? workgroup : "PLEASE_REPLACE"); ++ idmap_config_range = g_strdup_printf ("idmap config %s : range", workgroup != NULL ? workgroup : "PLEASE_REPLACE"); ++ idmap_config_schema_mode = g_strdup_printf ("idmap config %s : schema_mode", workgroup != NULL ? workgroup : "PLEASE_REPLACE"); ++ g_free (workgroup); ++ ++ if (realm_options_automatic_mapping (options, domain_name)) { ++ realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, ++ "idmap config * : backend", "tdb", ++ "idmap config * : range", "10000-999999", ++ idmap_config_backend != NULL ? idmap_config_backend : "idmap config PLEASE_REPLACE : backend", "rid", ++ idmap_config_range != NULL ? idmap_config_range: "idmap config PLEASE_REPLACE : range", "2000000-2999999", ++ idmap_config_schema_mode != NULL ? idmap_config_schema_mode: "idmap config PLEASE_REPLACE : schema_mode", NULL, ++ NULL); ++ } else { ++ realm_ini_config_set (config, REALM_SAMBA_CONFIG_GLOBAL, ++ "idmap config * : backend", "tdb", ++ "idmap config * : range", "10000000-10999999", ++ idmap_config_backend != NULL ? idmap_config_backend : "idmap config PLEASE_REPLACE : backend", "ad", ++ idmap_config_range != NULL ? idmap_config_range: "idmap config PLEASE_REPLACE : range", "500-999999", ++ idmap_config_schema_mode != NULL ? idmap_config_schema_mode: "idmap config PLEASE_REPLACE : schema_mode", "rfc2307", ++ NULL); ++ } + } + + realm_ini_config_finish_change (config, &error); ++ g_free (idmap_config_backend); ++ g_free (idmap_config_range); + } + + /* Setup pam_winbind.conf with decent defaults matching our expectations */ +-- +2.14.4 + diff --git a/0001-doc-make-sure-cross-reference-ids-are-predictable.patch b/0001-doc-make-sure-cross-reference-ids-are-predictable.patch new file mode 100644 index 000000000000..64e1f39e1c5b --- /dev/null +++ b/0001-doc-make-sure-cross-reference-ids-are-predictable.patch @@ -0,0 +1,1500 @@ +From 4f3c02dc14300c0b8e51a55d627c57f73c108f64 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 10:36:19 +0200 +Subject: [PATCH 1/7] doc: make sure cross-reference ids are predictable + +To make sure the cross-reference ids are predictable in the +auto-generated DBus documentation as well the xsl and css files form the +gtk-doc package are updated as well. +--- + doc/manual/devhelp2.xsl | 173 ++++++++ + doc/manual/gtk-doc.xsl | 436 ++++++++----------- + doc/manual/realm.xml | 14 +- + doc/manual/realmd-guide-active-directory.xml | 4 +- + doc/manual/realmd-guide-ipa.xml | 2 +- + doc/manual/realmd-guide-kerberos.xml | 2 +- + doc/manual/realmd.conf.xml | 4 +- + doc/manual/static/gtk-doc.css | 420 +++++++++++++----- + 8 files changed, 688 insertions(+), 367 deletions(-) + create mode 100644 doc/manual/devhelp2.xsl + +diff --git a/doc/manual/devhelp2.xsl b/doc/manual/devhelp2.xsl +new file mode 100644 +index 0000000..bab6692 +--- /dev/null ++++ b/doc/manual/devhelp2.xsl +@@ -0,0 +1,173 @@ ++<?xml version='1.0'?> <!--*- mode: xml -*--> ++<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ++ version='1.0' ++ xmlns="http://www.devhelp.net/book" ++ xmlns:str="http://exslt.org/strings" ++ exclude-result-prefixes="str"> ++ ++ <xsl:template name="generate.devhelp2"> ++ <xsl:call-template name="write.chunk"> ++ <xsl:with-param name="filename"> ++ <xsl:choose> ++ <xsl:when test="$gtkdoc.bookname"> ++ <xsl:value-of select="$gtkdoc.bookname"/> ++ </xsl:when> ++ <xsl:otherwise> ++ <xsl:text>book</xsl:text> ++ </xsl:otherwise> ++ </xsl:choose> ++ <xsl:text>.devhelp2</xsl:text> ++ </xsl:with-param> ++ <xsl:with-param name="method" select="'xml'"/> ++ <xsl:with-param name="indent" select="'yes'"/> ++ <xsl:with-param name="encoding" select="'utf-8'"/> ++ <xsl:with-param name="doctype-public"/> ++ <xsl:with-param name="content"> ++ <xsl:call-template name="devhelp2"/> ++ </xsl:with-param> ++ </xsl:call-template> ++ </xsl:template> ++ ++ <xsl:variable name="gtkdoc.refsect2" select="//refsect2"/> ++ ++ <xsl:template name="devhelp2"> ++ <xsl:variable name="title"> ++ <xsl:apply-templates select="." mode="generate.devhelp2.toc.title.mode"/> ++ </xsl:variable> ++ <xsl:variable name="link"> ++ <xsl:call-template name="href.target"/> ++ </xsl:variable> ++ <xsl:variable name="author"> ++ <xsl:if test="articleinfo|bookinfo"> ++ <xsl:apply-templates mode="generate.devhelp2.authors" ++ select="articleinfo|bookinfo"/> ++ </xsl:if> ++ </xsl:variable> ++ <xsl:variable name="online"> ++ <xsl:value-of select="/book/bookinfo/releaseinfo/ulink[@role='online-location']/@url"/> ++ </xsl:variable> ++ <xsl:variable name="toc.nodes" select="part|reference|preface|chapter| ++ appendix|article|bibliography| ++ glossary|index|refentry| ++ bridgehead|sect1"/> ++ ++ <book title="{$title}" link="{$link}" author="{$author}" name="{$gtkdoc.bookname}" version="2" language="c"> ++ <xsl:if test="$online != ''"> ++ <xsl:attribute name="online"><xsl:value-of select="$online"/></xsl:attribute> ++ </xsl:if> ++ <xsl:if test="$toc.nodes"> ++ <chapters> ++ <xsl:apply-templates select="$toc.nodes" ++ mode="generate.devhelp2.toc.mode"/> ++ </chapters> ++ </xsl:if> ++ <functions> ++ <xsl:apply-templates select="$gtkdoc.refsect2[@role]" ++ mode="generate.devhelp2.index.mode"/> ++ <xsl:apply-templates select="$gtkdoc.refsect2/refsect3[@role='enum_members']/informaltable/tgroup/tbody/row[@role='constant']" ++ mode="generate.devhelp2.index.mode"/> ++ <xsl:apply-templates select="$gtkdoc.refsect2/refsect3[@role='struct_members']/informaltable/tgroup/tbody/row[@role='member']" ++ mode="generate.devhelp2.index.mode"/> ++ </functions> ++ </book> ++ </xsl:template> ++ ++ <xsl:template match="*" mode="generate.devhelp2.toc.mode"> ++ <xsl:variable name="title"> ++ <xsl:apply-templates select="." mode="generate.devhelp2.toc.title.mode"/> ++ </xsl:variable> ++ <xsl:variable name="target"> ++ <xsl:variable name="anchor" select="title/anchor"/> ++ <xsl:choose> ++ <xsl:when test="$anchor"> ++ <xsl:call-template name="href.target"> ++ <xsl:with-param name="object" select="$anchor"/> ++ </xsl:call-template> ++ </xsl:when> ++ <xsl:otherwise> ++ <xsl:call-template name="href.target"/> ++ </xsl:otherwise> ++ </xsl:choose> ++ </xsl:variable> ++ ++ <sub name="{$title}" link="{$target}"> ++ <xsl:apply-templates select="section|sect1| ++ refentry|refsect| ++ bridgehead|part|chapter|glossary|index" ++ mode="generate.devhelp2.toc.mode"/> ++ </sub> ++ </xsl:template> ++ ++ <xsl:template match="*" mode="generate.devhelp2.index.mode"> ++ <xsl:variable name="title" select="title| ++ term/literal| ++ entry[@role='enum_member_name']/para| ++ entry[@role='struct_member_name']/para/structfield/@id"/> ++ <xsl:variable name="anchor" select="title/anchor| ++ entry[@role='enum_member_name']/para| ++ entry[@role='struct_member_name']/para/structfield"/> ++ <xsl:variable name="type" select="@role"/> ++ <xsl:variable name="condition" select="@condition"/> ++ <xsl:variable name="target"> ++ <xsl:choose> ++ <xsl:when test="$anchor"> ++ <xsl:call-template name="href.target"> ++ <xsl:with-param name="object" select="$anchor"/> ++ </xsl:call-template> ++ </xsl:when> ++ <xsl:otherwise> ++ <xsl:call-template name="href.target"/> ++ </xsl:otherwise> ++ </xsl:choose> ++ </xsl:variable> ++ <keyword type="{$type}" name="{$title}" link="{$target}"> ++ <xsl:if test="$condition"> ++ <xsl:for-each select="str:split($condition,'|')"> ++ <xsl:variable name="attrname"> ++ <xsl:value-of select="substring-before(.,':')"/> ++ </xsl:variable> ++ <xsl:choose> ++ <xsl:when test="string-length($attrname)=0"> ++ <xsl:variable name="attrname2"> ++ <xsl:value-of select="."/> ++ </xsl:variable> ++ <xsl:attribute name="{$attrname2}"/> ++ </xsl:when> ++ <xsl:otherwise> ++ <xsl:attribute name="{$attrname}"> ++ <xsl:value-of select="substring-after(.,':')"/> ++ </xsl:attribute> ++ </xsl:otherwise> ++ </xsl:choose> ++ </xsl:for-each> ++ </xsl:if> ++ </keyword> ++ </xsl:template> ++ ++ <!-- get title --> ++ <xsl:template match="article" mode="generate.devhelp2.toc.title.mode"> ++ <xsl:value-of select="articleinfo/title"/> ++ </xsl:template> ++ <xsl:template match="book" mode="generate.devhelp2.toc.title.mode"> ++ <xsl:value-of select="bookinfo/title"/> ++ </xsl:template> ++ <xsl:template match="refentry" mode="generate.devhelp2.toc.title.mode"> ++ <xsl:value-of select="refmeta/refentrytitle"/> ++ </xsl:template> ++ <xsl:template match="*" mode="generate.devhelp2.toc.title.mode"> ++ <xsl:value-of select="title"/> ++ </xsl:template> ++ ++ <!-- generate list of authors ... --> ++ <xsl:template match="articleinfo|bookinfo" mode="generate.devhelp2.authors"> ++ <xsl:for-each select="authorgroup/author"> ++ <xsl:value-of select="firstname"/> ++ <xsl:text> </xsl:text> ++ <xsl:value-of select="surname"/> ++ <xsl:if test="not(last())"> ++ <xsl:text>, </xsl:text> ++ </xsl:if> ++ </xsl:for-each> ++ </xsl:template> ++ ++</xsl:stylesheet> +diff --git a/doc/manual/gtk-doc.xsl b/doc/manual/gtk-doc.xsl +index 9c0901b..3471e6c 100644 +--- a/doc/manual/gtk-doc.xsl ++++ b/doc/manual/gtk-doc.xsl +@@ -5,20 +5,19 @@ + version="1.0"> + + <!-- import the chunked XSL stylesheet --> +- <!-- http://www.sagehill.net/docbookxsl/Chunking.html says we should use +- "chunkfast.xsl", but I can see a difference --> ++ <!-- http://www.sagehill.net/docbookxsl/Chunking.html#FastChunking says we should use ++ "chunkfast.xsl", but I can't see a difference. Also it is not clear wheter ++ one should still set "chunk.fast". Again, no meassuable difference. --> + <xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl"/> ++ <xsl:include href="devhelp2.xsl"/> + <xsl:include href="version-greater-or-equal.xsl"/> + +- <xsl:key name="acronym.key" +- match="glossentry/glossterm" +- use="."/> +- <xsl:key name="gallery.key" +- match="para[@role='gallery']/link" +- use="@linkend"/> ++ <xsl:key name="acronym.key" match="glossentry/glossterm" use="."/> ++ <xsl:key name="gallery.key" match="para[@role='gallery']/link" use="@linkend"/> + + <!-- change some parameters --> + <!-- http://docbook.sourceforge.net/release/xsl/current/doc/html/index.html --> ++ <xsl:param name="admon.style"/> + <xsl:param name="toc.section.depth">2</xsl:param> + <xsl:param name="generate.toc"> + book toc +@@ -28,16 +27,17 @@ + part toc + reference toc + </xsl:param> ++ <xsl:param name="process.empty.source.toc">1</xsl:param> + + <xsl:param name="chunker.output.encoding" select="'UTF-8'"/> + <xsl:param name="chunker.output.indent" select="'yes'"/> + <xsl:param name="chunker.output.doctype-public" select="'-//W3C//DTD HTML 4.01 Transitional//EN'"/> + <xsl:param name="chunk.fast" select="1"/> +- <xsl:param name="chunk.quietly" select="1"/> + + <xsl:param name="default.encoding" select="'UTF-8'"/> + <xsl:param name="chapter.autolabel" select="0"/> + <xsl:param name="use.id.as.filename" select="1"/> ++ <xsl:param name="generate.consistent.ids" select="1"/> + <xsl:param name="html.ext" select="'.html'"/> + <xsl:param name="refentry.generate.name" select="0"/> + <xsl:param name="refentry.generate.title" select="1"/> +@@ -60,6 +60,9 @@ + <xsl:param name="gtkdoc.version" select="''"/> + <xsl:param name="gtkdoc.bookname" select="''"/> + ++ <!-- Override the typical template to prevent showing titles --> ++ <xsl:param name="admon.textlabel" select="0"/> ++ + <!-- ========================================================= --> + + <!-- l10n is slow, we don't ue it, so we'd like to turn it off +@@ -68,12 +71,8 @@ + + <xsl:param name="gtkdoc.l10n.xml" select="document('http://docbook.sourceforge.net/release/xsl/current/common/en.xml')"/> + +- <xsl:key name="gtkdoc.gentext.key" +- match="l:gentext[@key]" +- use="@key"/> +- <xsl:key name="gtkdoc.context.key" +- match="l:context[@name]" +- use="@name"/> ++ <xsl:key name="gtkdoc.gentext.key" match="l:gentext[@key]" use="@key"/> ++ <xsl:key name="gtkdoc.context.key" match="l:context[@name]" use="@name"/> + + <xsl:template name="gentext"> + <xsl:param name="key" select="local-name(.)"/> +@@ -250,7 +249,6 @@ + </xsl:if> + </xsl:variable> + +- + <xsl:variable name="is.title-unnumbered"> + <xsl:if test="$is.title = 0 and $is.title-numbered = 0"> + <xsl:call-template name="gentext.template.exists"> +@@ -309,52 +307,8 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + </xsl:if> + <xsl:apply-imports/> + +- <!-- generate the index.sgml href index --> +- <xsl:call-template name="generate.index"/> +- </xsl:template> +- +- <xsl:template name="generate.index"> +- <xsl:call-template name="write.text.chunk"> +- <xsl:with-param name="filename" select="'index.sgml'"/> +- <xsl:with-param name="content"> +- <xsl:apply-templates select="/book/bookinfo/releaseinfo/ulink" +- mode="generate.index.mode"/> +- <!-- check all anchor and refentry elements --> +- <!-- +- The obvious way to write this is //anchor|//refentry|etc... +- The obvious way is slow because it causes multiple traversals +- in libxslt. This take about half the time. +- --> +- <xsl:apply-templates select="//*[name()='anchor' or name()='refentry' or name()='refsect1' or +- name() = 'refsect2' or name()='refsynopsisdiv' or +- name()='varlistentry']" +- mode="generate.index.mode"/> +- </xsl:with-param> +- <xsl:with-param name="default.encoding" select="'UTF-8'"/> +- <xsl:with-param name="chunker.output.indent" select="'no'"/> +- </xsl:call-template> +- </xsl:template> +- +- <xsl:template match="*" mode="generate.index.mode"> +- <xsl:if test="not(@href) and count(@id) > 0"> +- <xsl:text><ANCHOR id="</xsl:text> +- <xsl:value-of select="@id"/> +- <xsl:text>" href="</xsl:text> +- <xsl:if test="$gtkdoc.bookname"> +- <xsl:value-of select="$gtkdoc.bookname"/> +- <xsl:text>/</xsl:text> +- </xsl:if> +- <xsl:call-template name="href.target"/> +- <xsl:text>"> </xsl:text> +- </xsl:if> +- </xsl:template> +- +- <xsl:template match="/book/bookinfo/releaseinfo/ulink" mode="generate.index.mode"> +- <xsl:if test="@role='online-location'"> +- <xsl:text><ONLINE href="</xsl:text> +- <xsl:value-of select="@url"/> +- <xsl:text>"> </xsl:text> +- </xsl:if> ++ <!-- generate $book.devhelp2 --> ++ <xsl:call-template name="generate.devhelp2"/> + </xsl:template> + + <!-- ========================================================= --> +@@ -387,6 +341,15 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <xsl:apply-imports/> + </xsl:template> + ++ <xsl:template name="user.head.title"> ++ <xsl:param name="node" select="."/> ++ <xsl:param name="title"/> ++ <xsl:variable name="home" select="/*[1]"/> ++ <title> ++ <xsl:copy-of select="$title"/>: <xsl:apply-templates select="$home" mode="object.title.markup"/> ++ </title> ++ </xsl:template> ++ + <xsl:template name="user.head.content"> + <xsl:if test="$gtkdoc.version"> + <meta name="generator" content="GTK-Doc V{$gtkdoc.version} (XML mode)"/> +@@ -399,10 +362,10 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <hr /> + <xsl:choose> + <xsl:when test="$gtkdoc.version"> +- Generated by GTK-Doc V<xsl:copy-of select="$gtkdoc.version" /> ++ <xsl:text>Generated by GTK-Doc V</xsl:text><xsl:copy-of select="$gtkdoc.version" /> + </xsl:when> + <xsl:otherwise> +- Generated by GTK-Doc ++ <xsl:text>Generated by GTK-Doc</xsl:text> + </xsl:otherwise> + </xsl:choose> + </div> +@@ -451,21 +414,119 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + + <xsl:if test="$suppress.navigation = '0' and $home != ."> + <table class="navigation" id="top" width="100%" +- summary = "Navigation header" cellpadding="2" cellspacing="2"> ++ summary = "Navigation header" cellpadding="2" cellspacing="5"> + <tr valign="middle"> ++ <td width="100%" align="left" class="shortcuts"> ++ <!--<xsl:if test="name()='refentry'"--> ++ <xsl:choose> ++ <xsl:when test="count($refsections) > 0"> ++ <a href="#" class="shortcut">Top</a> ++ <xsl:if test="count($sect_desc) > 0"> ++ <span id="nav_description">  <span class="dim">|</span>  ++ <a href="#{$section_id}.description" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='desc']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_object_hierarchy) > 0"> ++ <span id="nav_hierarchy">  <span class="dim">|</span>  ++ <a href="#{$section_id}.object-hierarchy" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='object_hierarchy']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_impl_interfaces) > 0"> ++ <span id="nav_interfaces">  <span class="dim">|</span>  ++ <a href="#{$section_id}.implemented-interfaces" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='impl_interfaces']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_prerequisites) > 0"> ++ <span id="nav_prerequisites">  <span class="dim">|</span>  ++ <a href="#{$section_id}.prerequisites" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='prerequisites']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_derived_interfaces) > 0"> ++ <span id="nav_derived_interfaces">  <span class="dim">|</span>  ++ <a href="#{$section_id}.derived-interfaces" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='derived_interfaces']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_implementations) > 0"> ++ <span id="nav_implementations">  <span class="dim">|</span>  ++ <a href="#{$section_id}.implementations" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='implementations']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_properties) > 0"> ++ <span id="nav_properties">  <span class="dim">|</span>  ++ <a href="#{$section_id}.properties" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='properties']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_child_properties) > 0"> ++ <span id="nav_child_properties">  <span class="dim">|</span>  ++ <a href="#{$section_id}.child-properties" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='child_properties']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_style_properties) > 0"> ++ <span id="nav_style_properties">  <span class="dim">|</span>  ++ <a href="#{$section_id}.style-properties" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='style_properties']/title"/> ++ </a></span> ++ </xsl:if> ++ <xsl:if test="count($sect_signal_proto) > 0"> ++ <span id="nav_signals">  <span class="dim">|</span>  ++ <a href="#{$section_id}.signals" class="shortcut"> ++ <xsl:value-of select="./refsect1[@role='signal_proto']/title"/> ++ </a></span> ++ </xsl:if> ++ </xsl:when> ++ <!-- this is not yet very nice, as it requires all glossdic/indexdiv ++ elements having a anchor element. maybe we can customize the xsl ++ to automaticaly create local anchors ++ --> ++ <xsl:when test="count($glssections) > 0"> ++ <span id="nav_glossary"> ++ <xsl:for-each select="./glossdiv"> ++ <xsl:if test="position() > 1"> ++  <span class="dim">|</span>  ++ </xsl:if> ++ <a class="shortcut"> ++ <xsl:attribute name="href">#gls<xsl:value-of select="./title"/></xsl:attribute> ++ <xsl:value-of select="./title"/> ++ </a> ++ </xsl:for-each> ++ </span> ++ </xsl:when> ++ <xsl:when test="count($idxsections) > 0"> ++ <span id="nav_index"> ++ <xsl:for-each select="./indexdiv/indexdiv"> ++ <xsl:if test="position() > 1"> ++  <span class="dim">|</span>  ++ </xsl:if> ++ <a class="shortcut"> ++ <xsl:attribute name="href">#idx<xsl:value-of select="./title"/></xsl:attribute> ++ <xsl:value-of select="./title"/> ++ </a> ++ </xsl:for-each> ++ </span> ++ </xsl:when> ++ </xsl:choose> ++ </td> + <xsl:choose> +- <xsl:when test="count($prev) > 0"> ++ <xsl:when test="$home != ."> + <td> +- <a accesskey="p"> ++ <a accesskey="h"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> +- <xsl:with-param name="object" select="$prev"/> ++ <xsl:with-param name="object" select="$home"/> + </xsl:call-template> + </xsl:attribute> +- <img src="left.png" width="24" height="24" border="0"> ++ <img src="home.png" width="16" height="16" border="0"> + <xsl:attribute name="alt"> + <xsl:call-template name="gentext"> +- <xsl:with-param name="key">nav-prev</xsl:with-param> ++ <xsl:with-param name="key">nav-home</xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </img> +@@ -485,7 +546,7 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <xsl:with-param name="object" select="$up"/> + </xsl:call-template> + </xsl:attribute> +- <img src="up.png" width="24" height="24" border="0"> ++ <img src="up.png" width="16" height="16" border="0"> + <xsl:attribute name="alt"> + <xsl:call-template name="gentext"> + <xsl:with-param name="key">nav-up</xsl:with-param> +@@ -496,22 +557,22 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + </td> + </xsl:when> + <xsl:otherwise> +- <td> </td> ++ <td><img src="up-insensitive.png" width="16" height="16" border="0"/></td> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> +- <xsl:when test="$home != ."> ++ <xsl:when test="count($prev) > 0"> + <td> +- <a accesskey="h"> ++ <a accesskey="p"> + <xsl:attribute name="href"> + <xsl:call-template name="href.target"> +- <xsl:with-param name="object" select="$home"/> ++ <xsl:with-param name="object" select="$prev"/> + </xsl:call-template> + </xsl:attribute> +- <img src="home.png" width="24" height="24" border="0"> ++ <img src="left.png" width="16" height="16" border="0"> + <xsl:attribute name="alt"> + <xsl:call-template name="gentext"> +- <xsl:with-param name="key">nav-home</xsl:with-param> ++ <xsl:with-param name="key">nav-prev</xsl:with-param> + </xsl:call-template> + </xsl:attribute> + </img> +@@ -519,12 +580,9 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + </td> + </xsl:when> + <xsl:otherwise> +- <td> </td> ++ <td><img src="left-insensitive.png" width="16" height="16" border="0"/></td> + </xsl:otherwise> + </xsl:choose> +- <th width="100%" align="center"> +- <xsl:apply-templates select="$home" mode="object.title.markup"/> +- </th> + <xsl:choose> + <xsl:when test="count($next) > 0"> + <td> +@@ -534,7 +592,7 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <xsl:with-param name="object" select="$next"/> + </xsl:call-template> + </xsl:attribute> +- <img src="right.png" width="24" height="24" border="0"> ++ <img src="right.png" width="16" height="16" border="0"> + <xsl:attribute name="alt"> + <xsl:call-template name="gentext"> + <xsl:with-param name="key">nav-next</xsl:with-param> +@@ -545,148 +603,10 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + </td> + </xsl:when> + <xsl:otherwise> +- <td> </td> ++ <td><img src="right-insensitive.png" width="16" height="16" border="0"/></td> + </xsl:otherwise> + </xsl:choose> + </tr> +- <!--<xsl:if test="name()='refentry'"--> +- <xsl:choose> +- <xsl:when test="count($refsections) > 0"> +- <tr> +- <td colspan="5" class="shortcuts"> +- <xsl:if test="count($sect_synopsis) > 0"> +- <a href="#{$section_id}.synopsis" class="shortcut">Top</a> +- </xsl:if> +- <xsl:if test="count($sect_desc) > 0"> +-  |  +- <a href="#{$section_id}.description" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='desc']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_object_hierarchy) > 0"> +-  |  +- <a href="#{$section_id}.object-hierarchy" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='object_hierarchy']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_impl_interfaces) > 0"> +-  |  +- <a href="#{$section_id}.implemented-interfaces" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='impl_interfaces']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_prerequisites) > 0"> +-  |  +- <a href="#{$section_id}.prerequisites" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='prerequisites']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_derived_interfaces) > 0"> +-  |  +- <a href="#{$section_id}.derived-interfaces" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='derived_interfaces']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_implementations) > 0"> +-  |  +- <a href="#{$section_id}.implementations" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='implementations']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_properties) > 0"> +-  |  +- <a href="#{$section_id}.properties" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='properties']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_child_properties) > 0"> +-  |  +- <a href="#{$section_id}.child-properties" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='child_properties']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_style_properties) > 0"> +-  |  +- <a href="#{$section_id}.style-properties" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='style_properties']/title"/> +- </a> +- </xsl:if> +- <xsl:if test="count($sect_signal_proto) > 0"> +-  |  +- <a href="#{$section_id}.signals" class="shortcut"> +- <xsl:value-of select="./refsect1[@role='signal_proto']/title"/> +- </a> +- </xsl:if> +- <!-- +- <xsl:if test="count($sect_details) > 0"> +- <a href="#details" class="shortcut"> +- <xsl:value-of select="./refsect1[@id='details']/title"/> +- </a> +-  |  +- </xsl:if> +- <xsl:if test="count($sect_property_details) > 0"> +- <a href="#property_details" class="shortcut"> +- <xsl:value-of select="./refsect1[@id='property_details']/title"/> +- </a> +-  |  +- </xsl:if> +- <xsl:if test="count($sect_child_property_details) > 0"> +- <a href="#child_property_details" class="shortcut"> +- <xsl:value-of select="./refsect1[@id='property_child_details']/title"/> +- </a> +-  |  +- </xsl:if> +- <xsl:if test="count($sect_style_property_details) > 0"> +- <a href="#style_property_details" class="shortcut"> +- <xsl:value-of select="./refsect1[@id='style_property_details']/title"/> +- </a> +-  |  +- </xsl:if> +- <xsl:if test="count($sect_signals) > 0"> +- <a href="#signals" class="shortcut"> +- <xsl:value-of select="./refsect1[@id='signals']/title"/> +- </a> +-  |  +- </xsl:if> +- --> +- </td> +- </tr> +- </xsl:when> +- <!-- this is not yet very nice, as it requires all glossdic/indexdiv +- elements having a anchor element. maybe we can customize the xsl +- to automaticaly create local anchors +- --> +- <xsl:when test="count($glssections) > 0"> +- <tr> +- <td colspan="5" class="shortcuts"> +- <xsl:for-each select="./glossdiv"> +- <xsl:if test="position() > 1"> +-  |  +- </xsl:if> +- <a class="shortcut"> +- <xsl:attribute name="href">#gls<xsl:value-of select="./title"/></xsl:attribute> +- <xsl:value-of select="./title"/> +- </a> +- </xsl:for-each> +- </td> +- </tr> +- </xsl:when> +- <xsl:when test="count($idxsections) > 0"> +- <tr> +- <td colspan="5" class="shortcuts"> +- <xsl:for-each select="./indexdiv/indexdiv"> +- <xsl:if test="position() > 1"> +-  |  +- </xsl:if> +- <a class="shortcut"> +- <xsl:attribute name="href">#idx<xsl:value-of select="./title"/></xsl:attribute> +- <xsl:value-of select="./title"/> +- </a> +- </xsl:for-each> +- </td> +- </tr> +- </xsl:when> +- </xsl:choose> + </table> + </xsl:if> + </xsl:template> +@@ -758,32 +678,32 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <table width="100%"> + <tr><td valign="top"> + <xsl:call-template name="anchor"/> +- <xsl:choose> +- <xsl:when test="$refentry.generate.name != 0"> +- <h2> +- <xsl:call-template name="gentext"> +- <xsl:with-param name="key" select="'RefName'"/> +- </xsl:call-template> +- </h2> +- </xsl:when> +- <xsl:when test="$refentry.generate.title != 0"> +- <h2> +- <xsl:choose> +- <xsl:when test="../refmeta/refentrytitle"> +- <xsl:apply-templates select="../refmeta/refentrytitle"/> +- </xsl:when> +- <xsl:otherwise> +- <xsl:apply-templates select="refname[1]"/> +- </xsl:otherwise> +- </xsl:choose> +- </h2> +- </xsl:when> +- </xsl:choose> +- <p> ++ <xsl:choose> ++ <xsl:when test="$refentry.generate.name != 0"> ++ <h2> ++ <xsl:call-template name="gentext"> ++ <xsl:with-param name="key" select="'RefName'"/> ++ </xsl:call-template> ++ </h2> ++ </xsl:when> ++ <xsl:when test="$refentry.generate.title != 0"> ++ <h2> ++ <xsl:choose> ++ <xsl:when test="../refmeta/refentrytitle"> ++ <xsl:apply-templates select="../refmeta/refentrytitle"/> ++ </xsl:when> ++ <xsl:otherwise> ++ <xsl:apply-templates select="refname[1]"/> ++ </xsl:otherwise> ++ </xsl:choose> ++ </h2> ++ </xsl:when> ++ </xsl:choose> ++ <p> + <xsl:apply-templates/> + </p> + </td> +- <td valign="top" align="right"> ++ <td class="gallery_image" valign="top" align="right"> + <xsl:choose> + <xsl:when test="../refmeta/refmiscinfo/inlinegraphic"> + <xsl:apply-templates select="../refmeta/refmiscinfo/inlinegraphic"/> +@@ -795,7 +715,7 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + - use it here + --> + <xsl:variable name="refentryid" select="../@id"/> +- <xsl:apply-templates select="key('gallery.key', $refentryid)/inlinegraphic"/> ++ <xsl:apply-templates select="key('gallery.key', $refentryid)/inlinegraphic"/> + </xsl:otherwise> + </xsl:choose> + </td></tr> +@@ -803,6 +723,21 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + </div> + </xsl:template> + ++ <!-- a copy from refentry.xsl to add the missing mode attribute, ++ see bug/729911, https://sourceforge.net/p/docbook/bugs/1358/ ++ fixed in: https://sourceforge.net/p/docbook/code/9962/ ++ --> ++ <xsl:template match="refpurpose" mode="no.anchor.mode"> ++ <xsl:if test="node()"> ++ <xsl:text> </xsl:text> ++ <xsl:call-template name="dingbat"> ++ <xsl:with-param name="dingbat">em-dash</xsl:with-param> ++ </xsl:call-template> ++ <xsl:text> </xsl:text> ++ <xsl:apply-templates mode="no.anchor.mode"/> ++ </xsl:if> ++ </xsl:template> ++ + <!-- add anchors for index sections --> + <xsl:template match="indexdiv"> + <a><xsl:attribute name="name">idx<xsl:value-of select="./title"/></xsl:attribute></a> +@@ -825,12 +760,12 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <span class="extralinks"> + <xsl:for-each select="../ulink[@role='extralinks']"> + <xsl:if test="position() = 1">[ </xsl:if> +- <xsl:if test="position() > 1"> | </xsl:if> ++ <xsl:if test="position() > 1">  <span class="dim">|</span> </xsl:if> + <a> + <xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute> + <xsl:copy-of select="text()" /> + </a> +- <xsl:if test="position() = last()"> ]</xsl:if> ++ <xsl:if test="position() = last()">  ]</xsl:if> + </xsl:for-each> + </span> + </xsl:if> +@@ -861,11 +796,6 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <xsl:param name="acronym"> + <xsl:apply-templates/> + </xsl:param> +- <!-- +- We use for-each to change context to the database document because key() +- only locates elements in the same document as the context node! +- --> +- + <xsl:param name="value" > + <xsl:value-of select="key('acronym.key', $acronym)/../glossdef/para[1]" /> + </xsl:param> +@@ -878,7 +808,7 @@ Get a newer version at http://docbook.sourceforge.net/projects/xsl/ + <a> + <xsl:attribute name="href"> + <xsl:text>http://foldoc.org/</xsl:text> +- <xsl:value-of select="$acronym"/> ++ <xsl:value-of select="$acronym"/> + </xsl:attribute> + <xsl:call-template name="inline.charseq"/> + </a> +diff --git a/doc/manual/realm.xml b/doc/manual/realm.xml +index 9d9136a..7b73331 100644 +--- a/doc/manual/realm.xml ++++ b/doc/manual/realm.xml +@@ -49,7 +49,7 @@ + </cmdsynopsis> + </refsynopsisdiv> + +-<refsect1> ++<refsect1 id="man-description"> + <title>Description</title> + <para><command>realm</command> is a command line tool that + can be used to manage enrollment in kerberos realms, like Active +@@ -81,7 +81,7 @@ + + </refsect1> + +-<refsect1> ++<refsect1 id="man-discover"> + <title>Discover</title> + + <para>Discover a realm and its capabilities.</para> +@@ -138,7 +138,7 @@ $ realm discover domain.example.com + + </refsect1> + +-<refsect1> ++<refsect1 id="man-join"> + <title>Join</title> + + <para>Configure the local machine for use with a realm.</para> +@@ -263,7 +263,7 @@ $ realm join --user=admin --computer-ou=OU=Special domain.example.com + + </refsect1> + +-<refsect1> ++<refsect1 id="man-leave"> + <title>Leave</title> + + <para>Deconfigure the local machine for use with a realm.</para> +@@ -313,7 +313,7 @@ $ realm leave domain.example.com + + </refsect1> + +-<refsect1> ++<refsect1 id="man-list"> + <title>List</title> + + <para>List all the discovered and configured realms.</para> +@@ -345,7 +345,7 @@ $ realm list + </variablelist> + </refsect1> + +-<refsect1> ++<refsect1 id="man-permit"> + <title>Permit</title> + + <para>Permit local login by users of the realm.</para> +@@ -392,7 +392,7 @@ $ realm permit --withdraw user@example.com + + </refsect1> + +-<refsect1> ++<refsect1 id="man-deny"> + <title>Deny</title> + + <para>Deny local login by realm accounts.</para> +diff --git a/doc/manual/realmd-guide-active-directory.xml b/doc/manual/realmd-guide-active-directory.xml +index 362cf94..c88e8af 100644 +--- a/doc/manual/realmd-guide-active-directory.xml ++++ b/doc/manual/realmd-guide-active-directory.xml +@@ -69,7 +69,7 @@ $ <command>realm discover --verbose domain.example.com</command> + <ulink url="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html">Winbind</ulink>. + By default SSSD is used.</para> + +- <section> ++ <section id="using-sssd-with-active-directory"> + <title>Using SSSD with Active Directory</title> + <para><ulink url="https://fedorahosted.org/sssd/">SSSD</ulink> + provides client software for various kerberos and/or LDAP +@@ -91,7 +91,7 @@ $ <command>realm join --client-software=sssd domain.example.com</command> + </informalexample> + </section> + +- <section> ++ <section id="using-winbind-with-active-directory"> + <title>Using Winbind with Active Directory</title> + <para>Samba + <ulink url="http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html">Winbind</ulink> +diff --git a/doc/manual/realmd-guide-ipa.xml b/doc/manual/realmd-guide-ipa.xml +index bba6504..c3ad450 100644 +--- a/doc/manual/realmd-guide-ipa.xml ++++ b/doc/manual/realmd-guide-ipa.xml +@@ -13,7 +13,7 @@ + users locally, and log into the local machine with IPA domain + credentials.</para> + +- <section> ++ <section id="discovering-ipa-domains"> + <title>Discovering IPA domains</title> + <para><command>realmd</command> discovers which domains or + realms it can use or configure. It can discover and identify +diff --git a/doc/manual/realmd-guide-kerberos.xml b/doc/manual/realmd-guide-kerberos.xml +index a57e964..5b9d4b1 100644 +--- a/doc/manual/realmd-guide-kerberos.xml ++++ b/doc/manual/realmd-guide-kerberos.xml +@@ -12,7 +12,7 @@ + Since there is no standard way to enroll a computer against a Kerberos + server, it is not possible to do this with <command>realmd</command>.</para> + +- <section> ++ <section id="discovering-kerberos-realms"> + <title>Discovering Kerberos realms</title> + <para><command>realmd</command> discovers which domains or + realms it can use or configure. It can discover and identify +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index a2b577c..f0b0879 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -28,7 +28,7 @@ + <refpurpose>Tweak behavior of realmd</refpurpose> + </refnamediv> + +-<refsect1> ++<refsect1 id="realmd-conf-file"> + <title>Configuration File</title> + + <para><command>realmd</command> can be tweaked by network administrators +@@ -297,7 +297,7 @@ DOMAIN\user:*:13445:13446:Name:/home/DOMAIN/user:/bin/bash + + </refsect1> + +-<refsect1> ++<refsect1 id="realmd-conf-specific-settings"> + <title>Realm specific settings</title> + <para>These options should go in an section with the same name + as the realm in the <filename>/etc/realmd.conf</filename> file. +diff --git a/doc/manual/static/gtk-doc.css b/doc/manual/static/gtk-doc.css +index 5618926..af6ce9c 100644 +--- a/doc/manual/static/gtk-doc.css ++++ b/doc/manual/static/gtk-doc.css +@@ -1,15 +1,23 @@ ++body ++{ ++ font-family: cantarell, sans-serif; ++} + .synopsis, .classsynopsis + { + /* tango:aluminium 1/2 */ + background: #eeeeec; +- border: solid 1px #d3d7cf; ++ background: rgba(238, 238, 236, 0.5); ++ border: solid 1px rgb(238, 238, 236); + padding: 0.5em; + } + .programlisting + { + /* tango:sky blue 0/1 */ ++ /* fallback for no rgba support */ + background: #e6f3ff; + border: solid 1px #729fcf; ++ background: rgba(114, 159, 207, 0.1); ++ border: solid 1px rgba(114, 159, 207, 0.2); + padding: 0.5em; + } + .variablelist +@@ -22,86 +30,8 @@ + vertical-align: top; + } + +-@media screen { +- sup a.footnote +- { +- position: relative; +- top: 0em ! important; +- } +- /* this is needed so that the local anchors are displayed below the naviagtion */ +- div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] +- { +- display: inline-block; +- position: relative; +- top:-5em; +- } +- /* this seems to be a bug in the xsl style sheets when generating indexes */ +- div.index div.index +- { +- top: 0em; +- } +- /* make space for the fixed navigation bar and add space at the bottom so that +- * link targets appear somewhat close to top +- */ +- body +- { +- padding-top: 3.2em; +- padding-bottom: 20em; +- } +- /* style and size the navigation bar */ +- table.navigation#top +- { +- position: fixed; +- /* tango:scarlet red 0/1 */ +- background: #ffe6e6; +- border: solid 1px #ef2929; +- margin-top: 0; +- margin-bottom: 0; +- top: 0; +- left: 0; +- height: 3em; +- z-index: 10; +- } +- .navigation a, .navigation a:visited +- { +- /* tango:scarlet red 3 */ +- color: #a40000; +- } +- .navigation a:hover +- { +- /* tango:scarlet red 1 */ +- color: #ef2929; +- } +- td.shortcuts +- { +- /* tango:scarlet red 1 */ +- color: #ef2929; +- font-size: 80%; +- white-space: nowrap; +- } +-} +-@media print { +- table.navigation { +- visibility: collapse; +- display: none; +- } +- div.titlepage table.navigation { +- visibility: visible; +- display: table; +- /* tango:scarlet red 0/1 */ +- background: #ffe6e6; +- border: solid 1px #ef2929; +- margin-top: 0; +- margin-bottom: 0; +- top: 0; +- left: 0; +- height: 3em; +- } +-} +- +-.navigation .title +-{ +- font-size: 200%; ++span.nowrap { ++ white-space: nowrap; + } + + div.gallery-float +@@ -131,6 +61,72 @@ a:hover + color: #729fcf; + } + ++div.informaltable table ++{ ++ border-collapse: separate; ++ border-spacing: 1em 0.3em; ++ border: none; ++} ++ ++div.informaltable table td, div.informaltable table th ++{ ++ vertical-align: top; ++} ++ ++.function_type, ++.variable_type, ++.property_type, ++.signal_type, ++.parameter_name, ++.struct_member_name, ++.union_member_name, ++.define_keyword, ++.datatype_keyword, ++.typedef_keyword ++{ ++ text-align: right; ++} ++ ++/* dim non-primary columns */ ++.c_punctuation, ++.function_type, ++.variable_type, ++.property_type, ++.signal_type, ++.define_keyword, ++.datatype_keyword, ++.typedef_keyword, ++.property_flags, ++.signal_flags, ++.parameter_annotations, ++.enum_member_annotations, ++.struct_member_annotations, ++.union_member_annotations ++{ ++ color: #888a85; ++} ++ ++.function_type a, ++.function_type a:visited, ++.function_type a:hover, ++.property_type a, ++.property_type a:visited, ++.property_type a:hover, ++.signal_type a, ++.signal_type a:visited, ++.signal_type a:hover, ++.signal_flags a, ++.signal_flags a:visited, ++.signal_flags a:hover ++{ ++ color: #729fcf; ++} ++ ++td p ++{ ++ margin: 0.25em; ++} ++ + div.table table + { + border-collapse: collapse; +@@ -153,14 +149,44 @@ div.table table th + background-color: #d3d7cf; + } + ++h4 ++{ ++ color: #555753; ++ margin-top: 1em; ++ margin-bottom: 1em; ++} ++ + hr + { +- /* tango:aluminium 3 */ +- color: #babdb6; +- background: #babdb6; ++ /* tango:aluminium 1 */ ++ color: #d3d7cf; ++ background: #d3d7cf; + border: none 0px; + height: 1px; + clear: both; ++ margin: 2.0em 0em 2.0em 0em; ++} ++ ++dl.toc dt ++{ ++ padding-bottom: 0.25em; ++} ++ ++dl.toc > dt ++{ ++ padding-top: 0.25em; ++ padding-bottom: 0.25em; ++ font-weight: bold; ++} ++ ++dl.toc > dl ++{ ++ padding-bottom: 0.5em; ++} ++ ++.parameter ++{ ++ font-style: normal; + } + + .footer +@@ -172,31 +198,70 @@ hr + font-size: 80%; + } + ++.informalfigure, ++.figure ++{ ++ margin: 1em; ++} ++ ++.informalexample, ++.example ++{ ++ margin-top: 1em; ++ margin-bottom: 1em; ++} ++ + .warning + { + /* tango:orange 0/1 */ + background: #ffeed9; ++ background: rgba(252, 175, 62, 0.1); + border-color: #ffb04f; ++ border-color: rgba(252, 175, 62, 0.2); + } + .note + { + /* tango:chameleon 0/0.5 */ + background: #d8ffb2; ++ background: rgba(138, 226, 52, 0.1); + border-color: #abf562; ++ border-color: rgba(138, 226, 52, 0.2); + } +-.note, .warning ++div.blockquote ++{ ++ border-color: #eeeeec; ++} ++.note, .warning, div.blockquote + { + padding: 0.5em; + border-width: 1px; + border-style: solid; ++ margin: 2em; + } +-.note h3, .warning h3 ++.note p, .warning p + { +- margin-top: 0.0em ++ margin: 0; + } +-.note p, .warning p ++ ++div.warning h3.title, ++div.note h3.title ++{ ++ display: none; ++} ++ ++p + div.section ++{ ++ margin-top: 1em; ++} ++ ++div.refnamediv, ++div.refsynopsisdiv, ++div.refsect1, ++div.refsect2, ++div.toc, ++div.section + { +- margin-bottom: 0.0em ++ margin-bottom: 1em; + } + + /* blob links */ +@@ -209,33 +274,52 @@ h2 .extralinks, h3 .extralinks + font-weight: normal; + } + ++.lineart ++{ ++ color: #d3d7cf; ++ font-weight: normal; ++} ++ + .annotation + { + /* tango:aluminium 5 */ + color: #555753; +- font-size: 80%; + font-weight: normal; + } + ++.structfield ++{ ++ font-style: normal; ++ font-weight: normal; ++} ++ ++acronym,abbr ++{ ++ border-bottom: 1px dotted gray; ++} ++ + /* code listings */ + +-.listing_code .programlisting .cbracket { color: #a40000; } /* tango: scarlet red 3 */ +-.listing_code .programlisting .comment { color: #a1a39d; } /* tango: aluminium 4 */ +-.listing_code .programlisting .function { color: #000000; font-weight: bold; } +-.listing_code .programlisting .function a { color: #11326b; font-weight: bold; } /* tango: sky blue 4 */ +-.listing_code .programlisting .keyword { color: #4e9a06; } /* tango: chameleon 3 */ ++.listing_code .programlisting .normal, ++.listing_code .programlisting .normal a, ++.listing_code .programlisting .number, ++.listing_code .programlisting .cbracket, ++.listing_code .programlisting .symbol { color: #555753; } ++.listing_code .programlisting .comment, + .listing_code .programlisting .linenum { color: #babdb6; } /* tango: aluminium 3 */ +-.listing_code .programlisting .normal { color: #000000; } +-.listing_code .programlisting .number { color: #75507b; } /* tango: plum 2 */ ++.listing_code .programlisting .function, ++.listing_code .programlisting .function a, + .listing_code .programlisting .preproc { color: #204a87; } /* tango: sky blue 3 */ +-.listing_code .programlisting .string { color: #c17d11; } /* tango: chocolate 2 */ +-.listing_code .programlisting .type { color: #000000; } +-.listing_code .programlisting .type a { color: #11326b; } /* tango: sky blue 4 */ +-.listing_code .programlisting .symbol { color: #ce5c00; } /* tango: orange 3 */ ++.listing_code .programlisting .string { color: #ad7fa8; } /* tango: plum */ ++.listing_code .programlisting .keyword, ++.listing_code .programlisting .usertype, ++.listing_code .programlisting .type, ++.listing_code .programlisting .type a { color: #4e9a06; } /* tango: chameleon 3 */ + + .listing_frame { + /* tango:sky blue 1 */ + border: solid 1px #729fcf; ++ border: solid 1px rgba(114, 159, 207, 0.2); + padding: 0px; + } + +@@ -247,18 +331,152 @@ h2 .extralinks, h3 .extralinks + .listing_lines { + /* tango:sky blue 0.5 */ + background: #a6c5e3; ++ background: rgba(114, 159, 207, 0.2); + /* tango:aluminium 6 */ + color: #2e3436; + } + .listing_code { + /* tango:sky blue 0 */ + background: #e6f3ff; ++ background: rgba(114, 159, 207, 0.1); + } + .listing_code .programlisting { + /* override from previous */ + border: none 0px; + padding: 0px; ++ background: none; + } + .listing_lines pre, .listing_code pre { + margin: 0px; + } ++ ++@media screen { ++ /* these have a <sup> as a first child, but since there are no parent selectors ++ * we can't use that. */ ++ a.footnote ++ { ++ position: relative; ++ top: 0em ! important; ++ } ++ /* this is needed so that the local anchors are displayed below the naviagtion */ ++ div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] ++ { ++ display: inline-block; ++ position: relative; ++ top:-5em; ++ } ++ /* this seems to be a bug in the xsl style sheets when generating indexes */ ++ div.index div.index ++ { ++ top: 0em; ++ } ++ /* make space for the fixed navigation bar and add space at the bottom so that ++ * link targets appear somewhat close to top ++ */ ++ body ++ { ++ padding-top: 2.5em; ++ padding-bottom: 500px; ++ max-width: 60em; ++ } ++ p ++ { ++ max-width: 60em; ++ } ++ /* style and size the navigation bar */ ++ table.navigation#top ++ { ++ position: fixed; ++ background: #e2e2e2; ++ border-bottom: solid 1px #babdb6; ++ border-spacing: 5px; ++ margin-top: 0; ++ margin-bottom: 0; ++ top: 0; ++ left: 0; ++ z-index: 10; ++ } ++ table.navigation#top td ++ { ++ padding-left: 6px; ++ padding-right: 6px; ++ } ++ .navigation a, .navigation a:visited ++ { ++ /* tango:sky blue 3 */ ++ color: #204a87; ++ } ++ .navigation a:hover ++ { ++ /* tango:sky blue 2 */ ++ color: #3465a4; ++ } ++ td.shortcuts ++ { ++ /* tango:sky blue 2 */ ++ color: #3465a4; ++ font-size: 80%; ++ white-space: nowrap; ++ } ++ td.shortcuts .dim ++ { ++ color: #babdb6; ++ } ++ .navigation .title ++ { ++ font-size: 80%; ++ max-width: none; ++ margin: 0px; ++ font-weight: normal; ++ } ++} ++@media screen and (min-width: 60em) { ++ /* screen larger than 60em */ ++ body { margin: auto; } ++} ++@media screen and (max-width: 60em) { ++ /* screen less than 60em */ ++ #nav_hierarchy { display: none; } ++ #nav_interfaces { display: none; } ++ #nav_prerequisites { display: none; } ++ #nav_derived_interfaces { display: none; } ++ #nav_implementations { display: none; } ++ #nav_child_properties { display: none; } ++ #nav_style_properties { display: none; } ++ #nav_index { display: none; } ++ #nav_glossary { display: none; } ++ .gallery_image { display: none; } ++ .property_flags { display: none; } ++ .signal_flags { display: none; } ++ .parameter_annotations { display: none; } ++ .enum_member_annotations { display: none; } ++ .struct_member_annotations { display: none; } ++ .union_member_annotations { display: none; } ++ /* now that a column is hidden, optimize space */ ++ col.parameters_name { width: auto; } ++ col.parameters_description { width: auto; } ++ col.struct_members_name { width: auto; } ++ col.struct_members_description { width: auto; } ++ col.enum_members_name { width: auto; } ++ col.enum_members_description { width: auto; } ++ col.union_members_name { width: auto; } ++ col.union_members_description { width: auto; } ++ .listing_lines { display: none; } ++} ++@media print { ++ table.navigation { ++ visibility: collapse; ++ display: none; ++ } ++ div.titlepage table.navigation { ++ visibility: visible; ++ display: table; ++ background: #e2e2e2; ++ border: solid 1px #babdb6; ++ margin-top: 0; ++ margin-bottom: 0; ++ top: 0; ++ left: 0; ++ height: 3em; ++ } ++} +-- +2.25.1 + diff --git a/0001-service-Add-nss-and-pam-sssd.conf-services-after-joi.patch b/0001-service-Add-nss-and-pam-sssd.conf-services-after-joi.patch new file mode 100644 index 000000000000..8b8f633a8977 --- /dev/null +++ b/0001-service-Add-nss-and-pam-sssd.conf-services-after-joi.patch @@ -0,0 +1,96 @@ +From 402cbab6e8267fcd959bcfa84a47f4871b59944d Mon Sep 17 00:00:00 2001 +From: Stef Walter <stefw@redhat.com> +Date: Fri, 28 Oct 2016 20:27:48 +0200 +Subject: [PATCH] service: Add nss and pam sssd.conf services after joining + +After adding a domain to sssd.conf add the nss and pam services +to the [sssd] block. + +https://bugs.freedesktop.org/show_bug.cgi?id=98479 +--- + service/realm-sssd-ad.c | 3 +++ + service/realm-sssd-config.c | 2 -- + service/realm-sssd-ipa.c | 3 +++ + tests/test-sssd-config.c | 4 ++-- + 4 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c +index 5ed384d..5fa81ce 100644 +--- a/service/realm-sssd-ad.c ++++ b/service/realm-sssd-ad.c +@@ -160,6 +160,7 @@ configure_sssd_for_domain (RealmIniConfig *config, + gboolean use_adcli, + GError **error) + { ++ const gchar *services[] = { "nss", "pam", NULL }; + GString *realmd_tags; + const gchar *access_provider; + const gchar *shell; +@@ -206,6 +207,8 @@ configure_sssd_for_domain (RealmIniConfig *config, + "ldap_sasl_authid", authid, + NULL); + ++ realm_ini_config_set_list_diff (config, "sssd", "services", ", ", services, NULL); ++ + g_free (authid); + g_string_free (realmd_tags, TRUE); + +diff --git a/service/realm-sssd-config.c b/service/realm-sssd-config.c +index 2096afd..d4398b9 100644 +--- a/service/realm-sssd-config.c ++++ b/service/realm-sssd-config.c +@@ -154,8 +154,6 @@ realm_sssd_config_add_domain (RealmIniConfig *config, + g_strfreev (already); + + /* Setup a default sssd section */ +- if (!realm_ini_config_have (config, "section", "services")) +- realm_ini_config_set (config, "sssd", "services", "nss, pam", NULL); + if (!realm_ini_config_have (config, "sssd", "config_file_version")) + realm_ini_config_set (config, "sssd", "config_file_version", "2", NULL); + +diff --git a/service/realm-sssd-ipa.c b/service/realm-sssd-ipa.c +index b12136e..001870d 100644 +--- a/service/realm-sssd-ipa.c ++++ b/service/realm-sssd-ipa.c +@@ -156,6 +156,7 @@ on_ipa_client_do_restart (GObject *source, + GAsyncResult *result, + gpointer user_data) + { ++ const gchar *services[] = { "nss", "pam", NULL }; + GTask *task = G_TASK (user_data); + EnrollClosure *enroll = g_task_get_task_data (task); + RealmSssd *sssd = g_task_get_source_object (task); +@@ -207,6 +208,8 @@ on_ipa_client_do_restart (GObject *source, + "realmd_tags", realmd_tags, + NULL); + ++ realm_ini_config_set_list_diff (config, "sssd", "services", ", ", services, NULL); ++ + g_free (home); + } + +diff --git a/tests/test-sssd-config.c b/tests/test-sssd-config.c +index 59eab75..892b9d5 100644 +--- a/tests/test-sssd-config.c ++++ b/tests/test-sssd-config.c +@@ -90,7 +90,7 @@ test_add_domain (Test *test, + gconstpointer unused) + { + const gchar *data = "[domain/one]\nval=1\n[sssd]\ndomains=one"; +- const gchar *check = "[domain/one]\nval=1\n[sssd]\ndomains = one, two\nconfig_file_version = 2\nservices = nss, pam\n\n[domain/two]\ndos = 2\n"; ++ const gchar *check = "[domain/one]\nval=1\n[sssd]\ndomains = one, two\nconfig_file_version = 2\n\n[domain/two]\ndos = 2\n"; + GError *error = NULL; + gchar *output; + gboolean ret; +@@ -140,7 +140,7 @@ static void + test_add_domain_only (Test *test, + gconstpointer unused) + { +- const gchar *check = "\n[sssd]\ndomains = two\nconfig_file_version = 2\nservices = nss, pam\n\n[domain/two]\ndos = 2\n"; ++ const gchar *check = "\n[sssd]\ndomains = two\nconfig_file_version = 2\n\n[domain/two]\ndos = 2\n"; + GError *error = NULL; + gchar *output; + gboolean ret; +-- +2.9.3 + diff --git a/0001-service-Add-pam-and-nss-services-in-realm_sssd_confi.patch b/0001-service-Add-pam-and-nss-services-in-realm_sssd_confi.patch new file mode 100644 index 000000000000..6c44727a2f71 --- /dev/null +++ b/0001-service-Add-pam-and-nss-services-in-realm_sssd_confi.patch @@ -0,0 +1,98 @@ +From 9d5b6f5c88df582fb94edcf5cc05a8cfaa63cf6a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com> +Date: Tue, 25 Apr 2017 07:20:17 +0200 +Subject: [PATCH] service: Add "pam" and "nss" services in + realm_sssd_config_add_domain() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +realm_sssd_config_add_domain() must setup the services line in sssd.conf +otherwise SSSD won't be able to start any of its services. + +It's a regression caused by 402cbab which leaves SSSD with no services +line when joining to an ad client doing "realm join ad.example". + +https://bugs.freedesktop.org/show_bug.cgi?id=98479 + +Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com> +--- + service/realm-sssd-ad.c | 3 ++- + service/realm-sssd-config.c | 2 ++ + service/realm-sssd-ipa.c | 3 ++- + tests/test-sssd-config.c | 4 ++-- + 4 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c +index 5fa81ce..8543ca8 100644 +--- a/service/realm-sssd-ad.c ++++ b/service/realm-sssd-ad.c +@@ -207,7 +207,8 @@ configure_sssd_for_domain (RealmIniConfig *config, + "ldap_sasl_authid", authid, + NULL); + +- realm_ini_config_set_list_diff (config, "sssd", "services", ", ", services, NULL); ++ if (ret) ++ ret = realm_ini_config_change_list (config, "sssd", "services", ", ", services, NULL, error); + + g_free (authid); + g_string_free (realmd_tags, TRUE); +diff --git a/service/realm-sssd-config.c b/service/realm-sssd-config.c +index d4398b9..140d7dc 100644 +--- a/service/realm-sssd-config.c ++++ b/service/realm-sssd-config.c +@@ -130,6 +130,7 @@ realm_sssd_config_add_domain (RealmIniConfig *config, + gchar **already; + gboolean ret; + gchar *section; ++ const gchar *services[] = { "nss", "pam", NULL }; + va_list va; + gint i; + +@@ -154,6 +155,7 @@ realm_sssd_config_add_domain (RealmIniConfig *config, + g_strfreev (already); + + /* Setup a default sssd section */ ++ realm_ini_config_set_list_diff (config, "sssd", "services", ", ", services, NULL); + if (!realm_ini_config_have (config, "sssd", "config_file_version")) + realm_ini_config_set (config, "sssd", "config_file_version", "2", NULL); + +diff --git a/service/realm-sssd-ipa.c b/service/realm-sssd-ipa.c +index 001870d..ff1dc8a 100644 +--- a/service/realm-sssd-ipa.c ++++ b/service/realm-sssd-ipa.c +@@ -208,7 +208,8 @@ on_ipa_client_do_restart (GObject *source, + "realmd_tags", realmd_tags, + NULL); + +- realm_ini_config_set_list_diff (config, "sssd", "services", ", ", services, NULL); ++ if (error == NULL) ++ realm_ini_config_change_list (config, "sssd", "services", ", ", services, NULL, &error); + + g_free (home); + } +diff --git a/tests/test-sssd-config.c b/tests/test-sssd-config.c +index 892b9d5..59eab75 100644 +--- a/tests/test-sssd-config.c ++++ b/tests/test-sssd-config.c +@@ -90,7 +90,7 @@ test_add_domain (Test *test, + gconstpointer unused) + { + const gchar *data = "[domain/one]\nval=1\n[sssd]\ndomains=one"; +- const gchar *check = "[domain/one]\nval=1\n[sssd]\ndomains = one, two\nconfig_file_version = 2\n\n[domain/two]\ndos = 2\n"; ++ const gchar *check = "[domain/one]\nval=1\n[sssd]\ndomains = one, two\nconfig_file_version = 2\nservices = nss, pam\n\n[domain/two]\ndos = 2\n"; + GError *error = NULL; + gchar *output; + gboolean ret; +@@ -140,7 +140,7 @@ static void + test_add_domain_only (Test *test, + gconstpointer unused) + { +- const gchar *check = "\n[sssd]\ndomains = two\nconfig_file_version = 2\n\n[domain/two]\ndos = 2\n"; ++ const gchar *check = "\n[sssd]\ndomains = two\nconfig_file_version = 2\nservices = nss, pam\n\n[domain/two]\ndos = 2\n"; + GError *error = NULL; + gchar *output; + gboolean ret; +-- +2.9.3 + diff --git a/0001-switch-to-authselect.patch b/0001-switch-to-authselect.patch new file mode 100644 index 000000000000..d750d6dbf3bf --- /dev/null +++ b/0001-switch-to-authselect.patch @@ -0,0 +1,36 @@ +From 32645f2fc1ddfb2eed7069fd749602619f26ed37 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com> +Date: Mon, 19 Feb 2018 11:51:06 +0100 +Subject: [PATCH] switch to authselect + +--- + service/realmd-redhat.conf | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/service/realmd-redhat.conf b/service/realmd-redhat.conf +index e39fad525c716d1ed99715280cd5d497b9039427..26cf6147f352e1b48c3261fa42707d816428f879 100644 +--- a/service/realmd-redhat.conf ++++ b/service/realmd-redhat.conf +@@ -23,15 +23,15 @@ adcli = /usr/sbin/adcli + freeipa-client = /usr/sbin/ipa-client-install + + [commands] +-winbind-enable-logins = /usr/bin/sh -c "/usr/sbin/authconfig --update --enablewinbind --enablewinbindauth --enablemkhomedir --nostart && /usr/bin/systemctl enable oddjobd.service && /usr/bin/systemctl start oddjobd.service" +-winbind-disable-logins = /usr/sbin/authconfig --update --disablewinbind --disablewinbindauth --nostart ++winbind-enable-logins = /usr/bin/sh -c "/usr/bin/authselect select winbind with-mkhomedir --force && /usr/bin/systemctl enable oddjobd.service && /usr/bin/systemctl start oddjobd.service" ++winbind-disable-logins = /usr/bin/authselect select sssd with-mkhomedir + winbind-enable-service = /usr/bin/systemctl enable winbind.service + winbind-disable-service = /usr/bin/systemctl disable winbind.service + winbind-restart-service = /usr/bin/systemctl restart winbind.service + winbind-stop-service = /usr/bin/systemctl stop winbind.service + +-sssd-enable-logins = /usr/bin/sh -c "/usr/sbin/authconfig --update --enablesssd --enablesssdauth --enablemkhomedir --nostart && /usr/bin/systemctl enable oddjobd.service && /usr/bin/systemctl start oddjobd.service" +-sssd-disable-logins = /usr/sbin/authconfig --update --disablesssdauth --nostart ++sssd-enable-logins = /usr/bin/sh -c "/usr/bin/authselect select sssd with-mkhomedir --force && /usr/bin/systemctl enable oddjobd.service && /usr/bin/systemctl start oddjobd.service" ++sssd-disable-logins = /usr/bin/authselect select sssd with-mkhomedir + sssd-enable-service = /usr/bin/systemctl enable sssd.service + sssd-disable-service = /usr/bin/systemctl disable sssd.service + sssd-restart-service = /usr/bin/systemctl restart sssd.service +-- +2.9.3 + diff --git a/0001-tests-ignore-order-in-test_update_domain.patch b/0001-tests-ignore-order-in-test_update_domain.patch new file mode 100644 index 000000000000..2a84abac57b3 --- /dev/null +++ b/0001-tests-ignore-order-in-test_update_domain.patch @@ -0,0 +1,82 @@ +From b6753bd048b4012b11d60c094d1ab6ca181ee50d Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Thu, 21 Feb 2019 21:16:26 +0100 +Subject: [PATCH] tests: ignore order in test_update_domain + +Individual options of a domain or in general for a section in an ini +file are stored by realmd in a hash table. When writing out the ini file +the options can show up in any order and the unit tests should be aware +of it. + +Resolves: https://gitlab.freedesktop.org/realmd/realmd/issues/19 +--- + tests/test-sssd-config.c | 41 ++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 2 deletions(-) + +diff --git a/tests/test-sssd-config.c b/tests/test-sssd-config.c +index 59eab75..8f3fec5 100644 +--- a/tests/test-sssd-config.c ++++ b/tests/test-sssd-config.c +@@ -163,12 +163,49 @@ test_add_domain_only (Test *test, + g_free (output); + } + ++static void check_for_test_update_domain (char *new) ++{ ++ char *token; ++ char *saveptr; ++ size_t c; ++ int result = 0; ++ ++ token = strtok_r (new, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "[domain/one]"); ++ ++ for (c = 0; c < 3; c++) { ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ if (strcmp (token, "val=1") == 0) { ++ result += 1; ++ } else if (strcmp (token, "uno = 1") == 0) { ++ result += 2; ++ } else if (strcmp (token, "eins = one") == 0) { ++ result += 4; ++ } else { ++ g_assert_not_reached (); ++ } ++ } ++ g_assert_cmpint (result, ==, 7); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "[sssd]"); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_nonnull (token); ++ g_assert_cmpstr (token, ==, "domains=one"); ++ ++ token = strtok_r (NULL, "\n", &saveptr); ++ g_assert_null (token); ++} ++ + static void + test_update_domain (Test *test, + gconstpointer unused) + { + const gchar *data = "[domain/one]\nval=1\n[sssd]\ndomains=one"; +- const gchar *check = "[domain/one]\nval=1\nuno = 1\neins = one\n[sssd]\ndomains=one"; + GError *error = NULL; + gchar *output; + gboolean ret; +@@ -190,7 +227,7 @@ test_update_domain (Test *test, + g_assert_no_error (error); + g_assert (ret == TRUE); + +- g_assert_cmpstr (check, ==, output); ++ check_for_test_update_domain (output); + g_free (output); + } + +-- +2.20.1 + diff --git a/0001-tests-run-tests-with-python3.patch b/0001-tests-run-tests-with-python3.patch new file mode 100644 index 000000000000..607afa44655a --- /dev/null +++ b/0001-tests-run-tests-with-python3.patch @@ -0,0 +1,374 @@ +From c257850912897a07e20f205faecf3c1b692fa9e9 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Wed, 4 Jul 2018 16:41:16 +0200 +Subject: [PATCH] tests: run tests with python3 + +To allow the test to run with python3 build/tap-driver and +build/tap-gtester are updated to the latest version provided by the +cockpit project https://github.com/cockpit-project/cockpit. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1595813 +--- + build/tap-driver | 104 +++++++++++++++++++++++++++++++++++++++++++----------- + build/tap-gtester | 59 ++++++++++++++++++++++--------- + 2 files changed, 125 insertions(+), 38 deletions(-) + +diff --git a/build/tap-driver b/build/tap-driver +index 42f57c8..241fd50 100755 +--- a/build/tap-driver ++++ b/build/tap-driver +@@ -1,4 +1,5 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 ++# This can also be run with Python 2. + + # Copyright (C) 2013 Red Hat, Inc. + # +@@ -29,20 +30,58 @@ + # + + import argparse ++import fcntl + import os + import select ++import struct + import subprocess + import sys ++import termios ++import errno ++ ++_PY3 = sys.version[0] >= '3' ++_str = _PY3 and str or unicode ++ ++def out(data, stream=None, flush=False): ++ if not isinstance(data, bytes): ++ data = data.encode("UTF-8") ++ if not stream: ++ stream = _PY3 and sys.stdout.buffer or sys.stdout ++ while True: ++ try: ++ if data: ++ stream.write(data) ++ data = None ++ if flush: ++ stream.flush() ++ flush = False ++ break ++ except IOError as e: ++ if e.errno == errno.EAGAIN: ++ continue ++ raise ++ ++def terminal_width(): ++ try: ++ h, w, hp, wp = struct.unpack('HHHH', ++ fcntl.ioctl(1, termios.TIOCGWINSZ, ++ struct.pack('HHHH', 0, 0, 0, 0))) ++ return w ++ except IOError as e: ++ if e.errno != errno.ENOTTY: ++ sys.stderr.write("%i %s %s\n" % (e.errno, e.strerror, sys.exc_info())) ++ return sys.maxsize + + class Driver: + def __init__(self, args): + self.argv = args.command + self.test_name = args.test_name +- self.log = open(args.log_file, "w") +- self.log.write("# %s\n" % " ".join(sys.argv)) ++ self.log = open(args.log_file, "wb") ++ self.log.write(("# %s\n" % " ".join(sys.argv)).encode("UTF-8")) + self.trs = open(args.trs_file, "w") + self.color_tests = args.color_tests + self.expect_failure = args.expect_failure ++ self.width = terminal_width() - 9 + + def report(self, code, *args): + CODES = { +@@ -57,17 +96,18 @@ class Driver: + # Print out to console + if self.color_tests: + if code in CODES: +- sys.stdout.write(CODES[code]) +- sys.stdout.write(code) ++ out(CODES[code]) ++ out(code) + if self.color_tests: +- sys.stdout.write('\x1b[m') +- sys.stdout.write(": ") +- sys.stdout.write(self.test_name) +- sys.stdout.write(" ") +- for arg in args: +- sys.stdout.write(str(arg)) +- sys.stdout.write("\n") +- sys.stdout.flush() ++ out('\x1b[m') ++ out(": ") ++ msg = "".join([ self.test_name + " " ] + list(map(_str, args))) ++ if code == "PASS" and len(msg) > self.width: ++ out(msg[:self.width]) ++ out("...") ++ else: ++ out(msg) ++ out("\n", flush=True) + + # Book keeping + if code in CODES: +@@ -100,12 +140,14 @@ class Driver: + def execute(self): + try: + proc = subprocess.Popen(self.argv, close_fds=True, ++ stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) +- except OSError, ex: ++ except OSError as ex: + self.report_error("Couldn't run %s: %s" % (self.argv[0], str(ex))) + return + ++ proc.stdin.close() + outf = proc.stdout.fileno() + errf = proc.stderr.fileno() + rset = [outf, errf] +@@ -113,18 +155,25 @@ class Driver: + ret = select.select(rset, [], [], 10) + if outf in ret[0]: + data = os.read(outf, 1024) +- if data == "": ++ if data == b"": + rset.remove(outf) + self.log.write(data) + self.process(data) + if errf in ret[0]: + data = os.read(errf, 1024) +- if data == "": ++ if data == b"": + rset.remove(errf) + self.log.write(data) +- sys.stderr.write(data) ++ stream = _PY3 and sys.stderr.buffer or sys.stderr ++ out(data, stream=stream, flush=True) + + proc.wait() ++ ++ # Make sure the test didn't change blocking output ++ assert fcntl.fcntl(0, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ assert fcntl.fcntl(1, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ assert fcntl.fcntl(2, fcntl.F_GETFL) & os.O_NONBLOCK == 0 ++ + return proc.returncode + + +@@ -137,6 +186,7 @@ class TapDriver(Driver): + self.late_plan = False + self.errored = False + self.bail_out = False ++ self.skip_all_reason = None + + def report(self, code, num, *args): + if num: +@@ -170,13 +220,19 @@ class TapDriver(Driver): + else: + self.result_fail(num, description) + +- def consume_test_plan(self, first, last): ++ def consume_test_plan(self, line): + # Only one test plan is supported + if self.test_plan: + self.report_error("Get a second TAP test plan") + return + ++ if line.lower().startswith('1..0 # skip'): ++ self.skip_all_reason = line[5:].strip() ++ self.bail_out = True ++ return ++ + try: ++ (first, unused, last) = line.partition("..") + first = int(first) + last = int(last) + except ValueError: +@@ -192,7 +248,7 @@ class TapDriver(Driver): + + def process(self, output): + if output: +- self.output += output ++ self.output += output.decode("UTF-8") + elif self.output: + self.output += "\n" + (ready, unused, self.output) = self.output.rpartition("\n") +@@ -202,8 +258,7 @@ class TapDriver(Driver): + elif line.startswith("not ok "): + self.consume_test_line(False, line[7:]) + elif line and line[0].isdigit() and ".." in line: +- (first, unused, last) = line.partition("..") +- self.consume_test_plan(first, last) ++ self.consume_test_plan(line) + elif line.lower().startswith("bail out!"): + self.consume_bail_out(line) + +@@ -213,6 +268,13 @@ class TapDriver(Driver): + failed = False + skipped = True + ++ if self.skip_all_reason is not None: ++ self.result_skip("skipping:", self.skip_all_reason) ++ self.trs.write(":global-test-result: SKIP\n") ++ self.trs.write(":test-global-result: SKIP\n") ++ self.trs.write(":recheck: no\n") ++ return 0 ++ + # Basic collation of results + for (num, code) in self.reported.items(): + if code == "ERROR": +diff --git a/build/tap-gtester b/build/tap-gtester +index 7e667d4..bbda266 100755 +--- a/build/tap-gtester ++++ b/build/tap-gtester +@@ -1,4 +1,5 @@ +-#!/usr/bin/python ++#!/usr/bin/python3 ++# This can also be run with Python 2. + + # Copyright (C) 2014 Red Hat, Inc. + # +@@ -30,9 +31,19 @@ + import argparse + import os + import select ++import signal + import subprocess + import sys + ++# Yes, it's dumb, but strsignal is not exposed in python ++# In addition signal numbers varify heavily from arch to arch ++def strsignal(sig): ++ for name in dir(signal): ++ if name.startswith("SIG") and sig == getattr(signal, name): ++ return name ++ return str(sig) ++ ++ + class NullCompiler: + def __init__(self, command): + self.command = command +@@ -76,22 +87,22 @@ class GTestCompiler(NullCompiler): + elif cmd == "result": + if self.test_name: + if data == "OK": +- print "ok %d %s" % (self.test_num, self.test_name) ++ print("ok %d %s" % (self.test_num, self.test_name)) + if data == "FAIL": +- print "not ok %d %s", (self.test_num, self.test_name) ++ print("not ok %d %s" % (self.test_num, self.test_name)) + self.test_name = None + elif cmd == "skipping": + if "/subprocess" not in data: +- print "ok %d # skip -- %s" % (self.test_num, data) ++ print("ok %d # skip -- %s" % (self.test_num, data)) + self.test_name = None + elif data: +- print "# %s: %s" % (cmd, data) ++ print("# %s: %s" % (cmd, data)) + else: +- print "# %s" % cmd ++ print("# %s" % cmd) + elif line.startswith("(MSG: "): +- print "# %s" % line[6:-1] ++ print("# %s" % line[6:-1]) + elif line: +- print "# %s" % line ++ print("# %s" % line) + sys.stdout.flush() + + def run(self, proc, output=""): +@@ -106,22 +117,26 @@ class GTestCompiler(NullCompiler): + if line.startswith("/"): + self.test_remaining.append(line.strip()) + if not self.test_remaining: +- print "Bail out! No tests found in GTest: %s" % self.command[0] ++ print("Bail out! No tests found in GTest: %s" % self.command[0]) + return 0 + +- print "1..%d" % len(self.test_remaining) ++ print("1..%d" % len(self.test_remaining)) + + # First try to run all the tests in a batch +- proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, ++ stdout=subprocess.PIPE, universal_newlines=True) + result = self.process(proc) + if result == 0: + return 0 + ++ if result < 0: ++ sys.stderr.write("%s terminated with %s\n" % (self.command[0], strsignal(-result))) ++ + # Now pick up any stragglers due to failures + while True: + # Assume that the last test failed + if self.test_name: +- print "not ok %d %s" % (self.test_num, self.test_name) ++ print("not ok %d %s" % (self.test_num, self.test_name)) + self.test_name = None + + # Run any tests which didn't get run +@@ -129,7 +144,8 @@ class GTestCompiler(NullCompiler): + break + + proc = subprocess.Popen(self.command + ["--verbose", "-p", self.test_remaining[0]], +- close_fds=True, stdout=subprocess.PIPE) ++ close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + result = self.process(proc) + + # The various exit codes and signals we continue for +@@ -139,24 +155,32 @@ class GTestCompiler(NullCompiler): + return result + + def main(argv): +- parser = argparse.ArgumentParser(description='Automake TAP compiler') ++ parser = argparse.ArgumentParser(description='Automake TAP compiler', ++ usage="tap-gtester [--format FORMAT] command ...") + parser.add_argument('--format', metavar='FORMAT', choices=[ "auto", "gtest", "tap" ], + default="auto", help='The input format to compile') + parser.add_argument('--verbose', action='store_true', + default=True, help='Verbose mode (ignored)') +- parser.add_argument('command', nargs='+', help="A test command to run") ++ parser.add_argument('command', nargs=argparse.REMAINDER, help="A test command to run") + args = parser.parse_args(argv[1:]) + + output = None + format = args.format + cmd = args.command ++ if not cmd: ++ sys.stderr.write("tap-gtester: specify a command to run\n") ++ return 2 ++ if cmd[0] == '--': ++ cmd.pop(0) ++ + proc = None + + os.environ['HARNESS_ACTIVE'] = '1' + + if format in ["auto", "gtest"]: + list_cmd = cmd + ["-l", "--verbose"] +- proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + output = proc.stdout.readline() + # Smell whether we're dealing with GTest list output from first line + if "random seed" in output or "GTest" in output or output.startswith("/"): +@@ -164,7 +188,8 @@ def main(argv): + else: + format = "tap" + else: +- proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE) ++ proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE, ++ universal_newlines=True) + + if format == "gtest": + compiler = GTestCompiler(cmd) +-- +2.14.4 + diff --git a/0002-Change-qualified-names-default-for-IPA.patch b/0002-Change-qualified-names-default-for-IPA.patch new file mode 100644 index 000000000000..4ac6c6d413d9 --- /dev/null +++ b/0002-Change-qualified-names-default-for-IPA.patch @@ -0,0 +1,113 @@ +From 21ab1fdd127d242a9b4e95c3c90dd2bf3159d149 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Tue, 14 Aug 2018 16:44:39 +0200 +Subject: [PATCH 2/3] Change qualified names default for IPA + +In a FreeIPA domain it is typically expected that the IPA accounts use +sort names while accounts from trusted domains have fully qualified +names. This is automatically done by SSSD's IPA provider so there is no +need to force fully qualified names in the SSSD configuration. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1575538 +--- + service/realm-options.c | 9 +++++---- + service/realm-options.h | 3 ++- + service/realm-samba-winbind.c | 2 +- + service/realm-sssd-ad.c | 2 +- + service/realm-sssd-ipa.c | 2 +- + 5 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/service/realm-options.c b/service/realm-options.c +index bd804ea..34a209f 100644 +--- a/service/realm-options.c ++++ b/service/realm-options.c +@@ -98,7 +98,7 @@ realm_options_automatic_mapping (GVariant *options, + + if (realm_name && !option) { + section = g_utf8_casefold (realm_name, -1); +- mapping = realm_settings_boolean (realm_name, REALM_DBUS_OPTION_AUTOMATIC_ID_MAPPING, TRUE); ++ mapping = realm_settings_boolean (section, REALM_DBUS_OPTION_AUTOMATIC_ID_MAPPING, TRUE); + g_free (section); + } + +@@ -112,20 +112,21 @@ realm_options_automatic_join (const gchar *realm_name) + gboolean mapping; + + section = g_utf8_casefold (realm_name, -1); +- mapping = realm_settings_boolean (realm_name, "automatic-join", FALSE); ++ mapping = realm_settings_boolean (section, "automatic-join", FALSE); + g_free (section); + + return mapping; + } + + gboolean +-realm_options_qualify_names (const gchar *realm_name) ++realm_options_qualify_names (const gchar *realm_name, ++ gboolean def) + { + gchar *section; + gboolean qualify; + + section = g_utf8_casefold (realm_name, -1); +- qualify = realm_settings_boolean (realm_name, "fully-qualified-names", TRUE); ++ qualify = realm_settings_boolean (section, "fully-qualified-names", def); + g_free (section); + + return qualify; +diff --git a/service/realm-options.h b/service/realm-options.h +index 7a1355e..b71d219 100644 +--- a/service/realm-options.h ++++ b/service/realm-options.h +@@ -37,7 +37,8 @@ const gchar * realm_options_user_principal (GVariant *options, + gboolean realm_options_automatic_mapping (GVariant *options, + const gchar *realm_name); + +-gboolean realm_options_qualify_names (const gchar *realm_name); ++gboolean realm_options_qualify_names (const gchar *realm_name, ++ gboolean def); + + gboolean realm_options_check_domain_name (const gchar *domain_name); + +diff --git a/service/realm-samba-winbind.c b/service/realm-samba-winbind.c +index 9335e26..61988eb 100644 +--- a/service/realm-samba-winbind.c ++++ b/service/realm-samba-winbind.c +@@ -102,7 +102,7 @@ realm_samba_winbind_configure_async (RealmIniConfig *config, + "winbind enum groups", "no", + "winbind offline logon", "yes", + "winbind refresh tickets", "yes", +- "winbind use default domain", realm_options_qualify_names (domain_name )? "no" : "yes", ++ "winbind use default domain", realm_options_qualify_names (domain_name, TRUE )? "no" : "yes", + "template shell", realm_settings_string ("users", "default-shell"), + NULL); + +diff --git a/service/realm-sssd-ad.c b/service/realm-sssd-ad.c +index 8543ca8..de7ce30 100644 +--- a/service/realm-sssd-ad.c ++++ b/service/realm-sssd-ad.c +@@ -172,7 +172,7 @@ configure_sssd_for_domain (RealmIniConfig *config, + gchar *home; + + home = realm_sssd_build_default_home (realm_settings_string ("users", "default-home")); +- qualify = realm_options_qualify_names (disco->domain_name); ++ qualify = realm_options_qualify_names (disco->domain_name, TRUE); + shell = realm_settings_string ("users", "default-shell"); + explicit_computer_name = realm_options_computer_name (options, disco->domain_name); + realmd_tags = g_string_new (""); +diff --git a/service/realm-sssd-ipa.c b/service/realm-sssd-ipa.c +index ff1dc8a..5029f6b 100644 +--- a/service/realm-sssd-ipa.c ++++ b/service/realm-sssd-ipa.c +@@ -201,7 +201,7 @@ on_ipa_client_do_restart (GObject *source, + + realm_sssd_config_update_domain (config, domain, &error, + "cache_credentials", "True", +- "use_fully_qualified_names", realm_options_qualify_names (domain) ? "True" : "False", ++ "use_fully_qualified_names", realm_options_qualify_names (domain, FALSE) ? "True" : "False", + "krb5_store_password_if_offline", "True", + "default_shell", shell, + "fallback_homedir", home, +-- +2.17.1 + diff --git a/0002-configure-do-not-inherit-DISTRO-from-the-environment.patch b/0002-configure-do-not-inherit-DISTRO-from-the-environment.patch new file mode 100644 index 000000000000..addff4cae319 --- /dev/null +++ b/0002-configure-do-not-inherit-DISTRO-from-the-environment.patch @@ -0,0 +1,32 @@ +From 506887297ea33339d8ad8b274be643d220bf22f8 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Thu, 28 Nov 2019 18:51:30 +0100 +Subject: [PATCH 2/7] configure: do not inherit DISTRO from the environment + +The argument of the --with-distro configure option is stored in the +variable DISTRO. If DISTRO is already set in the build environment it +should not be used hence DISTRO must be cleared by the configure script +if not set by --with-distro. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1638396 +--- + configure.ac | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index e335247..a424a49 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -31,7 +31,8 @@ AC_ARG_WITH([distro], + [AS_HELP_STRING([--with-distro], + [Configure for a specific distribution (eg: redhat)] + )], +- [DISTRO=$withval]) ++ [DISTRO=$withval], ++ [DISTRO=]) + + if test -z $DISTRO; then + AC_CHECK_FILE(/etc/redhat-release, [DISTRO="redhat"]) +-- +2.25.1 + diff --git a/0002-tools-remove-duplicated-va_start.patch b/0002-tools-remove-duplicated-va_start.patch new file mode 100644 index 000000000000..4d1441cad2db --- /dev/null +++ b/0002-tools-remove-duplicated-va_start.patch @@ -0,0 +1,25 @@ +From 6b41b3292bb826d90fd7986e4a66b20b6fb658b3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 10:39:13 +0200 +Subject: [PATCH 2/7] tools: remove duplicated va_start() + +--- + tools/realm.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/tools/realm.c b/tools/realm.c +index ed8ab3e..4d76a94 100644 +--- a/tools/realm.c ++++ b/tools/realm.c +@@ -52,8 +52,6 @@ realm_print_error (const gchar *format, + GString *message; + va_list va; + +- va_start (va, format); +- + message = g_string_new (""); + g_string_append_printf (message, "%s: ", g_get_prgname ()); + +-- +2.25.1 + diff --git a/0003-discover-try-to-get-domain-name-from-hostname.patch b/0003-discover-try-to-get-domain-name-from-hostname.patch new file mode 100644 index 000000000000..b611d6c8ada8 --- /dev/null +++ b/0003-discover-try-to-get-domain-name-from-hostname.patch @@ -0,0 +1,76 @@ +From 5e28cf702ad338e399f8fff0b3fa18736a297318 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Tue, 21 Aug 2018 13:09:20 +0200 +Subject: [PATCH 3/3] discover: try to get domain name from hostname + +If there is no domain name returned by DHCP check if the hostname +contains a domain part and use this to discover a realm. + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1619162 +--- + service/realm-provider.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/service/realm-provider.c b/service/realm-provider.c +index d647c7a..258e8e1 100644 +--- a/service/realm-provider.c ++++ b/service/realm-provider.c +@@ -28,6 +28,8 @@ + #include <glib/gi18n.h> + #include <gio/gio.h> + ++#include <errno.h> ++ + #define TIMEOUT_SECONDS 15 + + G_DEFINE_TYPE (RealmProvider, realm_provider, G_TYPE_DBUS_OBJECT_SKELETON); +@@ -181,6 +183,25 @@ on_discover_complete (GObject *source, + return_discover_result (method, realms, relevance, error); + } + ++static gchar * ++get_domain_from_hostname (void) ++{ ++ gchar hostname[HOST_NAME_MAX + 1]; ++ gchar *dot; ++ ++ if (gethostname (hostname, sizeof (hostname)) < 0) { ++ g_warning ("Couldn't get the computer host name: %s", g_strerror (errno)); ++ return NULL; ++ } ++ ++ dot = strchr (hostname, '.'); ++ if (dot != NULL) { ++ return g_strdup (dot + 1); ++ } ++ ++ return NULL; ++} ++ + static void + on_discover_default (GObject *source, + GAsyncResult *result, +@@ -195,6 +216,10 @@ on_discover_default (GObject *source, + g_clear_error (&error); + } + ++ if (method->string == NULL) { ++ method->string = get_domain_from_hostname (); ++ } ++ + if (method->string) { + g_strstrip (method->string); + if (g_str_equal (method->string, "")) { +@@ -210,7 +235,8 @@ on_discover_default (GObject *source, + on_discover_complete, method); + + } else { +- realm_diagnostics_info (method->invocation, "No default domain received via DHCP"); ++ realm_diagnostics_info (method->invocation, ++ "No default domain received via DHCP or given by hostname"); + return_discover_result (method, NULL, 0, NULL); + } + } +-- +2.17.1 + diff --git a/0003-doc-extend-user-principal-section.patch b/0003-doc-extend-user-principal-section.patch new file mode 100644 index 000000000000..6384944d124c --- /dev/null +++ b/0003-doc-extend-user-principal-section.patch @@ -0,0 +1,75 @@ +From d6d1ce2f8b1c81903115b018973c61fc71235b7b Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 29 Nov 2019 18:10:03 +0100 +Subject: [PATCH 3/7] doc: extend user-principal section + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1643814 +--- + doc/manual/realm.xml | 21 +++++++++++++++++++-- + doc/manual/realmd.conf.xml | 15 ++++++++++----- + 2 files changed, 29 insertions(+), 7 deletions(-) + +diff --git a/doc/manual/realm.xml b/doc/manual/realm.xml +index 7b73331..55a7640 100644 +--- a/doc/manual/realm.xml ++++ b/doc/manual/realm.xml +@@ -238,10 +238,27 @@ $ realm join --user=admin --computer-ou=OU=Special domain.example.com + </varlistentry> + <varlistentry> + <term><option>--user-principal=<parameter>host/name@REALM</parameter></option></term> +- <listitem><para>Set the userPrincipalName field of the ++ <listitem><para>Set the ++ <option>userPrincipalName</option> field of the + computer account to this kerberos principal. If you omit + the value for this option, then a principal will be set +- in the form of <literal>host/shortname@REALM</literal></para></listitem> ++ based on the defaults of the membership software.</para> ++ <para>AD makes a distinction between user and service ++ principals. Only with user principals you can request a ++ Kerberos Ticket-Granting-Ticket (TGT), i.e. only user ++ principals can be used with the <command>kinit</command> ++ command. By default the user principal and the canonical ++ principal name of an AD computer account is ++ <code>shortname$@AD.DOMAIN</code>, where shortname is ++ the NetBIOS name which is limited to 15 characters.</para> ++ <para>If there are applications which are not aware of ++ the AD default and are using a hard-coded default ++ principal the <option>--user-principal</option> can be ++ used to make AD aware of this principal. Please note ++ that <option>userPrincipalName</option> is a single ++ value LDAP attribute, i.e. only one alternative user ++ principal besides the AD default user principal can be ++ set.</para></listitem> + </varlistentry> + <varlistentry> + <term><option>--os-name=xxx</option></term> +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index f0b0879..a26a60c 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -365,12 +365,17 @@ computer-name = SERVER01 + </listitem> + </varlistentry> + <varlistentry> +- <term><option>user-prinicpal</option></term> ++ <term><option>user-principal</option></term> + <listitem> +- <para>Set the <option>user-prinicpal</option> to <code>yes</code> +- to create <option>userPrincipalName</option> attributes for the +- computer account in the realm, in the form +- <code>host/computer@REALM</code></para> ++ <para>Set the <option>user-principal</option> to <code>yes</code> ++ to create <option>userPrincipalName</option> attribute for the ++ computer accounts in the realm. The exact value depends on the ++ defaults of the used membership software. To have full control ++ over the value please use the ++ <option>--user-principal</option> option of the ++ <command>realm</command> command, see ++ <citerefentry><refentrytitle>realm</refentrytitle> ++ <manvolnum>8</manvolnum></citerefentry> for details.</para> + + <informalexample> + <programlisting language="js"> +-- +2.25.1 + diff --git a/0003-service-remove-dead-code.patch b/0003-service-remove-dead-code.patch new file mode 100644 index 000000000000..82061cff6b32 --- /dev/null +++ b/0003-service-remove-dead-code.patch @@ -0,0 +1,33 @@ +From 4cd0cc0ace4a346444dd34e7f3c6a23fd654fef4 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 11:00:13 +0200 +Subject: [PATCH 3/7] service: remove dead code + +--- + service/realm-samba.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/service/realm-samba.c b/service/realm-samba.c +index 5cf2aa8..e2a3608 100644 +--- a/service/realm-samba.c ++++ b/service/realm-samba.c +@@ -180,7 +180,6 @@ on_join_do_winbind (GObject *source, + GTask *task = G_TASK (user_data); + EnrollClosure *enroll = g_task_get_task_data (task); + RealmSamba *self = g_task_get_source_object (task); +- GHashTable *settings = NULL; + GError *error = NULL; + const gchar *name; + const gchar *computer_name; +@@ -215,8 +214,6 @@ on_join_do_winbind (GObject *source, + g_task_return_error (task, error); + } + +- if (settings) +- g_hash_table_unref (settings); + g_object_unref (task); + } + +-- +2.25.1 + diff --git a/0004-doc-fix-discover-name-only.patch b/0004-doc-fix-discover-name-only.patch new file mode 100644 index 000000000000..36667126062b --- /dev/null +++ b/0004-doc-fix-discover-name-only.patch @@ -0,0 +1,26 @@ +From 878e40f5a3b50d37a0ed981a4f0872a9d5d99e6b Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 29 Nov 2019 18:49:15 +0100 +Subject: [PATCH 4/7] doc: fix discover name-only + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1625001 +--- + doc/manual/realmd.conf.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index a26a60c..fc6a785 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -308,7 +308,7 @@ DOMAIN\user:*:13445:13446:Name:/home/DOMAIN/user:/bin/bash + + <informalexample> + <screen> +-$ <command>realm discover --name DOMAIN.example.com</command> ++$ <command>realm discover --name-only DOMAIN.example.com</command> + domain.example.com + ... + </screen> +-- +2.25.1 + diff --git a/0004-service-check-return-value-of-fcntl.patch b/0004-service-check-return-value-of-fcntl.patch new file mode 100644 index 000000000000..a274de822f53 --- /dev/null +++ b/0004-service-check-return-value-of-fcntl.patch @@ -0,0 +1,36 @@ +From f4636827818d514ebc2f73df2a55b22e7bc8ab89 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 11:00:30 +0200 +Subject: [PATCH 4/7] service: check return value of fcntl() + +--- + service/realm-command.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/service/realm-command.c b/service/realm-command.c +index 2fe02ab..5257caa 100644 +--- a/service/realm-command.c ++++ b/service/realm-command.c +@@ -361,6 +361,7 @@ on_unix_process_child_setup (gpointer user_data) + int *child_fds = user_data; + long val; + guint i; ++ int ret; + + /* + * Become a process leader in order to close the controlling terminal. +@@ -378,7 +379,10 @@ on_unix_process_child_setup (gpointer user_data) + for (i = 0; i < NUM_FDS; i++) { + if (child_fds[i] >= 0) { + val = fcntl (child_fds[i], F_GETFD); +- fcntl (child_fds[i], F_SETFD, val & ~FD_CLOEXEC); ++ ret = fcntl (child_fds[i], F_SETFD, val & ~FD_CLOEXEC); ++ if (ret != 0) { ++ /* ignore */ ++ } + } + } + } +-- +2.25.1 + diff --git a/0005-doc-add-see-also-to-man-pages.patch b/0005-doc-add-see-also-to-man-pages.patch new file mode 100644 index 000000000000..788dbc8cb3cd --- /dev/null +++ b/0005-doc-add-see-also-to-man-pages.patch @@ -0,0 +1,46 @@ +From 799821650c538754aae842d400df75d3bd8864bf Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 29 Nov 2019 18:49:51 +0100 +Subject: [PATCH 5/7] doc: add see also to man pages + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1625001 +--- + doc/manual/realm.xml | 7 +++++++ + doc/manual/realmd.conf.xml | 7 +++++++ + 2 files changed, 14 insertions(+) + +diff --git a/doc/manual/realm.xml b/doc/manual/realm.xml +index 55a7640..e5d4608 100644 +--- a/doc/manual/realm.xml ++++ b/doc/manual/realm.xml +@@ -440,4 +440,11 @@ $ realm deny --all + + </refsect1> + ++<refsect1 id='realm_see_also'> ++ <title>SEE ALSO</title> ++ ++ <para><citerefentry><refentrytitle>realmd.conf</refentrytitle> ++ <manvolnum>5</manvolnum></citerefentry></para> ++</refsect1> ++ + </refentry> +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index fc6a785..1592291 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -471,4 +471,11 @@ fully-qualified-names = no + </variablelist> + </refsect1> + ++<refsect1 id='realmd_conf_see_also'> ++ <title>SEE ALSO</title> ++ ++ <para><citerefentry><refentrytitle>realm</refentrytitle> ++ <manvolnum>8</manvolnum></citerefentry></para> ++</refsect1> ++ + </refentry> +-- +2.25.1 + diff --git a/0005-service-avoid-dereference-of-a-null-pointer.patch b/0005-service-avoid-dereference-of-a-null-pointer.patch new file mode 100644 index 000000000000..76f3acfc5543 --- /dev/null +++ b/0005-service-avoid-dereference-of-a-null-pointer.patch @@ -0,0 +1,39 @@ +From 7a1711b180a746ba574bdbfc814ec706a474cda8 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 11:07:03 +0200 +Subject: [PATCH 5/7] service: avoid dereference of a null pointer + +--- + service/realm-kerberos.c | 2 +- + service/realm-provider.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c +index 252e256..a8b3553 100644 +--- a/service/realm-kerberos.c ++++ b/service/realm-kerberos.c +@@ -720,7 +720,7 @@ realm_kerberos_get_disco (RealmKerberos *self) + if (!disco->kerberos_realm) + disco->kerberos_realm = g_strdup (realm_kerberos_get_realm_name (self)); + klass = REALM_KERBEROS_GET_CLASS (self); +- if (klass->discover_myself) ++ if (klass && klass->discover_myself) + (klass->discover_myself) (self, disco); + self->pv->disco = disco; + } +diff --git a/service/realm-provider.c b/service/realm-provider.c +index 258e8e1..6d7cf96 100644 +--- a/service/realm-provider.c ++++ b/service/realm-provider.c +@@ -450,7 +450,7 @@ realm_provider_get_realms (RealmProvider *self) + + g_return_val_if_fail (REALM_IS_PROVIDER (self), NULL); + klass = REALM_PROVIDER_GET_CLASS (self); +- g_return_val_if_fail (klass->get_realms != NULL, NULL); ++ g_return_val_if_fail (klass != NULL && klass->get_realms != NULL, NULL); + + return (klass->get_realms) (self); + } +-- +2.25.1 + diff --git a/0006-doc-extend-description-of-config-handling.patch b/0006-doc-extend-description-of-config-handling.patch new file mode 100644 index 000000000000..d0b4ed835d25 --- /dev/null +++ b/0006-doc-extend-description-of-config-handling.patch @@ -0,0 +1,104 @@ +From 98a69ca00e3441128b181b59c06bb06e8c362360 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 29 Nov 2019 21:57:02 +0100 +Subject: [PATCH 6/7] doc: extend description of config handling + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1625005 +--- + doc/manual/Makefile.am | 8 ++++++++ + doc/manual/realmd.conf.xml | 15 +++++++++++---- + doc/privatedir.xml.in | 1 + + 4 files changed, 21 insertions(+), 4 deletions(-) + create mode 100644 doc/privatedir.xml.in + +diff --git a/doc/manual/Makefile.am b/doc/manual/Makefile.am +index 8b33fdd..9812c45 100644 +--- a/doc/manual/Makefile.am ++++ b/doc/manual/Makefile.am +@@ -1,14 +1,20 @@ ++XSLTPROC_FLAGS = --path $(abs_builddir):$(abs_srcdir):$(abs_builddir)/doc + + man8_MANS += \ + doc/manual/realm.8 + man5_MANS += \ + doc/manual/realmd.conf.5 + ++$(man5_MANS): doc/privatedir.xml ++ + MAN_IN_FILES = \ + $(man8_MANS:.8=.xml) \ + $(man5_MANS:.5=.xml) \ + $(NULL) + ++doc/privatedir.xml: doc/privatedir.xml.in ++ $(V_SED) $(MKDIR_P) $(dir $@) && $(SED_SUBST) $< > $@ ++ + MANUAL_DOCBOOK = doc/manual/realmd-docs.xml + + MANUAL_INCLUDES = \ +@@ -41,6 +47,7 @@ MANUAL_XSLT = \ + $(NULL) + + EXTRA_DIST += \ ++ doc/privatedir.xml.in \ + $(MANUAL_DOCBOOK) \ + $(MANUAL_INCLUDES) \ + $(MAN_IN_FILES) \ +@@ -50,6 +57,7 @@ EXTRA_DIST += \ + + CLEANFILES += \ + realmd-org.freedesktop.realmd.generated \ ++ doc/privatedir.xml \ + $(DBUS_DOC_GENERATED) \ + $(DBUS_ESCAPED) \ + $(man8_MANS) \ +diff --git a/doc/manual/realmd.conf.xml b/doc/manual/realmd.conf.xml +index 1592291..9062252 100644 +--- a/doc/manual/realmd.conf.xml ++++ b/doc/manual/realmd.conf.xml +@@ -1,6 +1,9 @@ + <?xml version='1.0'?> + <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" +- "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> ++ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" ++[ ++<!ENTITY privatedir SYSTEM "privatedir.xml"> ++]> + + <refentry id="realmd-conf"> + +@@ -35,7 +38,9 @@ + to act in specific ways. This is done by placing settings in a + <filename>/etc/realmd.conf</filename>. This file does not exist by + default. The syntax of this file is the same as an INI file or +- Desktop Entry file.</para> ++ Desktop Entry file. If the file is changed and ++ <command>realmd</command> is running <command>realmd</command> must be ++ restarted to read the new values.</para> + + <para>In general, settings in this file only apply at the point of + joining a domain or realm. Once the realm has been setup the settings +@@ -46,8 +51,10 @@ + + <para>Only specify the settings you wish to override in the + <filename>/etc/realmd.conf</filename> file. Settings not specified will +- be loaded from their packaged defaults. Only override the settings +- below. You may find other settings if you look through the ++ be loaded from their packaged defaults which can be found in ++ <filename>&privatedir;/realmd-defaults.conf</filename> and ++ <filename>&privatedir;/realmd-distro.conf</filename>. Only override the ++ settings below. You may find other settings if you look through the + <command>realmd</command> source code. However these are not guaranteed + to remain stable.</para> + +diff --git a/doc/privatedir.xml.in b/doc/privatedir.xml.in +new file mode 100644 +index 0000000..7f71afe +--- /dev/null ++++ b/doc/privatedir.xml.in +@@ -0,0 +1 @@ ++@privatedir@ +\ No newline at end of file +-- +2.25.1 + diff --git a/0006-service-avoid-dereferencing-a-NULL-pointer.patch b/0006-service-avoid-dereferencing-a-NULL-pointer.patch new file mode 100644 index 000000000000..7936bf08a074 --- /dev/null +++ b/0006-service-avoid-dereferencing-a-NULL-pointer.patch @@ -0,0 +1,24 @@ +From 9675cc5b6318f848ddf7237d50d02606e16d8003 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 28 Sep 2018 11:17:07 +0200 +Subject: [PATCH 6/7] service: avoid dereferencing a NULL pointer + +--- + service/realm-kerberos.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/service/realm-kerberos.c b/service/realm-kerberos.c +index a8b3553..3294932 100644 +--- a/service/realm-kerberos.c ++++ b/service/realm-kerberos.c +@@ -251,6 +251,7 @@ is_credential_supported (RealmKerberosMembershipIface *iface, + gboolean found = FALSE; + gint i; + ++ g_assert (iface != NULL); + g_assert (iface->join_creds != NULL); + g_assert (iface->leave_creds != NULL); + +-- +2.25.1 + diff --git a/0007-service-use-kerberos-method-secrets-and-keytab.patch b/0007-service-use-kerberos-method-secrets-and-keytab.patch new file mode 100644 index 000000000000..fa1bfcf3f4d8 --- /dev/null +++ b/0007-service-use-kerberos-method-secrets-and-keytab.patch @@ -0,0 +1,30 @@ +From 517fa766782421302da827278ca17e6b2ad57da3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose <sbose@redhat.com> +Date: Fri, 21 Feb 2020 14:06:16 +0100 +Subject: [PATCH 7/7] service: use "kerberos method" "secrets and keytab" + +When using Samba with Winbind the host password stored in secrets.tdb is +still important so the "secrets and keytab" should be the preferred +"kerberos method". + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1801195 +--- + service/realm-samba.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/service/realm-samba.c b/service/realm-samba.c +index e2a3608..4940b38 100644 +--- a/service/realm-samba.c ++++ b/service/realm-samba.c +@@ -200,7 +200,7 @@ on_join_do_winbind (GObject *source, + "template shell", realm_settings_string ("users", "default-shell"), + "netbios name", computer_name, + "password server", enroll->disco->explicit_server, +- "kerberos method", "system keytab", ++ "kerberos method", "secrets and keytab", + NULL); + } + +-- +2.25.1 + @@ -3,7 +3,7 @@ pkgname=realmd pkgver=0.16.3 -pkgrel=1 +pkgrel=2 pkgdesc="DBus service for joining hosts to Active Directory and FreeIPA realms" arch=(i686 x86_64) url="https://freedesktop.org/software/realmd/" @@ -13,19 +13,89 @@ optdepends=('sssd: Active Directory, FreeIPA, LDAP client' 'samba: traditional Active Directory client') makedepends=(docbook-xsl git intltool python xmlto) source=("https://www.freedesktop.org/software/realmd/releases/$pkgname-$pkgver.tar.gz" - "https://www.freedesktop.org/software/realmd/releases/$pkgname-$pkgver.tar.gz.sig") + "https://www.freedesktop.org/software/realmd/releases/$pkgname-$pkgver.tar.gz.sig" + 0001-Add-missing-xsl-file-to-Makefile.am.patch + 0001-doc-make-sure-cross-reference-ids-are-predictable.patch + 0001-Find-NetBIOS-name-in-keytab-while-leaving.patch + 0001-Fix-issues-found-by-Coverity.patch + 0001-Fix-man-page-reference-in-systemd-service-file.patch + 0001-IPA-do-not-call-sssd-enable-logins.patch + 0001-Kerberos-fall-back-to-tcp-SRV-lookup.patch + 0001-LDAP-don-t-close-LDAP-socket-twice.patch + 0001-Remove-support-for-deprecated-gtester-format.patch + 0001-service-Add-nss-and-pam-sssd.conf-services-after-joi.patch + 0001-service-Add-pam-and-nss-services-in-realm_sssd_confi.patch + 0001-Set-NEWEST-flag-when-resolving-packages-with-Package.patch + 0001-switch-to-authselect.patch + 0001-tests-ignore-order-in-test_update_domain.patch + 0001-tests-run-tests-with-python3.patch + 0001-Use-current-idmap-options-for-smb.conf.patch + 0002-Change-qualified-names-default-for-IPA.patch + 0002-configure-do-not-inherit-DISTRO-from-the-environment.patch + 0002-tools-remove-duplicated-va_start.patch + 0003-discover-try-to-get-domain-name-from-hostname.patch + 0003-doc-extend-user-principal-section.patch + 0003-service-remove-dead-code.patch + 0004-doc-fix-discover-name-only.patch + 0004-service-check-return-value-of-fcntl.patch + 0005-doc-add-see-also-to-man-pages.patch + 0005-service-avoid-dereference-of-a-null-pointer.patch + 0006-doc-extend-description-of-config-handling.patch + 0006-service-avoid-dereferencing-a-NULL-pointer.patch + 0007-service-use-kerberos-method-secrets-and-keytab.patch + computer-ou.patch + duplicate-test-path.patch + install-diagnostic.patch) sha256sums=('d8943f66a2a666fee8be026d82a66904c0a5125aab7ef74504456ce269687dda' - 'SKIP') + 'SKIP' + '6db7704e9342efd801ec24949f1002a8e26ac67c4f04638ca51977940ef3ac1d' + 'ea5a2b311f76ebfea0c88c2cf333c007ea5db32316935bbd5dd6883450edd5a3' + 'faffd409b53b46c67d4f776e252e49025a63f9963796e12ef6f487d416310958' + '262764b9acbe2c84348d8f9a7b759bd08d10c04ef779c4f390c3f6650ef6d96a' + 'cb376d3b6e90be4aa84a1d42d4d395f5a8f0aedfbf719277e549f08928e3a985' + '2c79e27e504d24b22a06bce567a3aa96348e1bb0682db4e042c96165f799c500' + 'a56748ad07b75e346dccedead2ec50053bfe3c3084f9c804b8fae6d961977236' + '65f4b0d4d8f51e55e9adc5b8d2896a3abf159f311fc9d3a99ae2df906181e04d' + '440ae6ac9d7b4e08440dc1382cfc243e28d69dfcf010f8335e3699c40eda9d63' + 'f25dd08914fb493d8b8e6ff5bd44d8398d0498116a874effb314f2cd6e26446d' + '6b3a36fdb36655940194ec0b53dcec7e97a4a79a0427863c8a905ad67c9c1714' + '512def4faeaa0cd283161fbb05f2bba16bd2d2373d681a99248e78ede958b0fe' + '47d7a73329a7dbb4754ab7bd3ed436799cbd21b4f555a0a0ab50c27944817335' + 'f408dc7c2263b01e97b66ec068fc48ba5597a3d13e55a60d26008ae309a7787d' + 'f3a584270e3e0d6a76c9aeb1dbf078c864b78d948c3277d6899b0b40f8a58030' + '8346081c5a8c1efbd5c33890e530fdd84906d394737a1a2cd5a8e2f5fb4f64b6' + 'd93b5ba71204cbcb70bab02bf990068d04d4be1888f23c251e2c512c8bb0caeb' + '86640fbf9a7f5d7606529584902dcee96fd13cb50c673d785ec04ab525364119' + '1daa4159e6fe20131111112b6127ca823b2355a2ef7895840959168af00a5483' + 'e4922a6c16c7fd41a2903a5857876c679fd9c257569fe35a4b08ffaabfd016e7' + 'eeca4747df151ab624feeefdeda4274da3703681074f21789a69a2eb73da9ca4' + 'd594af102566775b4bb0cf59554c69c20721d7db935ac69a3fbc86f28f1226bc' + '6fc569eb9641503352fb5f19cb2c5dd16a0e8c888c7e4ea652b55a8e9e69ff6e' + 'a962c7b5f3cf2dba39d16195ad7bb1a9d2db9d2292d74d6e65879c220791b871' + '3ef0438e83ec4cefba482435d8c22d69bbb8e93b24032a83ad139481ecbda817' + '76e511fe1033f19c8499b4edcc3410eede375ceff968f4ac08cd6333c7e33c2a' + '77bad53ed4f36ae51f3c81b0195fb898fa6c9f79a377550f51551423c12dcff0' + '682a5f7af3e4bdc0bfa5ed2f7ad654e9d311666995520ae2997898edb9264bdc' + '950d252020635b4415551fcf9fcacc06ade8497a639b25661b138341b327ea24' + '5e43d034348bdf3cb3f06ebd56d811b3427e43f9220fee9a104f50d3972cb5cd' + 'a659dfcf8e4f91123832ae89b9ac92bbcc9ea8d90a698533ca25dff9ec610d90' + 'e49fc613594d4fb540f0a562778e2fd45711548cbe3dc9769f5aa0773de16319') validpgpkeys=('C0F67099B808FB063E2C81117BFB1108D92765AF') prepare() { cd "$pkgname-$pkgver" - AUTOMAKE=automake ACLOCAL=aclocal NOCONFIGURE=1 ./autogen.sh + local src + for src in "${source[@]}"; do + src="${src%%::*}" + src="${src##*/}" + [[ $src = 0*.patch ]] || continue + echo "Applying patch $src..." + patch -Np1 < "../$src" + done } - build() { cd "$pkgname-$pkgver" - ./configure \ + AUTOMAKE=automake ACLOCAL=aclocal ./configure \ --prefix=/usr \ --sbindir=/usr/bin \ --sysconfdir=/etc \ diff --git a/computer-ou.patch b/computer-ou.patch new file mode 100644 index 000000000000..39c8fadfd916 --- /dev/null +++ b/computer-ou.patch @@ -0,0 +1,894 @@ +From 3db35ad73ec57c8af499a0dcef96ffd4da914236 Mon Sep 17 00:00:00 2001 +From: Stef Walter <stefw@redhat.com> +Date: Mon, 7 Sep 2015 13:49:10 +0200 +Subject: [PATCH 2/2] service: Fully qualify --computer-ou DN before passing to + adcli + +This allows us to have a similar behavior for both the Samba and +adcli membership software. +--- + service/Makefile.am | 4 +- + service/realm-adcli-enroll.c | 11 +- + service/realm-dn-util.c | 239 +++++++++++++++++++++++++++++++++++++++++++ + service/realm-dn-util.h | 32 ++++++ + service/realm-samba-enroll.c | 4 +- + service/realm-samba-util.c | 172 ------------------------------- + service/realm-samba-util.h | 29 ------ + tests/Makefile.am | 16 +-- + tests/test-dn-util.c | 129 +++++++++++++++++++++++ + tests/test-samba-ou-format.c | 89 ---------------- + 11 files changed, 422 insertions(+), 305 deletions(-) + create mode 100644 service/realm-dn-util.c + create mode 100644 service/realm-dn-util.h + delete mode 100644 service/realm-samba-util.c + delete mode 100644 service/realm-samba-util.h + create mode 100644 tests/test-dn-util.c + delete mode 100644 tests/test-samba-ou-format.c + +diff --git a/service/Makefile.am b/service/Makefile.am +index 06a95ef..88ee780 100644 +--- a/service/Makefile.am ++++ b/service/Makefile.am +@@ -43,6 +43,8 @@ realmd_SOURCES = \ + service/realm-disco-mscldap.h \ + service/realm-disco-rootdse.c \ + service/realm-disco-rootdse.h \ ++ service/realm-dn-util.c \ ++ service/realm-dn-util.h \ + service/realm-errors.c \ + service/realm-errors.h \ + service/realm-example.c \ +@@ -79,8 +81,6 @@ realmd_SOURCES = \ + service/realm-samba-enroll.h \ + service/realm-samba-provider.c \ + service/realm-samba-provider.h \ +- service/realm-samba-util.c \ +- service/realm-samba-util.h \ + service/realm-samba-winbind.c \ + service/realm-samba-winbind.h \ + service/realm-service.c \ +diff --git a/service/realm-adcli-enroll.c b/service/realm-adcli-enroll.c +index 7448647..ef1b563 100644 +--- a/service/realm-adcli-enroll.c ++++ b/service/realm-adcli-enroll.c +@@ -18,6 +18,7 @@ + #include "realm-command.h" + #include "realm-daemon.h" + #include "realm-diagnostics.h" ++#include "realm-dn-util.h" + #include "realm-errors.h" + #include "realm-ini-config.h" + #include "realm-options.h" +@@ -82,6 +83,7 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + gchar *ccache_arg = NULL; + gchar *upn_arg = NULL; + gchar *server_arg = NULL; ++ gchar *ou_arg = NULL; + + g_return_if_fail (cred != NULL); + g_return_if_fail (disco != NULL); +@@ -120,9 +122,13 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + } + + computer_ou = realm_options_computer_ou (options, disco->domain_name); +- if (computer_ou) { ++ if (computer_ou != NULL) { ++ ou_arg = realm_dn_util_build_qualified (computer_ou, disco->domain_name); + g_ptr_array_add (args, "--computer-ou"); +- g_ptr_array_add (args, (gpointer)computer_ou); ++ if (ou_arg) ++ g_ptr_array_add (args, ou_arg); ++ else ++ g_ptr_array_add (args, (gpointer)computer_ou); + } + + os = realm_settings_value ("active-directory", "os-name"); +@@ -190,6 +196,7 @@ realm_adcli_enroll_join_async (RealmDisco *disco, + free (ccache_arg); + free (upn_arg); + free (server_arg); ++ free (ou_arg); + } + + gboolean +diff --git a/service/realm-dn-util.c b/service/realm-dn-util.c +new file mode 100644 +index 0000000..85bcdb9 +--- /dev/null ++++ b/service/realm-dn-util.c +@@ -0,0 +1,239 @@ ++/* realmd -- Realm configuration service ++ * ++ * Copyright 2012 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: Stef Walter <stefw@gnome.org> ++ */ ++ ++#include "config.h" ++ ++#include "realm-dn-util.h" ++ ++#include <glib.h> ++ ++#include <ldap.h> ++ ++static gboolean ++berval_is_string (const struct berval *bv, ++ const gchar *string, ++ gsize length) ++{ ++ return (bv->bv_len == length && ++ g_ascii_strncasecmp (bv->bv_val, string, length) == 0); ++ ++} ++ ++static gboolean ++berval_case_equals (const struct berval *v1, ++ const struct berval *v2) ++{ ++ return (v1->bv_len == v2->bv_len && ++ g_ascii_strncasecmp (v1->bv_val, v2->bv_val, v1->bv_len) == 0); ++} ++ ++static gboolean ++dn_equals_domain (LDAPDN dn, ++ const gchar *domain_dn_str, ++ const gchar *domain) ++{ ++ LDAPDN domain_dn; ++ gboolean ret; ++ int rc; ++ gint i, j; ++ ++ rc = ldap_str2dn (domain_dn_str, &domain_dn, LDAP_DN_FORMAT_LDAPV3); ++ g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE); ++ ++ for (i = 0; dn[i] != NULL && domain_dn[i] != NULL; i++) { ++ for (j = 0; dn[i][j] != NULL && domain_dn[i][j] != NULL; j++) { ++ if (!berval_case_equals (&(dn[i][j]->la_attr), &(domain_dn[i][j]->la_attr)) || ++ !berval_case_equals (&(dn[i][j]->la_value), &(domain_dn[i][j]->la_value))) ++ break; ++ } ++ ++ if (dn[i][j] != NULL && domain_dn[i][j] != NULL) ++ break; ++ } ++ ++ /* Did we reach end of both DNs? */ ++ ret = (dn[i] == NULL && domain_dn[i] == NULL); ++ ++ ldap_dnfree (domain_dn); ++ ++ return ret; ++} ++ ++gchar * ++realm_dn_util_build_samba_ou (const gchar *ldap_dn, ++ const gchar *domain) ++{ ++ gchar *domain_dn_str = NULL; ++ GArray *parts; ++ GString *part; ++ gchar **strv; ++ gchar *str; ++ LDAPAVA* ava; ++ gboolean ret; ++ LDAPDN dn; ++ int rc; ++ gint i, j; ++ ++ /* ++ * Here we convert a standard LDAP DN to the strange samba net format, ++ * as "documented" here: ++ * ++ * createcomputer=OU Precreate the computer account in a specific OU. ++ * The OU string read from top to bottom without RDNs and delimited by a '/'. ++ * E.g. "createcomputer=Computers/Servers/Unix" ++ * NB: A backslash '\' is used as escape at multiple levels and may ++ * need to be doubled or even quadrupled. It is not used as a separator. ++ */ ++ ++ /* ldap_str2dn doesn't like empty strings */ ++ while (g_ascii_isspace (ldap_dn[0])) ++ ldap_dn++; ++ if (g_str_equal (ldap_dn, "")) ++ return NULL; ++ ++ rc = ldap_str2dn (ldap_dn, &dn, LDAP_DN_FORMAT_LDAPV3); ++ if (rc != LDAP_SUCCESS) ++ return NULL; ++ ++ ret = TRUE; ++ parts = g_array_new (TRUE, TRUE, sizeof (gchar *)); ++ ++ for (i = 0; dn[i] != NULL; i++) { ++ ava = dn[i][0]; ++ ++ /* ++ * Make sure this is a valid DN, we only support one value per ++ * RDN, string values, and must be an OU. DC values are allowed ++ * but only at the end of the DN. ++ */ ++ ++ if (ava == NULL || dn[i][1] != NULL || !(ava->la_flags & LDAP_AVA_STRING)) { ++ ret = FALSE; ++ break; ++ ++ /* A DC, remainder must match the domain */ ++ } else if (berval_is_string (&ava->la_attr, "DC", 2)) { ++ rc = ldap_domain2dn (domain, &domain_dn_str); ++ if (rc != LDAP_SUCCESS) ++ ret = FALSE; ++ else ++ ret = dn_equals_domain (dn + i, domain_dn_str, domain); ++ break; ++ ++ /* An OU, include */ ++ } else if (berval_is_string (&ava->la_attr, "OU", 2)) { ++ part = g_string_sized_new (ava->la_value.bv_len); ++ for (j = 0; j < ava->la_value.bv_len; j++) { ++ switch (ava->la_value.bv_val[j]) { ++ case '\\': ++ g_string_append (part, "\\\\"); ++ break; ++ case '/': ++ g_string_append (part, "\\/"); ++ break; ++ default: ++ g_string_append_c (part, ava->la_value.bv_val[j]); ++ break; ++ } ++ } ++ str = g_string_free (part, FALSE); ++ g_array_insert_val (parts, 0, str); ++ ++ /* Invalid, stop */ ++ } else { ++ ret = FALSE; ++ break; ++ } ++ } ++ ++ ldap_dnfree (dn); ++ if (domain_dn_str) ++ ldap_memfree (domain_dn_str); ++ ++ strv = (gchar **)g_array_free (parts, FALSE); ++ str = NULL; ++ ++ /* Loop completed successfully */ ++ if (ret) ++ str = g_strjoinv ("/", strv); ++ ++ g_strfreev (strv); ++ ++ return str; ++} ++ ++gchar * ++realm_dn_util_build_qualified (const gchar *ldap_dn, ++ const gchar *domain) ++{ ++ gchar *domain_dn_str = NULL; ++ gboolean had_dc = FALSE; ++ gchar *str; ++ LDAPAVA* ava; ++ gboolean ret; ++ LDAPDN dn; ++ int rc; ++ gint i; ++ ++ /* ldap_str2dn doesn't like empty strings */ ++ while (g_ascii_isspace (ldap_dn[0])) ++ ldap_dn++; ++ if (g_str_equal (ldap_dn, "")) ++ return NULL; ++ ++ rc = ldap_str2dn (ldap_dn, &dn, LDAP_DN_FORMAT_LDAPV3); ++ if (rc != LDAP_SUCCESS) ++ return NULL; ++ ++ rc = ldap_domain2dn (domain, &domain_dn_str); ++ if (rc != LDAP_SUCCESS) { ++ ldap_dnfree (dn); ++ return NULL; ++ } ++ ++ ret = TRUE; ++ ++ for (i = 0; dn[i] != NULL; i++) { ++ ava = dn[i][0]; ++ ++ /* ++ * Make sure this is a valid DN, we only support one value per ++ * RDN, string values. DC values are allowed but only at the end of the DN. ++ */ ++ ++ if (ava == NULL || dn[i][1] != NULL || !(ava->la_flags & LDAP_AVA_STRING)) { ++ ret = FALSE; ++ break; ++ ++ /* A DC, remainder must match the domain */ ++ } else if (berval_is_string (&ava->la_attr, "DC", 2)) { ++ had_dc = TRUE; ++ ret = dn_equals_domain (dn + i, domain_dn_str, domain); ++ break; ++ } ++ } ++ ++ ldap_dnfree (dn); ++ ++ if (!ret) ++ return NULL; ++ ++ if (had_dc) ++ str = g_strdup (ldap_dn); ++ else ++ str = g_strdup_printf ("%s,%s", ldap_dn, domain_dn_str); ++ ++ ldap_memfree (domain_dn_str); ++ return str; ++} +diff --git a/service/realm-dn-util.h b/service/realm-dn-util.h +new file mode 100644 +index 0000000..f5e5e69 +--- /dev/null ++++ b/service/realm-dn-util.h +@@ -0,0 +1,32 @@ ++/* realmd -- Realm configuration service ++ * ++ * Copyright 2012 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: Stef Walter <stefw@gnome.org> ++ */ ++ ++#include "config.h" ++ ++#ifndef __REALM_DN_UTIL_H__ ++#define __REALM_DN_UTIL_H__ ++ ++#include <gio/gio.h> ++ ++G_BEGIN_DECLS ++ ++gchar * realm_dn_util_build_samba_ou (const gchar *ldap_dn, ++ const gchar *domain); ++ ++gchar * realm_dn_util_build_qualified (const gchar *ldap_dn, ++ const gchar *domain); ++ ++G_END_DECLS ++ ++#endif /* __REALM_DN_UTIL_H__ */ +diff --git a/service/realm-samba-enroll.c b/service/realm-samba-enroll.c +index e8739d7..e749764 100644 +--- a/service/realm-samba-enroll.c ++++ b/service/realm-samba-enroll.c +@@ -18,12 +18,12 @@ + #include "realm-daemon.h" + #include "realm-dbus-constants.h" + #include "realm-diagnostics.h" ++#include "realm-dn-util.h" + #include "realm-errors.h" + #include "realm-options.h" + #include "realm-samba-config.h" + #include "realm-samba-enroll.h" + #include "realm-samba-provider.h" +-#include "realm-samba-util.h" + #include "realm-settings.h" + + #include <glib/gstdio.h> +@@ -314,7 +314,7 @@ begin_join (GTask *task, + + computer_ou = realm_options_computer_ou (options, join->disco->domain_name); + if (computer_ou != NULL) { +- strange_ou = realm_samba_util_build_strange_ou (computer_ou, join->disco->domain_name); ++ strange_ou = realm_dn_util_build_samba_ou (computer_ou, join->disco->domain_name); + if (strange_ou) { + if (!g_str_equal (strange_ou, "")) + join->join_args[at++] = g_strdup_printf ("createcomputer=%s", strange_ou); +diff --git a/service/realm-samba-util.c b/service/realm-samba-util.c +deleted file mode 100644 +index 3f6a53e..0000000 +--- a/service/realm-samba-util.c ++++ /dev/null +@@ -1,172 +0,0 @@ +-/* realmd -- Realm configuration service +- * +- * Copyright 2012 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: Stef Walter <stefw@gnome.org> +- */ +- +-#include "config.h" +- +-#include "realm-samba-util.h" +- +-#include <glib.h> +- +-#include <ldap.h> +- +-static gboolean +-berval_is_string (const struct berval *bv, +- const gchar *string, +- gsize length) +-{ +- return (bv->bv_len == length && +- g_ascii_strncasecmp (bv->bv_val, string, length) == 0); +- +-} +- +-static gboolean +-berval_case_equals (const struct berval *v1, +- const struct berval *v2) +-{ +- return (v1->bv_len == v2->bv_len && +- g_ascii_strncasecmp (v1->bv_val, v2->bv_val, v1->bv_len) == 0); +-} +- +-static gboolean +-dn_equals_domain (LDAPDN dn, +- const gchar *domain) +-{ +- LDAPDN domain_dn; +- gchar *domain_dn_str; +- gboolean ret; +- int rc; +- gint i, j; +- +- rc = ldap_domain2dn (domain, &domain_dn_str); +- g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE); +- +- rc = ldap_str2dn (domain_dn_str, &domain_dn, LDAP_DN_FORMAT_LDAPV3); +- g_return_val_if_fail (rc == LDAP_SUCCESS, FALSE); +- +- ldap_memfree (domain_dn_str); +- +- for (i = 0; dn[i] != NULL && domain_dn[i] != NULL; i++) { +- for (j = 0; dn[i][j] != NULL && domain_dn[i][j] != NULL; j++) { +- if (!berval_case_equals (&(dn[i][j]->la_attr), &(domain_dn[i][j]->la_attr)) || +- !berval_case_equals (&(dn[i][j]->la_value), &(domain_dn[i][j]->la_value))) +- break; +- } +- +- if (dn[i][j] != NULL && domain_dn[i][j] != NULL) +- break; +- } +- +- /* Did we reach end of both DNs? */ +- ret = (dn[i] == NULL && domain_dn[i] == NULL); +- +- ldap_dnfree (domain_dn); +- +- return ret; +-} +- +-gchar * +-realm_samba_util_build_strange_ou (const gchar *ldap_dn, +- const gchar *domain) +-{ +- GArray *parts; +- GString *part; +- gchar **strv; +- gchar *str; +- LDAPAVA* ava; +- gboolean ret; +- LDAPDN dn; +- int rc; +- gint i, j; +- +- /* +- * Here we convert a standard LDAP DN to the strange samba net format, +- * as "documented" here: +- * +- * createcomputer=OU Precreate the computer account in a specific OU. +- * The OU string read from top to bottom without RDNs and delimited by a '/'. +- * E.g. "createcomputer=Computers/Servers/Unix" +- * NB: A backslash '\' is used as escape at multiple levels and may +- * need to be doubled or even quadrupled. It is not used as a separator. +- */ +- +- /* ldap_str2dn doesn't like empty strings */ +- while (g_ascii_isspace (ldap_dn[0])) +- ldap_dn++; +- if (g_str_equal (ldap_dn, "")) +- return NULL; +- +- rc = ldap_str2dn (ldap_dn, &dn, LDAP_DN_FORMAT_LDAPV3); +- if (rc != LDAP_SUCCESS) +- return NULL; +- +- ret = TRUE; +- parts = g_array_new (TRUE, TRUE, sizeof (gchar *)); +- +- for (i = 0; dn[i] != NULL; i++) { +- ava = dn[i][0]; +- +- /* +- * Make sure this is a valid DN, we only support one value per +- * RDN, string values, and must be an OU. DC values are allowed +- * but only at the end of the DN. +- */ +- +- if (ava == NULL || dn[i][1] != NULL || !(ava->la_flags & LDAP_AVA_STRING)) { +- ret = FALSE; +- break; +- +- /* A DC, remainder must match the domain */ +- } else if (berval_is_string (&ava->la_attr, "DC", 2)) { +- ret = dn_equals_domain (dn + i, domain); +- break; +- +- /* An OU, include */ +- } else if (berval_is_string (&ava->la_attr, "OU", 2)) { +- part = g_string_sized_new (ava->la_value.bv_len); +- for (j = 0; j < ava->la_value.bv_len; j++) { +- switch (ava->la_value.bv_val[j]) { +- case '\\': +- g_string_append (part, "\\\\"); +- break; +- case '/': +- g_string_append (part, "\\/"); +- break; +- default: +- g_string_append_c (part, ava->la_value.bv_val[j]); +- break; +- } +- } +- str = g_string_free (part, FALSE); +- g_array_insert_val (parts, 0, str); +- +- /* Invalid, stop */ +- } else { +- ret = FALSE; +- break; +- } +- } +- +- ldap_dnfree (dn); +- +- strv = (gchar **)g_array_free (parts, FALSE); +- str = NULL; +- +- /* Loop completed successfully */ +- if (ret) +- str = g_strjoinv ("/", strv); +- +- g_strfreev (strv); +- +- return str; +-} +diff --git a/service/realm-samba-util.h b/service/realm-samba-util.h +deleted file mode 100644 +index 2a680e7..0000000 +--- a/service/realm-samba-util.h ++++ /dev/null +@@ -1,29 +0,0 @@ +-/* realmd -- Realm configuration service +- * +- * Copyright 2012 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: Stef Walter <stefw@gnome.org> +- */ +- +-#include "config.h" +- +-#ifndef __REALM_SAMBA_UTIL_H__ +-#define __REALM_SAMBA_UTIL_H__ +- +-#include <gio/gio.h> +- +-G_BEGIN_DECLS +- +-gchar * realm_samba_util_build_strange_ou (const gchar *ldap_dn, +- const gchar *suffix_dn); +- +-G_END_DECLS +- +-#endif /* __REALM_SAMBA_UTIL_H__ */ +diff --git a/tests/Makefile.am b/tests/Makefile.am +index ddeba4d..3b05066 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -12,11 +12,11 @@ TEST_LIBS = \ + $(GLIB_LIBS) + + TEST_PROGS = \ ++ test-dn-util \ + test-ini-config \ + test-sssd-config \ + test-safe-format \ + test-login-name \ +- test-samba-ou-format \ + test-settings \ + $(NULL) + +@@ -27,6 +27,13 @@ noinst_PROGRAMS += \ + frob-install-packages \ + $(NULL) + ++test_dn_util_SOURCES = \ ++ tests/test-dn-util.c \ ++ service/realm-dn-util.c \ ++ $(NULL) ++test_dn_util_LDADD = $(TEST_LIBS) ++test_dn_util_CFLAGS = $(TEST_CFLAGS) ++ + test_ini_config_SOURCES = \ + tests/test-ini-config.c \ + service/realm-ini-config.c \ +@@ -59,13 +66,6 @@ test_login_name_SOURCES = \ + test_login_name_LDADD = $(TEST_LIBS) + test_login_name_CFLAGS = $(TEST_CFLAGS) + +-test_samba_ou_format_SOURCES = \ +- tests/test-samba-ou-format.c \ +- service/realm-samba-util.c \ +- $(NULL) +-test_samba_ou_format_LDADD = $(TEST_LIBS) +-test_samba_ou_format_CFLAGS = $(TEST_CFLAGS) +- + test_settings_SOURCES = \ + tests/test-settings.c \ + service/realm-settings.c \ +diff --git a/tests/test-dn-util.c b/tests/test-dn-util.c +new file mode 100644 +index 0000000..c62a40f +--- /dev/null ++++ b/tests/test-dn-util.c +@@ -0,0 +1,129 @@ ++/* realmd -- Realm configuration service ++ * ++ * Copyright 2012 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: Stef Walter <stefw@gnome.org> ++ */ ++ ++#include "config.h" ++ ++#include "service/realm-dn-util.h" ++ ++#include <glib/gstdio.h> ++ ++#include <string.h> ++ ++typedef struct { ++ const gchar *ldap_dn; ++ const gchar *domain; ++ const gchar *result; ++} Fixture; ++ ++static void ++test_samba_ou_format (gconstpointer user_data) ++{ ++ const Fixture *fixture = user_data; ++ gchar *result; ++ ++ result = realm_dn_util_build_samba_ou (fixture->ldap_dn, fixture->domain); ++ g_assert_cmpstr (result, ==, fixture->result); ++ g_free (result); ++} ++ ++static const Fixture samba_ou_fixtures[] = { ++ { "OU=One", "domain.example.com", "One" }, ++ { "OU=One,ou=two", "domain.example.com", "two/One" }, ++ { "Ou=One Long,OU=two", "domain.example.com", "two/One Long" }, ++ { "Ou=One,OU=two, ou=Three", "domain.example.com", "Three/two/One" }, ++ { "Ou=Test/Escape,Ou=Two", "domain.example.com", "Two/Test\\/Escape" }, ++ { "Ou=Test\\\\Escape,Ou=Two", "domain.example.com", "Two/Test\\\\Escape" }, ++ { "OU=One,DC=domain,dc=example,Dc=COM", "domain.example.com", "One" }, ++ { "OU=One,OU=Two Here,DC=domain,dc=example,Dc=COM", "domain.example.com", "Two Here/One" }, ++ { "OU=One,OU=Two Here,DC=invalid,Dc=COM", "domain.example.com", NULL }, ++ { " ", "domain.example.com", NULL }, ++ { "", "domain.example.com", NULL }, ++ { "OU", "domain.example.com", NULL }, ++ { "OU=One,", "domain.example.com", NULL }, ++ { "CN=Unsupported", "domain.example.com", NULL }, ++ { "OU=One+CN=Unsupported", "domain.example.com", NULL }, ++ { "DC=radi07, DC=segad, DC=lab, DC=sjc, DC=redhat, DC=com", "radi08.segad.lab.sjc.redhat.com", NULL }, ++ ++}; ++ ++static void ++test_qualify_dn (gconstpointer user_data) ++{ ++ const Fixture *fixture = user_data; ++ gchar *result; ++ ++ result = realm_dn_util_build_qualified (fixture->ldap_dn, fixture->domain); ++ g_assert_cmpstr (result, ==, fixture->result); ++ g_free (result); ++} ++ ++static const Fixture qualify_fixtures[] = { ++ { "OU=One", "domain.example.com", "OU=One,dc=domain,dc=example,dc=com" }, ++ { "OU=One,ou=two", "domain.example.com", "OU=One,ou=two,dc=domain,dc=example,dc=com" }, ++ { "Ou=One Long,OU=two", "domain.example.com", "Ou=One Long,OU=two,dc=domain,dc=example,dc=com" }, ++ { "OU=One,DC=domain,dc=example,Dc=COM", "domain.example.com", "OU=One,DC=domain,dc=example,Dc=COM" }, ++ { "OU=One,OU=Two Here,DC=domain,dc=example,Dc=COM", "domain.example.com", "OU=One,OU=Two Here,DC=domain,dc=example,Dc=COM" }, ++ { "OU=One,OU=Two Here,DC=invalid,Dc=COM", "domain.example.com", NULL }, ++ { " ", "domain.example.com", NULL }, ++ { "", "domain.example.com", NULL }, ++ { "OU", "domain.example.com", NULL }, ++ { "OU=One,", "domain.example.com", NULL }, ++ { "CN=Test", "domain.example.com", "CN=Test,dc=domain,dc=example,dc=com" }, ++ { "OU=One+CN=Unsupported", "domain.example.com", NULL }, ++ { "DC=radi07, DC=segad, DC=lab, DC=sjc, DC=redhat, DC=com", "radi08.segad.lab.sjc.redhat.com", NULL }, ++}; ++ ++int ++main (int argc, ++ char **argv) ++{ ++ gchar *escaped; ++ gchar *name; ++ gint i; ++ ++#if !GLIB_CHECK_VERSION(2, 36, 0) ++ g_type_init (); ++#endif ++ ++ g_test_init (&argc, &argv, NULL); ++ g_set_prgname ("test-dn-util"); ++ ++ for (i = 0; i < G_N_ELEMENTS (samba_ou_fixtures); i++) { ++ if (g_str_equal (samba_ou_fixtures[i].ldap_dn, "")) ++ escaped = g_strdup ("_empty_"); ++ else ++ escaped = g_strdup (samba_ou_fixtures[i].ldap_dn); ++ g_strdelimit (escaped, ", =\\/", '_'); ++ name = g_strdup_printf ("/realmd/samba-ou-format/%s", escaped); ++ g_free (escaped); ++ ++ g_test_add_data_func (name, samba_ou_fixtures + i, test_samba_ou_format); ++ g_free (name); ++ } ++ ++ for (i = 0; i < G_N_ELEMENTS (qualify_fixtures); i++) { ++ if (g_str_equal (qualify_fixtures[i].ldap_dn, "")) ++ escaped = g_strdup ("_empty_"); ++ else ++ escaped = g_strdup (qualify_fixtures[i].ldap_dn); ++ g_strdelimit (escaped, ", =\\/", '_'); ++ name = g_strdup_printf ("/realmd/qualify-dn/%s", escaped); ++ g_free (escaped); ++ ++ g_test_add_data_func (name, qualify_fixtures + i, test_qualify_dn); ++ g_free (name); ++ } ++ ++ return g_test_run (); ++} +diff --git a/tests/test-samba-ou-format.c b/tests/test-samba-ou-format.c +deleted file mode 100644 +index 0a482ee..0000000 +--- a/tests/test-samba-ou-format.c ++++ /dev/null +@@ -1,89 +0,0 @@ +-/* realmd -- Realm configuration service +- * +- * Copyright 2012 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: Stef Walter <stefw@gnome.org> +- */ +- +-#include "config.h" +- +-#include "service/realm-samba-util.h" +- +-#include <glib/gstdio.h> +- +-#include <string.h> +- +-typedef struct { +- const gchar *ldap_dn; +- const gchar *domain; +- const gchar *ou_format; +-} Fixture; +- +-static void +-test_samba_ou_format (gconstpointer user_data) +-{ +- const Fixture *fixture = user_data; +- gchar *result; +- +- result = realm_samba_util_build_strange_ou (fixture->ldap_dn, fixture->domain); +- g_assert_cmpstr (result, ==, fixture->ou_format); +- g_free (result); +-} +- +-static const Fixture samba_ou_fixtures[] = { +- { "OU=One", "domain.example.com", "One" }, +- { "OU=One,ou=two", "domain.example.com", "two/One" }, +- { "Ou=One Long,OU=two", "domain.example.com", "two/One Long" }, +- { "Ou=One,OU=two, ou=Three", "domain.example.com", "Three/two/One" }, +- { "Ou=Test/Escape,Ou=Two", "domain.example.com", "Two/Test\\/Escape" }, +- { "Ou=Test\\\\Escape,Ou=Two", "domain.example.com", "Two/Test\\\\Escape" }, +- { "OU=One,DC=domain,dc=example,Dc=COM", "domain.example.com", "One" }, +- { "OU=One,OU=Two Here,DC=domain,dc=example,Dc=COM", "domain.example.com", "Two Here/One" }, +- { "OU=One,OU=Two Here,DC=invalid,Dc=COM", "domain.example.com", NULL }, +- { " ", "domain.example.com", NULL }, +- { "", "domain.example.com", NULL }, +- { "OU", "domain.example.com", NULL }, +- { "OU=One,", "domain.example.com", NULL }, +- { "CN=Unsupported", "domain.example.com", NULL }, +- { "OU=One+CN=Unsupported", "domain.example.com", NULL }, +- { "DC=radi07, DC=segad, DC=lab, DC=sjc, DC=redhat, DC=com", "radi08.segad.lab.sjc.redhat.com", NULL }, +- +-}; +- +-int +-main (int argc, +- char **argv) +-{ +- gchar *escaped; +- gchar *name; +- gint i; +- +-#if !GLIB_CHECK_VERSION(2, 36, 0) +- g_type_init (); +-#endif +- +- g_test_init (&argc, &argv, NULL); +- g_set_prgname ("test-samba-ou-format"); +- +- for (i = 0; i < G_N_ELEMENTS (samba_ou_fixtures); i++) { +- if (g_str_equal (samba_ou_fixtures[i].ldap_dn, "")) +- escaped = g_strdup ("_empty_"); +- else +- escaped = g_strdup (samba_ou_fixtures[i].ldap_dn); +- g_strdelimit (escaped, ", =\\/", '_'); +- name = g_strdup_printf ("/realmd/samba-ou-format/%s", escaped); +- g_free (escaped); +- +- g_test_add_data_func (name, samba_ou_fixtures + i, test_samba_ou_format); +- g_free (name); +- } +- +- return g_test_run (); +-} +-- +2.4.3 + diff --git a/duplicate-test-path.patch b/duplicate-test-path.patch new file mode 100644 index 000000000000..5d628379bea3 --- /dev/null +++ b/duplicate-test-path.patch @@ -0,0 +1,26 @@ +From ab41e2830d2f7540d58370b5f35f85c2808c1871 Mon Sep 17 00:00:00 2001 +From: Stef Walter <stefw@redhat.com> +Date: Fri, 11 Sep 2015 12:32:36 +0200 +Subject: [PATCH] tests: Fix duplicate test case path + +GLib is now stricter about this +--- + tests/test-safe-format.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/test-safe-format.c b/tests/test-safe-format.c +index 02aa5f1..204e10d 100644 +--- a/tests/test-safe-format.c ++++ b/tests/test-safe-format.c +@@ -194,7 +194,7 @@ main (int argc, + else + escaped = g_strdup (fixtures[i].format); + g_strdelimit (escaped, " =\\/", '_'); +- name = g_strdup_printf ("/realmd/safe-format/%s", escaped); ++ name = g_strdup_printf ("/realmd/safe-format/%d-%s", i, escaped); + g_free (escaped); + + g_test_add_data_func (name, fixtures + i, test_safe_format_string_cb); +-- +2.4.3 + diff --git a/install-diagnostic.patch b/install-diagnostic.patch new file mode 100644 index 000000000000..2dc551ef6c2e --- /dev/null +++ b/install-diagnostic.patch @@ -0,0 +1,29 @@ +From ef0797e5ed116a98cc074a6d4e1d1d6b6e6384db Mon Sep 17 00:00:00 2001 +From: Stef Walter <stefw@redhat.com> +Date: Mon, 7 Sep 2015 12:53:02 +0200 +Subject: [PATCH 1/2] service: Fix issue where diagnostics about package + install hidden + +Due to the recent refactoring the diagnostics about package +installation were hidden (even when --verbose). + +https://bugzilla.redhat.com/show_bug.cgi?id=1258745 +--- + service/realm-packages.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/service/realm-packages.c b/service/realm-packages.c +index 9da852c..321921a 100644 +--- a/service/realm-packages.c ++++ b/service/realm-packages.c +@@ -615,6 +615,7 @@ realm_packages_install_async (const gchar **package_sets, + task = g_task_new (NULL, NULL, callback, user_data); + install = g_new0 (InstallClosure, 1); + install->automatic = realm_options_automatic_install (); ++ install->invocation = invocation ? g_object_ref (invocation) : NULL; + install->connection = g_object_ref (connection); + g_task_set_task_data (task, install, install_closure_free); + +-- +2.4.3 + |