This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 3.x development tree".
The branch, master has been updated via 00bd65c93f497ac7bbd1037ad8650f3077524ff2 (commit) via 71ebbb6d5ad12f4c036aa0520dd73561752790a3 (commit) via 729716ba8d6d478d02e3ef8a5f0e0da29d7a9d57 (commit) via 92ae11e35b917a174c355a8b7bc81d159f3220c0 (commit) via 80edb9ac60cc282a4de516862c314fcc2cd04908 (commit) from f11b6f6084a1f4c21c9d454b4b5ad94b55c99bcc (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 00bd65c93f497ac7bbd1037ad8650f3077524ff2 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Thu Oct 12 11:28:10 2017 +0200
libselinux: Drop package
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 71ebbb6d5ad12f4c036aa0520dd73561752790a3 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Thu Oct 12 11:28:09 2017 +0200
libsepol: Drop package
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 729716ba8d6d478d02e3ef8a5f0e0da29d7a9d57 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Thu Oct 12 11:28:08 2017 +0200
libsemanage: Drop package
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 92ae11e35b917a174c355a8b7bc81d159f3220c0 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Thu Oct 12 10:59:32 2017 +0200
sssd: Update to 1.14.2
This is a minor update to the latest stable version of the 1.14 series of sssd.
* Drop support for SELinux. * Adjust project and source URL.
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 80edb9ac60cc282a4de516862c314fcc2cd04908 Author: Stefan Schantl stefan.schantl@ipfire.org Date: Thu Oct 12 11:00:36 2017 +0200
ding-libs: Update to 0.6.1
This is a minor update to the latest available version of the ding-libs.
* Adjust project and source URL
Signed-off-by: Stefan Schantl stefan.schantl@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
-----------------------------------------------------------------------
Summary of changes: ding-libs/ding-libs.nm | 6 +- libselinux/libselinux.nm | 97 --- libselinux/patches/libselinux-rhat.patch2 | 693 -------------------- libsemanage/libsemanage.nm | 74 --- libsemanage/patches/libsemanage-rhat.patch | 24 - libsemanage/semanage.conf | 50 -- libsepol/libsepol.nm | 71 -- ...crypto-Port-libcrypto-code-to-openssl-1.1.patch | 728 +++++++++++++++++++++ ...crypto-Check-right-value-of-CRYPTO_memcmp.patch | 32 + ...s-Add-unit-test-for-sss_encrypt-sss_decry.patch | 78 +++ ...to-tests-Rename-encrypt-decrypt-test-case.patch | 44 ++ ...0005-BUILD-Fix-installation-without-samba.patch | 46 ++ ...ept-krb5-1.15-for-building-the-PAC-plugin.patch | 29 + ...-Use-portable-macro-for-location-of-.libs.patch | 41 ++ ...t-Add-missing-libraries-to-the-check-list.patch | 53 ++ ...test-Move-libraries-to-the-right-sections.patch | 63 ++ ...pen-test-Add-check-for-untested-libraries.patch | 115 ++++ ...1-sssctl-Flags-for-command-initialization.patch | 202 ++++++ ...dd-parent_dom-to-sysdb_get_direct_parents.patch | 125 ++++ ...ke-some-nested-group-related-calls-public.patch | 81 +++ ...olve-domain-local-groups-for-remote-users.patch | 683 +++++++++++++++++++ .../0015-PAM-add-a-test-for-filter_responses.patch | 121 ++++ .../0016-PAM-add-pam_response_filter-option.patch | 501 ++++++++++++++ ...-sysdb_try_to_find_expected_dn-into-small.patch | 343 ++++++++++ ...nt-sysdb_try_to_find_expected_dn-to-match.patch | 284 ++++++++ ...ad_access_filter-search-for-nested-groups.patch | 55 ++ .../0020-BUILD-Fix-linking-with-librt.patch | 61 ++ ...ONITOR-Do-not-set-up-watchdog-for-monitor.patch | 74 +++ ...0022-SYSDB-Adding-lowercase-sudoUser-form.patch | 107 +++ ...23-TESTS-Extending-sysdb-sudo-store-tests.patch | 225 +++++++ ...024-IPA-AD-check-auth-ctx-before-using-it.patch | 93 +++ ...-Fix-secrets-rule-in-the-allowed-sections.patch | 50 ++ ...026-SECRETS-Add-allowed_sec_users_options.patch | 70 ++ .../0027-ipa-Nested-netgroups-do-not-work.patch | 62 ++ ...st-user-attribute-in-case-ldap_group_nest.patch | 61 ++ ...-test-for-group-resolution-with-ldap_grou.patch | 56 ++ .../0030-BUILD-Fix-a-typo-in-inotify.m4.patch | 37 ++ ...SDB-Fixing-of-sudorule-without-a-sudoUser.patch | 48 ++ ...-implicit-declaration-of-function-htobe32.patch | 58 ++ .../0033-sssctl-Fix-missing-declaration.patch | 46 ++ ...compilation-of-sss_utf8-with-libunistring.patch | 49 ++ .../0035-SIFP-Fix-warning-format-security.patch | 40 ++ ...ault_domain_suffix-for-users-authorized-k.patch | 80 +++ ...vent-use-after-free-in-fd_input_available.patch | 72 ++ ...rint-transaction-statistics-if-the-script.patch | 39 ++ ...do-do-not-store-usn-if-no-rules-are-found.patch | 50 ++ ...evert-CONFIG-Use-default-config-when-none.patch | 117 ++++ sssd/patches/0502-SYSTEMD-Use-capabilities.patch | 25 + ...Defer-thread-cancellation-until-completio.patch | 179 +++++ sssd/sssd.nm | 19 +- 50 files changed, 5336 insertions(+), 1021 deletions(-) delete mode 100644 libselinux/libselinux.nm delete mode 100644 libselinux/patches/libselinux-rhat.patch2 delete mode 100644 libsemanage/libsemanage.nm delete mode 100644 libsemanage/patches/libsemanage-rhat.patch delete mode 100644 libsemanage/semanage.conf delete mode 100644 libsepol/libsepol.nm create mode 100644 sssd/patches/0001-crypto-Port-libcrypto-code-to-openssl-1.1.patch create mode 100644 sssd/patches/0002-libcrypto-Check-right-value-of-CRYPTO_memcmp.patch create mode 100644 sssd/patches/0003-crypto-tests-Add-unit-test-for-sss_encrypt-sss_decry.patch create mode 100644 sssd/patches/0004-crypto-tests-Rename-encrypt-decrypt-test-case.patch create mode 100644 sssd/patches/0005-BUILD-Fix-installation-without-samba.patch create mode 100644 sssd/patches/0006-BUILD-Accept-krb5-1.15-for-building-the-PAC-plugin.patch create mode 100644 sssd/patches/0007-dlopen-test-Use-portable-macro-for-location-of-.libs.patch create mode 100644 sssd/patches/0008-dlopen-test-Add-missing-libraries-to-the-check-list.patch create mode 100644 sssd/patches/0009-dlopen-test-Move-libraries-to-the-right-sections.patch create mode 100644 sssd/patches/0010-dlopen-test-Add-check-for-untested-libraries.patch create mode 100644 sssd/patches/0011-sssctl-Flags-for-command-initialization.patch create mode 100644 sssd/patches/0012-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch create mode 100644 sssd/patches/0013-sdap-make-some-nested-group-related-calls-public.patch create mode 100644 sssd/patches/0014-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch create mode 100644 sssd/patches/0015-PAM-add-a-test-for-filter_responses.patch create mode 100644 sssd/patches/0016-PAM-add-pam_response_filter-option.patch create mode 100644 sssd/patches/0017-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch create mode 100644 sssd/patches/0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch create mode 100644 sssd/patches/0019-ad_access_filter-search-for-nested-groups.patch create mode 100644 sssd/patches/0020-BUILD-Fix-linking-with-librt.patch create mode 100644 sssd/patches/0021-MONITOR-Do-not-set-up-watchdog-for-monitor.patch create mode 100644 sssd/patches/0022-SYSDB-Adding-lowercase-sudoUser-form.patch create mode 100644 sssd/patches/0023-TESTS-Extending-sysdb-sudo-store-tests.patch create mode 100644 sssd/patches/0024-IPA-AD-check-auth-ctx-before-using-it.patch create mode 100644 sssd/patches/0025-SECRETS-Fix-secrets-rule-in-the-allowed-sections.patch create mode 100644 sssd/patches/0026-SECRETS-Add-allowed_sec_users_options.patch create mode 100644 sssd/patches/0027-ipa-Nested-netgroups-do-not-work.patch create mode 100644 sssd/patches/0028-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch create mode 100644 sssd/patches/0029-tests-Add-a-test-for-group-resolution-with-ldap_grou.patch create mode 100644 sssd/patches/0030-BUILD-Fix-a-typo-in-inotify.m4.patch create mode 100644 sssd/patches/0031-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch create mode 100644 sssd/patches/0032-UTIL-Fix-implicit-declaration-of-function-htobe32.patch create mode 100644 sssd/patches/0033-sssctl-Fix-missing-declaration.patch create mode 100644 sssd/patches/0034-UTIL-Fix-compilation-of-sss_utf8-with-libunistring.patch create mode 100644 sssd/patches/0035-SIFP-Fix-warning-format-security.patch create mode 100644 sssd/patches/0036-SSH-Use-default_domain_suffix-for-users-authorized-k.patch create mode 100644 sssd/patches/0037-Prevent-use-after-free-in-fd_input_available.patch create mode 100644 sssd/patches/0038-STAP-Only-print-transaction-statistics-if-the-script.patch create mode 100644 sssd/patches/0039-sudo-do-not-store-usn-if-no-rules-are-found.patch create mode 100644 sssd/patches/0501-Partially-revert-CONFIG-Use-default-config-when-none.patch create mode 100644 sssd/patches/0502-SYSTEMD-Use-capabilities.patch create mode 100644 sssd/patches/0503-sss_client-Defer-thread-cancellation-until-completio.patch
Difference in files: diff --git a/ding-libs/ding-libs.nm b/ding-libs/ding-libs.nm index 51e9736..213d7a4 100644 --- a/ding-libs/ding-libs.nm +++ b/ding-libs/ding-libs.nm @@ -4,11 +4,11 @@ ###############################################################################
name = ding-libs -version = 0.6.0 +version = 0.6.1 release = 1
groups = System/Libraries -url = http://fedorahosted.org/sssd/ +url = https://pagure.io/SSSD/ding-libs license = GPLv3+ summary = "Ding is not GLib" assorted utility libraries.
@@ -16,7 +16,7 @@ description A set of helpful libraries used by projects such as SSSD. end
-source_dl = http://fedorahosted.org/releases/d/i/ding-libs/ +source_dl = https://releases.pagure.org/SSSD/ding-libs/
build configure_options += \ diff --git a/libselinux/libselinux.nm b/libselinux/libselinux.nm deleted file mode 100644 index 0be2a67..0000000 --- a/libselinux/libselinux.nm +++ /dev/null @@ -1,97 +0,0 @@ -############################################################################### -# IPFire.org - An Open Source Firewall Solution # -# Copyright (C) - IPFire Development Team info@ipfire.org # -############################################################################### - -name = libselinux -version = 2.1.10 -release = 1 - -groups = System/Libraries -url = http://www.selinuxproject.org -license = Public Domain -summary = SELinux library and simple utilities. - -description - libselinux provides an API for SELinux applications to get and set - process and file security contexts and to obtain security policy - decisions. -end - -sources = %{thisapp}.tgz - -build - requires - libsepol-devel - libsepol-static - python-devel - swig - end - - build - make clean - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" swigify - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" all - make CC=gcc LIBDIR="%{libdir}" SHLIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" pywrap - end - - # Install libraries to correct place. - make_install_targets += install-pywrap \ - BINDIR="%{BUILDROOT}%{bindir}" \ - SBINDIR="%{BUILDROOT}%{sbindir}" \ - LIBDIR="%{BUILDROOT}%{libdir}" \ - SHLIBDIR="%{BUILDROOT}%{libdir}" - - install_cmds - # Remove unwanted binaries - rm -f %{BUILDROOT}/usr/sbin/compute_* - rm -f %{BUILDROOT}/usr/sbin/deftype - rm -f %{BUILDROOT}/usr/sbin/execcon - rm -f %{BUILDROOT}/usr/sbin/getenforcemode - rm -f %{BUILDROOT}/usr/sbin/getfilecon - rm -f %{BUILDROOT}/usr/sbin/getpidcon - rm -f %{BUILDROOT}/usr/sbin/mkdircon - rm -f %{BUILDROOT}/usr/sbin/policyvers - rm -f %{BUILDROOT}/usr/sbin/setfilecon - rm -f %{BUILDROOT}/usr/sbin/selinuxconfig - rm -f %{BUILDROOT}/usr/sbin/selinuxdisable - rm -f %{BUILDROOT}/usr/sbin/getseuser - rm -f %{BUILDROOT}/usr/sbin/selinux_check_securetty_context - - # Fix weird symlink. - ln -svf libselinux.so.1 %{BUILDROOT}%{libdir}/libselinux.so - end -end - -packages - package %{name} - - package %{name}-devel - template DEVEL - end - - package %{name}-utils - summary = SELinux libselinux utitlities. - description - The libselinux-utils package contains the utilities. - end - - files - /usr/sbin/* - /usr/share/man/man{5,8} - end - end - - package python-selinux - summary = SELinux python bindings. - description = SELinux python bindings for libselinux. - - def files - %{libdir}/python* - end - end - - package %{name}-debuginfo - template DEBUGINFO - end -end diff --git a/libselinux/patches/libselinux-rhat.patch2 b/libselinux/patches/libselinux-rhat.patch2 deleted file mode 100644 index 4ac818f..0000000 --- a/libselinux/patches/libselinux-rhat.patch2 +++ /dev/null @@ -1,693 +0,0 @@ -diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h -index 1a54307..f6eeb21 100644 ---- a/libselinux/include/selinux/label.h -+++ b/libselinux/include/selinux/label.h -@@ -46,8 +46,10 @@ struct selabel_handle; - #define SELABEL_OPT_PATH 3 - /* select a subset of the search space as an optimization (file backend) */ - #define SELABEL_OPT_SUBSET 4 -+/* like subset, but an array of subsets */ -+#define SELABEL_OPT_PREFIXES 5 - /* total number of options */ --#define SELABEL_NOPT 5 -+#define SELABEL_NOPT 6 - - /* - * Label operations -diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h -index 6f483c9..9756ac9 100644 ---- a/libselinux/include/selinux/selinux.h -+++ b/libselinux/include/selinux/selinux.h -@@ -139,7 +139,10 @@ struct av_decision { - /* Structure for passing options, used by AVC and label subsystems */ - struct selinux_opt { - int type; -- const char *value; -+ union { -+ const char *value; -+ const char **values; -+ }; - }; - - /* Callback facilities */ -@@ -420,6 +423,11 @@ extern int matchpathcon_init(const char *path); - regexes that have stems that are prefixes of 'prefix'. */ - extern int matchpathcon_init_prefix(const char *path, const char *prefix); - -+/* Same as matchpathcon_init, but only load entries with -+ * regexes that have stems that are prefixes of the 'prefixes' -+ * array of entries. The last entry must be NULL. */ -+extern int matchpathcon_init_prefixes(const char *patch, const char **prefixes); -+ - /* Free the memory allocated by matchpathcon_init. */ - extern void matchpathcon_fini(void); - -@@ -488,6 +496,7 @@ extern const char *selinux_policy_root(void); - - /* These functions return the paths to specific files under the - policy root directory. */ -+extern const char *selinux_current_policy_path(void); - extern const char *selinux_binary_policy_path(void); - extern const char *selinux_failsafe_context_path(void); - extern const char *selinux_removable_context_path(void); -@@ -502,10 +511,12 @@ extern const char *selinux_homedir_context_path(void); - extern const char *selinux_media_context_path(void); - extern const char *selinux_virtual_domain_context_path(void); - extern const char *selinux_virtual_image_context_path(void); -+extern const char *selinux_lxc_contexts_path(void); - extern const char *selinux_x_context_path(void); - extern const char *selinux_sepgsql_context_path(void); - extern const char *selinux_contexts_path(void); - extern const char *selinux_securetty_types_path(void); -+extern const char *selinux_booleans_subs_path(void); - extern const char *selinux_booleans_path(void); - extern const char *selinux_customizable_types_path(void); - extern const char *selinux_users_path(void); -diff --git a/libselinux/man/man3/matchpathcon.3 b/libselinux/man/man3/matchpathcon.3 -index cdbb252..b6814ed 100644 ---- a/libselinux/man/man3/matchpathcon.3 -+++ b/libselinux/man/man3/matchpathcon.3 -@@ -8,7 +8,9 @@ matchpathcon, matchpathcon_index - get the default SELinux security context for - - .BI "int matchpathcon_init(const char *" path ");" - --.BI "int matchpathcon_init_prefix(const char *" path ", const char *" subset ");" -+.BI "int matchpathcon_init_prefix(const char *" path ", const char *" prefix ");" -+ -+.BI "int matchpathcon_init_prefixes(const char *" path ", const char **" prefixes ");" - - .BI "int matchpathcon_fini(void);" - .sp -@@ -50,6 +52,14 @@ by - .I prefix. - - .sp -+.B matchpathcon_init_prefixes -+is the same as -+.B matchpathcon_init_prefix -+but takes an array of -+.I prefixes -+instead of a single prefix. The last entry in the array must be NULL. -+ -+.sp - .B matchpathcon_fini - frees the memory allocated by a prior call to - .B matchpathcon_init. -diff --git a/libselinux/man/man3/selabel_open.3 b/libselinux/man/man3/selabel_open.3 -index 8674e37..fc5b120 100644 ---- a/libselinux/man/man3/selabel_open.3 -+++ b/libselinux/man/man3/selabel_open.3 -@@ -37,8 +37,11 @@ structures of length - .ta 4n 16n 24n - .nf - struct selinux_opt { -- int type; -- const char *value; -+ int type; -+ union { -+ const char *value; -+ const char **values; -+ }; - }; - .fi - .ta -@@ -66,6 +69,13 @@ A non-null value for this option enables context validation. By default, - is used; a custom validation function can be provided via - .BR selinux_set_callback (3). - Note that an invalid context may not be treated as an error unless it is actually encountered during a lookup operation. -+.TP -+.B SELABEL_OPT_SUBSET -+A ":" separates string of path prefixes that tell the system to only loads entries with regular expressions that could match this strings. For example "/dev:/var/run:/tmp". This option can cause the system to use less memory and work faster, but you should only use paths that begin with a prefix. -+.TP -+.B SELABEL_OPT_PATH -+A string representing an alternate path the the regular expressions. -+.sp - - .SH "BACKENDS" - -@@ -99,4 +109,3 @@ Eamon Walsh ewalsh@tycho.nsa.gov - .BR selabel_stats (3), - .BR selinux_set_callback (3), - .BR selinux (8) -- -diff --git a/libselinux/man/man3/selinux_binary_policy_path.3 b/libselinux/man/man3/selinux_binary_policy_path.3 -index 8ead1a4..c68ace5 100644 ---- a/libselinux/man/man3/selinux_binary_policy_path.3 -+++ b/libselinux/man/man3/selinux_binary_policy_path.3 -@@ -17,6 +17,8 @@ extern const char *selinux_policy_root(void); - - extern const char *selinux_binary_policy_path(void); - -+extern const char *selinux_current_policy_path(void); -+ - extern const char *selinux_failsafe_context_path(void); - - extern const char *selinux_removable_context_path(void); -@@ -52,7 +54,9 @@ selinux_path() - top-level SELinux configuration directory - .sp - selinux_policy_root() - top-level policy directory - .sp --selinux_binary_policy_path() - binary policy file loaded into kernel -+selinux_current_policy_path() - binary policy file loaded into kernel -+.sp -+selinux_binary_policy_path() - binary policy path on disk - .sp - selinux_default_type_path - context file mapping roles to default types. - .sp -diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c -index 1bf3599..f621de7 100644 ---- a/libselinux/src/audit2why.c -+++ b/libselinux/src/audit2why.c -@@ -214,19 +214,12 @@ static int __policy_init(const char *init_path) - PyErr_SetString( PyExc_ValueError, errormsg); - return 1; - } -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- while (!fp && errno == ENOENT && --vers) { -- snprintf(path, PATH_MAX, "%s.%d", -- selinux_binary_policy_path(), vers); -- fp = fopen(path, "r"); -- } -+ fp = fopen(selinux_current_policy_path(), "r"); - if (!fp) { - snprintf(errormsg, sizeof(errormsg), -- "unable to open %s.%d: %s\n", -- selinux_binary_policy_path(), -- security_policyvers(), strerror(errno)); -+ "unable to open %s: %s\n", -+ selinux_current_policy_path(), -+ strerror(errno)); - PyErr_SetString( PyExc_ValueError, errormsg); - return 1; - } -diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c -index 802a07f..6ff83a7 100644 ---- a/libselinux/src/avc.c -+++ b/libselinux/src/avc.c -@@ -827,6 +827,7 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid, - errsave = errno; - avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); - errno = errsave; -+ if (!avc_enforcing) return 0; - return rc; - } - -diff --git a/libselinux/src/avc_internal.c b/libselinux/src/avc_internal.c -index be4c0a3..a07aa7f 100644 ---- a/libselinux/src/avc_internal.c -+++ b/libselinux/src/avc_internal.c -@@ -101,7 +101,9 @@ static int avc_netlink_receive(char *buf, unsigned buflen, int blocking) - socklen_t nladdrlen = sizeof nladdr; - struct nlmsghdr *nlh = (struct nlmsghdr *)buf; - -- rc = poll(&pfd, 1, (blocking ? -1 : 0)); -+ do { -+ rc = poll(&pfd, 1, (blocking ? -1 : 0)); -+ } while (rc < 0 && errno == EINTR); - - if (rc == 0 && !blocking) { - errno = EWOULDBLOCK; -diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c -index 1510043..bf526c0 100644 ---- a/libselinux/src/booleans.c -+++ b/libselinux/src/booleans.c -@@ -86,45 +86,131 @@ int security_get_boolean_names(char ***names, int *len) - } - - hidden_def(security_get_boolean_names) --#define STRBUF_SIZE 3 --static int get_bool_value(const char *name, char **buf) -+ -+static char * bool_sub(const char *name) - { -- int fd, len; -+ char *sub = NULL; -+ char *line_buf = NULL; -+ size_t line_len = 0; -+ FILE *cfg; -+ -+ if (!name) -+ return NULL; -+ -+ cfg = fopen(selinux_booleans_subs_path(), "r"); -+ -+ if (!cfg) -+ return NULL; -+ -+ while (getline(&line_buf, &line_len, cfg)) { -+ char *ptr = NULL; -+ char *src = line_buf; -+ char *dst = NULL; -+ -+ while (*src && isspace(*src)) -+ src++; -+ if (src[0] == '#') continue; -+ ptr = src; -+ while (*ptr && ! isspace(*ptr)) -+ ptr++; -+ *ptr++ = '\0'; -+ if (! *src || (strcmp(src, name) != 0)) -+ continue; -+ -+ dst = ptr; -+ while (*dst && isspace(*dst)) -+ dst++; -+ ptr=dst; -+ while (*ptr && ! isspace(*ptr)) -+ ptr++; -+ *ptr='\0'; -+ if (! *dst) -+ continue; -+ -+ sub = strdup(dst); -+ break; -+ } -+ -+ free(line_buf); -+ fclose(cfg); -+ return sub; -+} -+ -+static int bool_open(const char *name, int flag) { - char *fname = NULL; -+ char *alt_name = NULL; -+ int len; -+ int fd = -1; -+ char *ptr; - -- if (!selinux_mnt) { -- errno = ENOENT; -- return -1; -+ if (!name) { -+ errno = EINVAL; -+ return fd; - } - -- *buf = (char *)malloc(sizeof(char) * (STRBUF_SIZE + 1)); -- if (!*buf) -- goto out; -- (*buf)[STRBUF_SIZE] = 0; -- - len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); - fname = (char *)malloc(sizeof(char) * len); - if (!fname) -- goto out; -+ return fd; -+ - snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); - -- fd = open(fname, O_RDONLY); -- if (fd < 0) -+ fd = open(fname, flag); -+ if (fd >= 0 || errno != ENOENT) - goto out; - -- len = read(fd, *buf, STRBUF_SIZE); -- close(fd); -- if (len != STRBUF_SIZE) -+ alt_name = bool_sub(name); -+ if (! alt_name) - goto out; - -+ len = strlen(alt_name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); -+ ptr = realloc(fname, len); -+ if (!ptr) -+ goto out; -+ -+ fname = ptr; -+ snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, alt_name); -+ fd = open(fname, flag); -+ -+out: - free(fname); -- return 0; -+ free(alt_name); -+ -+ return fd; -+} -+ -+#define STRBUF_SIZE 3 -+static int get_bool_value(const char *name, char **buf) -+{ -+ int fd, len; -+ int rc = -1; -+ char *bool_buf = NULL; -+ if (!selinux_mnt) { -+ errno = ENOENT; -+ return -1; -+ } -+ -+ fd = bool_open(name, O_RDONLY); -+ if (fd < 0) -+ return -1; -+ -+ bool_buf = malloc(sizeof(char) * (STRBUF_SIZE + 1)); -+ if (!bool_buf) -+ goto out; -+ bool_buf[STRBUF_SIZE] = 0; -+ -+ len = read(fd, bool_buf, STRBUF_SIZE); -+ if (len != STRBUF_SIZE) -+ goto out; -+ rc = 0; - out: -- if (*buf) -- free(*buf); -- if (fname) -- free(fname); -- return -1; -+ close(fd); -+ if (!rc) { -+ *buf = bool_buf; -+ } else { -+ free(bool_buf); -+ } -+ return rc; - } - - int security_get_boolean_pending(const char *name) -@@ -164,8 +250,8 @@ hidden_def(security_get_boolean_active) - - int security_set_boolean(const char *name, int value) - { -- int fd, ret, len; -- char buf[2], *fname; -+ int fd, ret; -+ char buf[2]; - - if (!selinux_mnt) { - errno = ENOENT; -@@ -176,17 +262,9 @@ int security_set_boolean(const char *name, int value) - return -1; - } - -- len = strlen(name) + strlen(selinux_mnt) + sizeof(SELINUX_BOOL_DIR); -- fname = (char *)malloc(sizeof(char) * len); -- if (!fname) -+ fd = bool_open(name, O_WRONLY); -+ if (fd < 0) - return -1; -- snprintf(fname, len, "%s%s%s", selinux_mnt, SELINUX_BOOL_DIR, name); -- -- fd = open(fname, O_WRONLY); -- if (fd < 0) { -- ret = -1; -- goto out; -- } - - if (value) - buf[0] = '1'; -@@ -196,8 +274,7 @@ int security_set_boolean(const char *name, int value) - - ret = write(fd, buf, 2); - close(fd); -- out: -- free(fname); -+ - if (ret > 0) - return 0; - else -diff --git a/libselinux/src/callbacks.c b/libselinux/src/callbacks.c -index b245364..7c47222 100644 ---- a/libselinux/src/callbacks.c -+++ b/libselinux/src/callbacks.c -@@ -16,6 +16,7 @@ default_selinux_log(int type __attribute__((unused)), const char *fmt, ...) - { - int rc; - va_list ap; -+ if (is_selinux_enabled() == 0) return 0; - va_start(ap, fmt); - rc = vfprintf(stderr, fmt, ap); - va_end(ap); -diff --git a/libselinux/src/file_path_suffixes.h b/libselinux/src/file_path_suffixes.h -index 0b00156..825f295 100644 ---- a/libselinux/src/file_path_suffixes.h -+++ b/libselinux/src/file_path_suffixes.h -@@ -22,6 +22,8 @@ S_(BINPOLICY, "/policy/policy") - S_(COLORS, "/secolor.conf") - S_(VIRTUAL_DOMAIN, "/contexts/virtual_domain_context") - S_(VIRTUAL_IMAGE, "/contexts/virtual_image_context") -+ S_(LXC_CONTEXTS, "/contexts/lxc_contexts") - S_(FILE_CONTEXT_SUBS, "/contexts/files/file_contexts.subs") - S_(FILE_CONTEXT_SUBS_DIST, "/contexts/files/file_contexts.subs_dist") - S_(SEPGSQL_CONTEXTS, "/contexts/sepgsql_contexts") -+ S_(BOOLEAN_SUBS, "/booleans.subs") -diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c -index 7bc46cc..82a608c 100644 ---- a/libselinux/src/label_file.c -+++ b/libselinux/src/label_file.c -@@ -27,6 +27,7 @@ - * Internals, mostly moved over from matchpathcon.c - */ - -+#define MAX_PREFIX 100 - /* A file security context specification. */ - typedef struct spec { - struct selabel_lookup_rec lr; /* holds contexts for lookup result */ -@@ -276,7 +277,7 @@ static int compile_regex(struct saved_data *data, spec_t *spec, char **errbuf) - - - static int process_line(struct selabel_handle *rec, -- const char *path, const char *prefix, -+ const char *path, const char **prefix_array, - char *line_buf, int pass, unsigned lineno) - { - int items, len; -@@ -310,12 +311,24 @@ static int process_line(struct selabel_handle *rec, - } - - len = get_stem_from_spec(regex); -- if (len && prefix && strncmp(prefix, regex, len)) { -- /* Stem of regex does not match requested prefix, discard. */ -- free(regex); -- free(type); -- free(context); -- return 0; -+ if (len && prefix_array[0]) { -+ int i = 0; -+ int found = 0; -+ while (i < MAX_PREFIX && prefix_array[i]) { -+ if (strncmp(prefix_array[i], regex, len) == 0) { -+ found = 1; -+ break; -+ } -+ i++; -+ } -+ -+ if (! found) { -+ /* Stem of regex does not match requested prefix, discard. */ -+ free(regex); -+ free(type); -+ free(context); -+ return 0; -+ } - } - - if (pass == 1) { -@@ -397,7 +410,8 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - { - struct saved_data *data = (struct saved_data *)rec->data; - const char *path = NULL; -- const char *prefix = NULL; -+ const char *static_prefix_array[2] = {NULL, }; -+ const char **prefix_array = static_prefix_array; - FILE *fp; - FILE *localfp = NULL; - FILE *homedirfp = NULL; -@@ -418,7 +432,10 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - path = opts[n].value; - break; - case SELABEL_OPT_SUBSET: -- prefix = opts[n].value; -+ static_prefix_array[0] = opts[n].value; -+ break; -+ case SELABEL_OPT_PREFIXES: -+ prefix_array = opts[n].values; - break; - case SELABEL_OPT_BASEONLY: - baseonly = !!opts[n].value; -@@ -481,7 +498,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, fp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -@@ -497,7 +514,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, homedirfp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, homedir_path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, homedir_path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -@@ -507,7 +524,7 @@ static int init(struct selabel_handle *rec, struct selinux_opt *opts, - while (getline(&line_buf, &line_len, localfp) > 0) { - if (data->nspec >= maxnspec) - break; -- status = process_line(rec, local_path, prefix, line_buf, pass, ++lineno); -+ status = process_line(rec, local_path, prefix_array, line_buf, pass, ++lineno); - if (status) - goto finish; - } -diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c -index 8f200d4..c18ea47 100644 ---- a/libselinux/src/matchpathcon.c -+++ b/libselinux/src/matchpathcon.c -@@ -2,6 +2,7 @@ - #include <string.h> - #include <errno.h> - #include <stdio.h> -+#include <syslog.h> - #include "selinux_internal.h" - #include "label_internal.h" - #include "callbacks.h" -@@ -62,7 +63,7 @@ static void - { - va_list ap; - va_start(ap, fmt); -- vfprintf(stderr, fmt, ap); -+ vsyslog(LOG_ERR, fmt, ap); - va_end(ap); - } - -@@ -306,7 +307,7 @@ static void matchpathcon_init_once(void) - destructor_key_initialized = 1; - } - --int matchpathcon_init_prefix(const char *path, const char *subset) -+int matchpathcon_init_prefixes(const char *path, const char **prefixes) - { - if (!mycanoncon) - mycanoncon = default_canoncon; -@@ -314,15 +315,22 @@ int matchpathcon_init_prefix(const char *path, const char *subset) - __selinux_once(once, matchpathcon_init_once); - __selinux_setspecific(destructor_key, (void *)1); - -- options[SELABEL_OPT_SUBSET].type = SELABEL_OPT_SUBSET; -- options[SELABEL_OPT_SUBSET].value = subset; -+ options[SELABEL_OPT_PREFIXES].type = SELABEL_OPT_PREFIXES; -+ options[SELABEL_OPT_PREFIXES].values = prefixes; - options[SELABEL_OPT_PATH].type = SELABEL_OPT_PATH; - options[SELABEL_OPT_PATH].value = path; - - hnd = selabel_open(SELABEL_CTX_FILE, options, SELABEL_NOPT); - return hnd ? 0 : -1; - } -+hidden_def(matchpathcon_init_prefixes) - -+int matchpathcon_init_prefix(const char *path, const char *prefix) -+{ -+ const char *prefixes[2] = { prefix, NULL }; -+ -+ return matchpathcon_init_prefixes(path, prefixes); -+} - hidden_def(matchpathcon_init_prefix) - - int matchpathcon_init(const char *path) -diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c -index f42cb7c..f544ac2 100644 ---- a/libselinux/src/selinux_config.c -+++ b/libselinux/src/selinux_config.c -@@ -9,6 +9,7 @@ - #include <unistd.h> - #include <pthread.h> - #include "selinux_internal.h" -+#include "policy.h" - #include "get_default_type_internal.h" - - #define SELINUXDIR "/etc/selinux/" -@@ -46,7 +47,9 @@ - #define FILE_CONTEXT_SUBS 23 - #define SEPGSQL_CONTEXTS 24 - #define FILE_CONTEXT_SUBS_DIST 25 --#define NEL 26 -+#define BOOLEAN_SUBS 26 -+#define LXC_CONTEXTS 27 -+#define NEL 28 - - /* Part of one-time lazy init */ - static pthread_once_t once = PTHREAD_ONCE_INIT; -@@ -301,6 +304,29 @@ const char *selinux_binary_policy_path(void) - - hidden_def(selinux_binary_policy_path) - -+const char *selinux_current_policy_path(void) -+{ -+ int rc = 0; -+ int vers = 0; -+ static char policy_path[PATH_MAX]; -+ -+ snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt); -+ if (access(policy_path, F_OK) != 0 ) { -+ vers = security_policyvers(); -+ do { -+ /* Check prior versions to see if old policy is available */ -+ snprintf(policy_path, sizeof(policy_path), "%s.%d", -+ selinux_binary_policy_path(), vers); -+ } while ((rc = access(policy_path, F_OK)) && --vers > 0); -+ -+ if (rc) return NULL; -+ } -+ -+ return policy_path; -+} -+ -+hidden_def(selinux_current_policy_path) -+ - const char *selinux_file_context_path(void) - { - return get_path(FILE_CONTEXTS); -@@ -418,6 +444,19 @@ const char *selinux_virtual_image_context_path(void) - - hidden_def(selinux_virtual_image_context_path) - -+const char *selinux_lxc_contexts_path(void) -+{ -+ return get_path(LXC_CONTEXTS); -+} -+ -+hidden_def(selinux_lxc_contexts_path) -+ -+const char * selinux_booleans_subs_path(void) { -+ return get_path(BOOLEAN_SUBS); -+} -+ -+hidden_def(selinux_booleans_subs_path) -+ - const char * selinux_file_context_subs_path(void) { - return get_path(FILE_CONTEXT_SUBS); - } -diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h -index 00df405..8a935d0 100644 ---- a/libselinux/src/selinux_internal.h -+++ b/libselinux/src/selinux_internal.h -@@ -60,12 +60,15 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(security_setenforce) - hidden_proto(security_deny_unknown) - hidden_proto(selinux_binary_policy_path) -+ hidden_proto(selinux_booleans_subs_path) -+ hidden_proto(selinux_current_policy_path) - hidden_proto(selinux_default_context_path) - hidden_proto(selinux_securetty_types_path) - hidden_proto(selinux_failsafe_context_path) - hidden_proto(selinux_removable_context_path) - hidden_proto(selinux_virtual_domain_context_path) - hidden_proto(selinux_virtual_image_context_path) -+ hidden_proto(selinux_lxc_contexts_path) - hidden_proto(selinux_file_context_path) - hidden_proto(selinux_file_context_homedir_path) - hidden_proto(selinux_file_context_local_path) -@@ -82,6 +85,7 @@ hidden_proto(selinux_mkload_policy) - hidden_proto(selinux_path) - hidden_proto(selinux_check_passwd_access) - hidden_proto(selinux_check_securetty_context) -+ hidden_proto(matchpathcon_init_prefixes) - hidden_proto(matchpathcon_init_prefix) - hidden_proto(selinux_users_path) - hidden_proto(selinux_usersconf_path); diff --git a/libsemanage/libsemanage.nm b/libsemanage/libsemanage.nm deleted file mode 100644 index 5bac1be..0000000 --- a/libsemanage/libsemanage.nm +++ /dev/null @@ -1,74 +0,0 @@ -############################################################################### -# IPFire.org - An Open Source Firewall Solution # -# Copyright (C) - IPFire Development Team info@ipfire.org # -############################################################################### - -name = libsemanage -version = 2.1.5 -release = 3 - -groups = System/Libraries -url = http://www.selinuxproject.org -license = LGPLv2+ -summary = SELinux binary policy manipulation library. - -description - libsemanage provides an API for the manipulation of SELinux - binary policies. -end - -sources = %{thisapp}.tgz - -build - requires - bison - bzip2-devel - flex - libselinux-devel - libsepol-devel >= 2.1.4 - python-devel - swig - ustr-devel - end - - build - make clean - make CC=gcc LIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" swigify - make CC=gcc LIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" all - make CC=gcc LIBDIR="%{libdir}" CFLAGS="-g %{CFLAGS}" pywrap - end - - # Install libraries to correct place. - make_install_targets += \ - LIBDIR="%{BUILDROOT}%{libdir}" \ - SHLIBDIR="%{BUILDROOT}%{libdir}" - - install_cmds - make install-pywrap %{make_install_targets} DESTDIR=%{BUILDROOT} - - # Install our config file - cp -vf %{DIR_SOURCE}/semanage.conf %{BUILDROOT}/etc/selinux/semanage.conf - end -end - -packages - package %{name} - end - - package %{name}-devel - template DEVEL - end - - package python-libsemanage - summary = SELinux manage python bindings. - description = SELinux python bindings for libsemanage. - - files - %{libdir}/python* - end - end - - package %{name}-debuginfo - template DEBUGINFO - end -end diff --git a/libsemanage/patches/libsemanage-rhat.patch b/libsemanage/patches/libsemanage-rhat.patch deleted file mode 100644 index a1f53c5..0000000 --- a/libsemanage/patches/libsemanage-rhat.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --exclude-from=exclude -N -u -r nsalibsemanage/src/genhomedircon.c libsemanage-2.0.44/src/genhomedircon.c ---- nsalibsemanage/src/genhomedircon.c 2009-09-17 08:59:43.000000000 -0400 -+++ libsemanage-2.0.44/src/genhomedircon.c 2010-02-24 14:57:23.000000000 -0500 -@@ -310,6 +310,10 @@ - } - if (strcmp(pwbuf->pw_dir, "/") == 0) - continue; -+ if (strcmp(pwbuf->pw_dir, "/root") == 0) { -+ continue; -+ } -+ - if (semanage_str_count(pwbuf->pw_dir, '/') <= 1) - continue; - if (!(path = strdup(pwbuf->pw_dir))) { -@@ -803,6 +807,9 @@ - * /root */ - continue; - } -+ if (strcmp(pwent->pw_dir, "/root") == 0) { -+ continue; -+ } - if (push_user_entry(&head, name, seuname, - prefix, pwent->pw_dir) != STATUS_SUCCESS) { - *errors = STATUS_ERR; diff --git a/libsemanage/semanage.conf b/libsemanage/semanage.conf deleted file mode 100644 index 882b8f0..0000000 --- a/libsemanage/semanage.conf +++ /dev/null @@ -1,50 +0,0 @@ -# Authors: Jason Tang jtang@tresys.com -# -# Copyright (C) 2004-2005 Tresys Technology, LLC -# -# This library 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.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# Specify how libsemanage will interact with a SELinux policy manager. -# The four options are: -# -# "source" - libsemanage manipulates a source SELinux policy -# "direct" - libsemanage will write directly to a module store. -# /foo/bar - Write by way of a policy management server, whose -# named socket is at /foo/bar. The path must begin -# with a '/'. -# foo.com:4242 - Establish a TCP connection to a remote policy -# management server at foo.com. If there is a colon -# then the remainder is interpreted as a port number; -# otherwise default to port 4242. -module-store = direct - -# When generating the final linked and expanded policy, by default -# semanage will set the policy version to POLICYDB_VERSION_MAX, as -# given in <sepol/policydb.h>. Change this setting if a different -# version is necessary. -#policy-version = 19 - -# expand-check check neverallow rules when executing all semanage commands. -# Large penalty in time if you turn this on. -expand-check=0 - -# usepasswd check tells semanage to scan all pass word records for home directories -# and setup the labeling correctly. If this is turned off, SELinux will label /home -# correctly only. You will need to use semanage fcontext command. -# For example, if you had home dirs in /althome directory you would have to execute -# semanage fcontext -a -e /home /althome -usepasswd=False -bzip-small=true -bzip-blocksize=5 diff --git a/libsepol/libsepol.nm b/libsepol/libsepol.nm deleted file mode 100644 index 951f76e..0000000 --- a/libsepol/libsepol.nm +++ /dev/null @@ -1,71 +0,0 @@ -############################################################################### -# IPFire.org - An Open Source Firewall Solution # -# Copyright (C) - IPFire Development Team info@ipfire.org # -############################################################################### - -name = libsepol -version = 2.5 -release = 1 - -groups = System/Libraries -url = http://www.selinuxproject.org -license = LGPLv2+ -summary = SELinux binary policy manipulation library. - -description - libsepol provides an API for the manipulation of SELinux binary - policies. -end - -source_dl = https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases... -sources = %{thisapp}.tar.gz - -build - # Keep static libsepol.a for some selinux tools, that needs to link - # against it. We will put it into an own package. - keep_libraries = %{libdir}/libsepol.a - - requires - flex - end - - build - make clean - make CFLAGS="%{CFLAGS}" LDFLAGS="%{LDFLAGS}" %{PARALLELISMFLAGS} - end - - # Install libraries to correct place. - make_install_targets += \ - LIBDIR="%{BUILDROOT}%{libdir}" \ - SHLIBDIR="%{BUILDROOT}%{libdir}" - - install_cmds - # Remove binaries - rm -rf %{BUILDROOT}/usr/bin - - # Remove manpages for binaries - rm -rf %{BUILDROOT}/usr/share/man/man8 - end -end - -packages - package %{name} - - package %{name}-devel - template DEVEL - end - - package %{name}-debuginfo - template DEBUGINFO - end - - package %{name}-static - summary = Static libraries used to build policy manipulation tools. - description = %{summary} - groups = Development/Libraries - - files - %{libdir}/libsepol.a - end - end -end diff --git a/sssd/patches/0001-crypto-Port-libcrypto-code-to-openssl-1.1.patch b/sssd/patches/0001-crypto-Port-libcrypto-code-to-openssl-1.1.patch new file mode 100644 index 0000000..b7913fd --- /dev/null +++ b/sssd/patches/0001-crypto-Port-libcrypto-code-to-openssl-1.1.patch @@ -0,0 +1,728 @@ +From 805494c6ffec6831753891c507a773f3e43b30e5 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 17 Oct 2016 15:44:20 +0200 +Subject: [PATCH 01/39] crypto: Port libcrypto code to openssl-1.1 + +EVP_MD_CTX and EVP_CIPHER_CTX are opaque in openssl-1.1 + +Reviewed-by: Tomas Mraz tmraz@redhat.com +(cherry picked from commit 8f1316a0c677f211eaaa1346e21a03446b8c4fb1) +(cherry picked from commit 81ebd058ab8f6ab08b05a7e35e04881812404d43) +--- + Makefile.am | 1 + + src/util/cert/libcrypto/cert.c | 23 ++++++-- + src/util/crypto/libcrypto/crypto_hmac_sha1.c | 33 ++++++----- + src/util/crypto/libcrypto/crypto_nite.c | 76 +++++++++++++++---------- + src/util/crypto/libcrypto/crypto_obfuscate.c | 32 +++++++---- + src/util/crypto/libcrypto/crypto_sha512crypt.c | 77 +++++++++++++++----------- + src/util/crypto/libcrypto/sss_openssl.h | 39 +++++++++++++ + 7 files changed, 190 insertions(+), 91 deletions(-) + create mode 100644 src/util/crypto/libcrypto/sss_openssl.h + +diff --git a/Makefile.am b/Makefile.am +index b5f300a37..3d3500918 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -565,6 +565,7 @@ endif + dist_noinst_HEADERS = \ + src/monitor/monitor.h \ + src/util/crypto/sss_crypto.h \ ++ src/util/crypto/libcrypto/sss_openssl.h \ + src/util/cert.h \ + src/util/dlinklist.h \ + src/util/debug.h \ +diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c +index a7752d7c1..aba598d7c 100644 +--- a/src/util/cert/libcrypto/cert.c ++++ b/src/util/cert/libcrypto/cert.c +@@ -182,6 +182,8 @@ errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db, + size_t c; + X509 *cert = NULL; + EVP_PKEY *cert_pub_key = NULL; ++ const BIGNUM *n; ++ const BIGNUM *e; + int modulus_len; + unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8]; + int exponent_len; +@@ -208,16 +210,29 @@ errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db, + goto done; + } + +- if (cert_pub_key->type != EVP_PKEY_RSA) { ++ if (EVP_PKEY_base_id(cert_pub_key) != EVP_PKEY_RSA) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Expected RSA public key, found unsupported [%d].\n", +- cert_pub_key->type); ++ EVP_PKEY_base_id(cert_pub_key)); + ret = EINVAL; + goto done; + } + +- modulus_len = BN_bn2bin(cert_pub_key->pkey.rsa->n, modulus); +- exponent_len = BN_bn2bin(cert_pub_key->pkey.rsa->e, exponent); ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ RSA *rsa_pub_key = NULL; ++ rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key); ++ if (rsa_pub_key == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ RSA_get0_key(rsa_pub_key, &n, &e, NULL); ++#else ++ n = cert_pub_key->pkey.rsa->n; ++ e = cert_pub_key->pkey.rsa->e; ++#endif ++ modulus_len = BN_bn2bin(n, modulus); ++ exponent_len = BN_bn2bin(e, exponent); + + size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t) + + modulus_len +diff --git a/src/util/crypto/libcrypto/crypto_hmac_sha1.c b/src/util/crypto/libcrypto/crypto_hmac_sha1.c +index 37d25794e..5a4ce356e 100644 +--- a/src/util/crypto/libcrypto/crypto_hmac_sha1.c ++++ b/src/util/crypto/libcrypto/crypto_hmac_sha1.c +@@ -24,6 +24,8 @@ + + #include <openssl/evp.h> + ++#include "sss_openssl.h" ++ + #define HMAC_SHA1_BLOCKSIZE 64 + + int sss_hmac_sha1(const unsigned char *key, +@@ -33,23 +35,26 @@ int sss_hmac_sha1(const unsigned char *key, + unsigned char *out) + { + int ret; +- EVP_MD_CTX ctx; ++ EVP_MD_CTX *ctx; + unsigned char ikey[HMAC_SHA1_BLOCKSIZE], okey[HMAC_SHA1_BLOCKSIZE]; + size_t i; + unsigned char hash[SSS_SHA1_LENGTH]; + unsigned int res_len; + +- EVP_MD_CTX_init(&ctx); ++ ctx = EVP_MD_CTX_new(); ++ if (ctx == NULL) { ++ return ENOMEM; ++ } + + if (key_len > HMAC_SHA1_BLOCKSIZE) { + /* keys longer than blocksize are shortened */ +- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ++ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) { + ret = EIO; + goto done; + } + +- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); +- EVP_DigestFinal_ex(&ctx, ikey, &res_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len); ++ EVP_DigestFinal_ex(ctx, ikey, &res_len); + memset(ikey + SSS_SHA1_LENGTH, 0, HMAC_SHA1_BLOCKSIZE - SSS_SHA1_LENGTH); + } else { + /* keys shorter than blocksize are zero-padded */ +@@ -63,25 +68,25 @@ int sss_hmac_sha1(const unsigned char *key, + ikey[i] ^= 0x36; + } + +- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ++ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) { + ret = EIO; + goto done; + } + +- EVP_DigestUpdate(&ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE); +- EVP_DigestUpdate(&ctx, (const unsigned char *)in, in_len); +- EVP_DigestFinal_ex(&ctx, hash, &res_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE); ++ EVP_DigestUpdate(ctx, (const unsigned char *)in, in_len); ++ EVP_DigestFinal_ex(ctx, hash, &res_len); + +- if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ++ if (!EVP_DigestInit_ex(ctx, EVP_sha1(), NULL)) { + ret = EIO; + goto done; + } + +- EVP_DigestUpdate(&ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE); +- EVP_DigestUpdate(&ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH); +- EVP_DigestFinal_ex(&ctx, out, &res_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE); ++ EVP_DigestUpdate(ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH); ++ EVP_DigestFinal_ex(ctx, out, &res_len); + ret = EOK; + done: +- EVP_MD_CTX_cleanup(&ctx); ++ EVP_MD_CTX_free(ctx); + return ret; + } +diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c +index fa267fbcc..de562f2d2 100644 +--- a/src/util/crypto/libcrypto/crypto_nite.c ++++ b/src/util/crypto/libcrypto/crypto_nite.c +@@ -33,6 +33,8 @@ + #include <openssl/rand.h> + #include <openssl/crypto.h> + ++#include "sss_openssl.h" ++ + struct cipher_mech { + const EVP_CIPHER * (*cipher)(void); + const EVP_MD * (*digest)(void); +@@ -47,9 +49,9 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + { + const EVP_CIPHER *cipher; + const EVP_MD *digest; +- EVP_PKEY *hmackey; +- EVP_CIPHER_CTX ctx; +- EVP_MD_CTX mdctx; ++ EVP_PKEY *hmackey = NULL; ++ EVP_CIPHER_CTX *ctx; ++ EVP_MD_CTX *mdctx = NULL; + uint8_t *out = NULL; + int evpkeylen; + int evpivlen; +@@ -86,8 +88,13 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + RAND_bytes(out, evpivlen); + } + +- EVP_CIPHER_CTX_init(&ctx); +- ret = EVP_EncryptInit_ex(&ctx, cipher, 0, key, evpivlen ? out : NULL); ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ ret = EVP_EncryptInit_ex(ctx, cipher, 0, key, evpivlen ? out : NULL); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -95,7 +102,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + + outlen = evpivlen; + tmplen = 0; +- ret = EVP_EncryptUpdate(&ctx, out + outlen, &tmplen, plaintext, plainlen); ++ ret = EVP_EncryptUpdate(ctx, out + outlen, &tmplen, plaintext, plainlen); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -103,7 +110,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + + outlen += tmplen; + +- ret = EVP_EncryptFinal_ex(&ctx, out + outlen, &tmplen); ++ ret = EVP_EncryptFinal_ex(ctx, out + outlen, &tmplen); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -113,28 +120,32 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + + /* Then HMAC */ + +- EVP_MD_CTX_init(&mdctx); ++ mdctx = EVP_MD_CTX_new(); ++ if (mdctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + +- ret = EVP_DigestInit_ex(&mdctx, digest, NULL); ++ ret = EVP_DigestInit_ex(mdctx, digest, NULL); + if (ret != 1) { + ret = EFAULT; + goto done; + } + +- ret = EVP_DigestSignInit(&mdctx, NULL, digest, NULL, hmackey); ++ ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey); + if (ret != 1) { + ret = EFAULT; + goto done; + } + +- ret = EVP_DigestSignUpdate(&mdctx, out, outlen); ++ ret = EVP_DigestSignUpdate(mdctx, out, outlen); + if (ret != 1) { + ret = EFAULT; + goto done; + } + + slen = hmaclen; +- ret = EVP_DigestSignFinal(&mdctx, &out[outlen], &slen); ++ ret = EVP_DigestSignFinal(mdctx, &out[outlen], &slen); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -147,8 +158,8 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + ret = EOK; + + done: +- EVP_MD_CTX_cleanup(&mdctx); +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_MD_CTX_free(mdctx); ++ EVP_CIPHER_CTX_free(ctx); + EVP_PKEY_free(hmackey); + return ret; + } +@@ -160,9 +171,9 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + { + const EVP_CIPHER *cipher; + const EVP_MD *digest; +- EVP_PKEY *hmackey; +- EVP_CIPHER_CTX ctx; +- EVP_MD_CTX mdctx; ++ EVP_PKEY *hmackey = NULL; ++ EVP_CIPHER_CTX *ctx = NULL; ++ EVP_MD_CTX *mdctx; + const uint8_t *iv = NULL; + uint8_t *out; + int evpkeylen; +@@ -194,28 +205,32 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + + /* First check HMAC */ + +- EVP_MD_CTX_init(&mdctx); ++ mdctx = EVP_MD_CTX_new(); ++ if (mdctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + +- ret = EVP_DigestInit_ex(&mdctx, digest, NULL); ++ ret = EVP_DigestInit_ex(mdctx, digest, NULL); + if (ret != 1) { + ret = EFAULT; + goto done; + } + +- ret = EVP_DigestSignInit(&mdctx, NULL, digest, NULL, hmackey); ++ ret = EVP_DigestSignInit(mdctx, NULL, digest, NULL, hmackey); + if (ret != 1) { + ret = EFAULT; + goto done; + } + +- ret = EVP_DigestSignUpdate(&mdctx, ciphertext, cipherlen - hmaclen); ++ ret = EVP_DigestSignUpdate(mdctx, ciphertext, cipherlen - hmaclen); + if (ret != 1) { + ret = EFAULT; + goto done; + } + + slen = hmaclen; +- ret = EVP_DigestSignFinal(&mdctx, out, &slen); ++ ret = EVP_DigestSignFinal(mdctx, out, &slen); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -233,14 +248,19 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + iv = ciphertext; + } + +- EVP_CIPHER_CTX_init(&ctx); +- ret = EVP_DecryptInit_ex(&ctx, cipher, 0, key, iv); ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ ret = EVP_DecryptInit_ex(ctx, cipher, 0, key, iv); + if (ret != 1) { + ret = EFAULT; + goto done; + } + +- ret = EVP_DecryptUpdate(&ctx, out, &outlen, ++ ret = EVP_DecryptUpdate(ctx, out, &outlen, + ciphertext + evpivlen, + cipherlen - evpivlen - hmaclen); + if (ret != 1) { +@@ -248,7 +268,7 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + goto done; + } + +- ret = EVP_DecryptFinal_ex(&ctx, out + outlen, &tmplen); ++ ret = EVP_DecryptFinal_ex(ctx, out + outlen, &tmplen); + if (ret != 1) { + ret = EFAULT; + goto done; +@@ -261,8 +281,8 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + ret = EOK; + + done: +- EVP_MD_CTX_cleanup(&mdctx); +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_MD_CTX_free(mdctx); ++ EVP_CIPHER_CTX_free(ctx); + EVP_PKEY_free(hmackey); + return ret; + } +diff --git a/src/util/crypto/libcrypto/crypto_obfuscate.c b/src/util/crypto/libcrypto/crypto_obfuscate.c +index 85de333ec..69b622e1d 100644 +--- a/src/util/crypto/libcrypto/crypto_obfuscate.c ++++ b/src/util/crypto/libcrypto/crypto_obfuscate.c +@@ -70,7 +70,7 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, + enum obfmethod meth, char **obfpwd) + { + int ret; +- EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX *ctx; + struct crypto_mech_data *mech_props; + TALLOC_CTX *tmp_ctx = NULL; + unsigned char *keybuf; +@@ -90,7 +90,11 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, + return ENOMEM; + } + +- EVP_CIPHER_CTX_init(&ctx); ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + + mech_props = get_crypto_mech_data(meth); + if (mech_props == NULL) { +@@ -121,20 +125,20 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, + goto done; + } + +- if (!EVP_EncryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { ++ if (!EVP_EncryptInit_ex(ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failure to initialize cipher contex\n"); + ret = EIO; + goto done; + } + + /* sample data we'll encrypt and decrypt */ +- if (!EVP_EncryptUpdate(&ctx, cryptotext, &ctlen, (const unsigned char*)password, plen)) { ++ if (!EVP_EncryptUpdate(ctx, cryptotext, &ctlen, (const unsigned char *)password, plen)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation\n"); + ret = EIO; + goto done; + } + +- if(!EVP_EncryptFinal_ex(&ctx, cryptotext+ctlen, &digestlen)) { ++ if (!EVP_EncryptFinal_ex(ctx, cryptotext + ctlen, &digestlen)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot finialize the encryption operation\n"); + ret = EIO; + goto done; +@@ -185,7 +189,7 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, + + done: + talloc_free(tmp_ctx); +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_CIPHER_CTX_free(ctx); + return ret; + } + +@@ -193,7 +197,7 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, + char **password) + { + int ret; +- EVP_CIPHER_CTX ctx; ++ EVP_CIPHER_CTX *ctx; + TALLOC_CTX *tmp_ctx = NULL; + struct crypto_mech_data *mech_props; + +@@ -217,7 +221,11 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, + return ENOMEM; + } + +- EVP_CIPHER_CTX_init(&ctx); ++ ctx = EVP_CIPHER_CTX_new(); ++ if (ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + + /* Base64 decode the incoming buffer */ + obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen); +@@ -276,18 +284,18 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, + goto done; + } + +- if (!EVP_DecryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { ++ if (!EVP_DecryptInit_ex(ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { + ret = EIO; + goto done; + } + + /* sample data we'll encrypt and decrypt */ +- if (!EVP_DecryptUpdate(&ctx, (unsigned char*)pwdbuf, &plainlen, cryptotext, ctsize)) { ++ if (!EVP_DecryptUpdate(ctx, (unsigned char *)pwdbuf, &plainlen, cryptotext, ctsize)) { + ret = EIO; + goto done; + } + +- if(!EVP_DecryptFinal_ex(&ctx, (unsigned char*)pwdbuf+plainlen, &digestlen)) { ++ if (!EVP_DecryptFinal_ex(ctx, (unsigned char *)pwdbuf + plainlen, &digestlen)) { + ret = EIO; + goto done; + } +@@ -296,6 +304,6 @@ int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, + ret = EOK; + done: + talloc_free(tmp_ctx); +- EVP_CIPHER_CTX_cleanup(&ctx); ++ EVP_CIPHER_CTX_free(ctx); + return ret; + } +diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c +index 34547d08a..102356662 100644 +--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c ++++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c +@@ -28,6 +28,9 @@ + #include <openssl/evp.h> + #include <openssl/rand.h> + ++#include "sss_openssl.h" ++ ++ + /* Define our magic string to mark salt for SHA512 "encryption" replacement. */ + const char sha512_salt_prefix[] = "$6$"; + #define SALT_PREF_SIZE (sizeof(sha512_salt_prefix) - 1) +@@ -75,8 +78,8 @@ static int sha512_crypt_r(const char *key, + unsigned char alt_result[64] __attribute__((__aligned__(ALIGN64))); + size_t rounds = ROUNDS_DEFAULT; + bool rounds_custom = false; +- EVP_MD_CTX alt_ctx; +- EVP_MD_CTX ctx; ++ EVP_MD_CTX *alt_ctx = NULL; ++ EVP_MD_CTX *ctx; + size_t salt_len; + size_t key_len; + size_t cnt; +@@ -125,75 +128,83 @@ static int sha512_crypt_r(const char *key, + salt = copied_salt = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, salt, salt_len); + } + +- EVP_MD_CTX_init(&ctx); ++ ctx = EVP_MD_CTX_new(); ++ if (ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + +- EVP_MD_CTX_init(&alt_ctx); ++ alt_ctx = EVP_MD_CTX_new(); ++ if (alt_ctx == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } + + /* Prepare for the real work. */ +- if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) { ++ if (!EVP_DigestInit_ex(ctx, EVP_sha512(), NULL)) { + ret = EIO; + goto done; + } + + /* Add the key string. */ +- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len); + + /* The last part is the salt string. This must be at most 16 + * characters and it ends at the first `$' character (for + * compatibility with existing implementations). */ +- EVP_DigestUpdate(&ctx, (const unsigned char *)salt, salt_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)salt, salt_len); + + /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. + * The final result will be added to the first context. */ +- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ++ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) { + ret = EIO; + goto done; + } + + /* Add key. */ +- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); ++ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len); + + /* Add salt. */ +- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len); ++ EVP_DigestUpdate(alt_ctx, (const unsigned char *)salt, salt_len); + + /* Add key again. */ +- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); ++ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len); + + /* Now get result of this (64 bytes) and add it to the other context. */ +- EVP_DigestFinal_ex(&alt_ctx, alt_result, &part); ++ EVP_DigestFinal_ex(alt_ctx, alt_result, &part); + + /* Add for any character in the key one byte of the alternate sum. */ + for (cnt = key_len; cnt > 64; cnt -= 64) { +- EVP_DigestUpdate(&ctx, alt_result, 64); ++ EVP_DigestUpdate(ctx, alt_result, 64); + } +- EVP_DigestUpdate(&ctx, alt_result, cnt); ++ EVP_DigestUpdate(ctx, alt_result, cnt); + + /* Take the binary representation of the length of the key and for every + * 1 add the alternate sum, for every 0 the key. */ + for (cnt = key_len; cnt > 0; cnt >>= 1) { + if ((cnt & 1) != 0) { +- EVP_DigestUpdate(&ctx, alt_result, 64); ++ EVP_DigestUpdate(ctx, alt_result, 64); + } else { +- EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)key, key_len); + } + } + + /* Create intermediate result. */ +- EVP_DigestFinal_ex(&ctx, alt_result, &part); ++ EVP_DigestFinal_ex(ctx, alt_result, &part); + + /* Start computation of P byte sequence. */ +- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ++ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) { + ret = EIO; + goto done; + } + + /* For every character in the password add the entire password. */ + for (cnt = 0; cnt < key_len; cnt++) { +- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); ++ EVP_DigestUpdate(alt_ctx, (const unsigned char *)key, key_len); + } + + /* Finish the digest. */ +- EVP_DigestFinal_ex(&alt_ctx, temp_result, &part); ++ EVP_DigestFinal_ex(alt_ctx, temp_result, &part); + + /* Create byte sequence P. */ + cp = p_bytes = alloca(key_len); +@@ -203,18 +214,18 @@ static int sha512_crypt_r(const char *key, + memcpy(cp, temp_result, cnt); + + /* Start computation of S byte sequence. */ +- if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ++ if (!EVP_DigestInit_ex(alt_ctx, EVP_sha512(), NULL)) { + ret = EIO; + goto done; + } + + /* For every character in the password add the entire salt. */ + for (cnt = 0; cnt < 16 + alt_result[0]; cnt++) { +- EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len); ++ EVP_DigestUpdate(alt_ctx, (const unsigned char *)salt, salt_len); + } + + /* Finish the digest. */ +- EVP_DigestFinal_ex(&alt_ctx, temp_result, &part); ++ EVP_DigestFinal_ex(alt_ctx, temp_result, &part); + + /* Create byte sequence S. */ + cp = s_bytes = alloca(salt_len); +@@ -226,37 +237,37 @@ static int sha512_crypt_r(const char *key, + /* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */ + for (cnt = 0; cnt < rounds; cnt++) { + +- if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) { ++ if (!EVP_DigestInit_ex(ctx, EVP_sha512(), NULL)) { + ret = EIO; + goto done; + } + + /* Add key or last result. */ + if ((cnt & 1) != 0) { +- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len); + } else { +- EVP_DigestUpdate(&ctx, alt_result, 64); ++ EVP_DigestUpdate(ctx, alt_result, 64); + } + + /* Add salt for numbers not divisible by 3. */ + if (cnt % 3 != 0) { +- EVP_DigestUpdate(&ctx, (const unsigned char *)s_bytes, salt_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)s_bytes, salt_len); + } + + /* Add key for numbers not divisible by 7. */ + if (cnt % 7 != 0) { +- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len); + } + + /* Add key or last result. */ + if ((cnt & 1) != 0) { +- EVP_DigestUpdate(&ctx, alt_result, 64); ++ EVP_DigestUpdate(ctx, alt_result, 64); + } else { +- EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); ++ EVP_DigestUpdate(ctx, (const unsigned char *)p_bytes, key_len); + } + + /* Create intermediate result. */ +- EVP_DigestFinal_ex(&ctx, alt_result, &part); ++ EVP_DigestFinal_ex(ctx, alt_result, &part); + } + + /* Now we can construct the result string. +@@ -318,8 +329,8 @@ done: + * to processes or reading core dumps cannot get any information. We do it + * in this way to clear correct_words[] inside the SHA512 implementation + * as well. */ +- EVP_MD_CTX_cleanup(&ctx); +- EVP_MD_CTX_cleanup(&alt_ctx); ++ EVP_MD_CTX_free(ctx); ++ EVP_MD_CTX_free(alt_ctx); + if (p_bytes) memset(p_bytes, '\0', key_len); + if (s_bytes) memset(s_bytes, '\0', salt_len); + if (copied_key) memset(copied_key, '\0', key_len); +diff --git a/src/util/crypto/libcrypto/sss_openssl.h b/src/util/crypto/libcrypto/sss_openssl.h +new file mode 100644 +index 000000000..a2e2d8523 +--- /dev/null ++++ b/src/util/crypto/libcrypto/sss_openssl.h +@@ -0,0 +1,39 @@ ++/* ++ Authors: ++ Lukas Slebodnik lslebodn@redhat.com ++ ++ Copyright (C) 2016 Red Hat ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see http://www.gnu.org/licenses/. ++*/ ++ ++#ifndef _SSS_LIBCRYTPO_SSS_OPENSSL_H_ ++#define _SSS_LIBCRYTPO_SSS_OPENSSL_H_ ++ ++#include <openssl/evp.h> ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++/* EVP_MD_CTX_create and EVP_MD_CTX_destroy are deprecated macros ++ * in openssl-1.1 but openssl-1.0 does not know anything about ++ * newly added functions EVP_MD_CTX_new, EVP_MD_CTX_free in 1.1 ++ */ ++ ++# define EVP_MD_CTX_new() EVP_MD_CTX_create() ++# define EVP_MD_CTX_free(ctx) EVP_MD_CTX_destroy((ctx)) ++ ++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ ++ ++ ++#endif /* _SSS_LIBCRYTPO_SSS_OPENSSL_H_ */ +-- +2.11.0 + diff --git a/sssd/patches/0002-libcrypto-Check-right-value-of-CRYPTO_memcmp.patch b/sssd/patches/0002-libcrypto-Check-right-value-of-CRYPTO_memcmp.patch new file mode 100644 index 0000000..440f2cd --- /dev/null +++ b/sssd/patches/0002-libcrypto-Check-right-value-of-CRYPTO_memcmp.patch @@ -0,0 +1,32 @@ +From 5a6aeb890bdf18729e45cd08cfa244e3da4ed45b Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Wed, 19 Oct 2016 16:46:44 +0200 +Subject: [PATCH 02/39] libcrypto: Check right value of CRYPTO_memcmp + +sss_decrypt failed even though should pass because +we were checking wrong value of CRYPTO_memcmp. +Nobody noticed that because there was not a unit test :-) + +Reviewed-by: Christian Heimes cheimes@redhat.com +(cherry picked from commit 0c2be9700d3b54db33c1a3dd5d230b34bfaceb50) +(cherry picked from commit f4da46bd77f2eed2d04152b75c78bfc561c79354) +--- + src/util/crypto/libcrypto/crypto_nite.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c +index de562f2d2..e863d3fc9 100644 +--- a/src/util/crypto/libcrypto/crypto_nite.c ++++ b/src/util/crypto/libcrypto/crypto_nite.c +@@ -237,7 +237,7 @@ int sss_decrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype, + } + + ret = CRYPTO_memcmp(&ciphertext[cipherlen - hmaclen], out, hmaclen); +- if (ret != 1) { ++ if (ret != 0) { + ret = EFAULT; + goto done; + } +-- +2.11.0 + diff --git a/sssd/patches/0003-crypto-tests-Add-unit-test-for-sss_encrypt-sss_decry.patch b/sssd/patches/0003-crypto-tests-Add-unit-test-for-sss_encrypt-sss_decry.patch new file mode 100644 index 0000000..6652b36 --- /dev/null +++ b/sssd/patches/0003-crypto-tests-Add-unit-test-for-sss_encrypt-sss_decry.patch @@ -0,0 +1,78 @@ +From 398f89119f9e852df3beec3644420057746dbfd1 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Wed, 19 Oct 2016 16:38:27 +0200 +Subject: [PATCH 03/39] crypto-tests: Add unit test for sss_encrypt + + sss_decrypt + +Reviewed-by: Christian Heimes cheimes@redhat.com +(cherry picked from commit 65c85654d9b32a866caa01c28fe743eeb0bdef67) +(cherry picked from commit 8cb41367912a50d6d9309f82b718af90032d0f02) +--- + src/tests/crypto-tests.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c +index ee807c6bc..a4074e474 100644 +--- a/src/tests/crypto-tests.c ++++ b/src/tests/crypto-tests.c +@@ -158,6 +158,49 @@ START_TEST(test_base64_decode) + } + END_TEST + ++START_TEST(test_sss_encrypt_decrypt) ++{ ++ uint8_t key[] = { ++ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, ++ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, ++ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f ++ }; ++ size_t key_len = sizeof(key); /* need to be 32 */ ++ const char input_text[] = "Secret text"; ++ const size_t input_text_len = sizeof(input_text) - 1; ++ uint8_t *cipher_text; ++ size_t cipher_text_len; ++ uint8_t *plain_text; ++ size_t plain_text_len; ++ int ret; ++ ++ test_ctx = talloc_new(NULL); ++ fail_if(test_ctx == NULL); ++ ++ ret = sss_encrypt(test_ctx, AES256CBC_HMAC_SHA256, key, key_len, ++ (const uint8_t *)input_text, input_text_len, ++ &cipher_text, &cipher_text_len); ++ ++ fail_if(ret != 0); ++ fail_if(cipher_text_len == 0); ++ ++ ret = memcmp(input_text, cipher_text, input_text_len); ++ fail_if(ret == 0, "Input and encrypted text has common prefix"); ++ ++ ret = sss_decrypt(test_ctx, AES256CBC_HMAC_SHA256, key, key_len, ++ cipher_text, cipher_text_len, ++ &plain_text, &plain_text_len); ++ fail_if(ret != 0); ++ fail_if(plain_text_len != input_text_len); ++ ++ ret = memcmp(plain_text, input_text, input_text_len); ++ fail_if(ret != 0, "input text is not the same as de-encrypted text"); ++ ++ talloc_free(test_ctx); ++} ++END_TEST ++ + Suite *crypto_suite(void) + { + Suite *s = suite_create("sss_crypto"); +@@ -172,6 +215,7 @@ Suite *crypto_suite(void) + tcase_add_test(tc, test_hmac_sha1); + tcase_add_test(tc, test_base64_encode); + tcase_add_test(tc, test_base64_decode); ++ tcase_add_test(tc, test_sss_encrypt_decrypt); + /* Add all test cases to the test suite */ + suite_add_tcase(s, tc); + +-- +2.11.0 + diff --git a/sssd/patches/0004-crypto-tests-Rename-encrypt-decrypt-test-case.patch b/sssd/patches/0004-crypto-tests-Rename-encrypt-decrypt-test-case.patch new file mode 100644 index 0000000..cfbb3cc --- /dev/null +++ b/sssd/patches/0004-crypto-tests-Rename-encrypt-decrypt-test-case.patch @@ -0,0 +1,44 @@ +From bb53631c770d287dfc9b130754ce3f9320c8b3d4 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Wed, 19 Oct 2016 16:55:37 +0200 +Subject: [PATCH 04/39] crypto-tests: Rename encrypt decrypt test case + +libsss_crypto provide 2 pairs of encrypt + decrypt functions. +sss_password_encrypt + sss_password_decrypt and more generic +sss_encrypt + sss_decrypt. + +The name of one test case was a little bit confusing. +It evokes that different pair of functions were tested. + +Reviewed-by: Christian Heimes cheimes@redhat.com +(cherry picked from commit 96d239e83e671b82525cec760cf0bcaa5ee1c249) +(cherry picked from commit 579daa9099acf848e1062a48a7cd3a5e923da349) +--- + src/tests/crypto-tests.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c +index a4074e474..c7f0edbb3 100644 +--- a/src/tests/crypto-tests.c ++++ b/src/tests/crypto-tests.c +@@ -48,7 +48,7 @@ START_TEST(test_nss_init) + END_TEST + #endif + +-START_TEST(test_encrypt_decrypt) ++START_TEST(test_sss_password_encrypt_decrypt) + { + const char *password[] = { "test123", /* general */ + "12345678901234567", /* just above blocksize */ +@@ -211,7 +211,7 @@ Suite *crypto_suite(void) + #ifdef HAVE_NSS + tcase_add_test(tc, test_nss_init); + #endif +- tcase_add_test(tc, test_encrypt_decrypt); ++ tcase_add_test(tc, test_sss_password_encrypt_decrypt); + tcase_add_test(tc, test_hmac_sha1); + tcase_add_test(tc, test_base64_encode); + tcase_add_test(tc, test_base64_decode); +-- +2.11.0 + diff --git a/sssd/patches/0005-BUILD-Fix-installation-without-samba.patch b/sssd/patches/0005-BUILD-Fix-installation-without-samba.patch new file mode 100644 index 0000000..e4b2ab0 --- /dev/null +++ b/sssd/patches/0005-BUILD-Fix-installation-without-samba.patch @@ -0,0 +1,46 @@ +From 30b240137ea5c8e6927b9a4f93813735a2a477ae Mon Sep 17 00:00:00 2001 +From: Sorah Fukumori her@sorah.jp +Date: Sun, 23 Oct 2016 01:43:05 +0900 +Subject: [PATCH 05/39] BUILD: Fix installation without samba +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +winbindplugindir is defined only when BUILD_SAMBA is on. Also the file +doesn't exist when BUILD_SAMBA is off, so installation will fail. + +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit 13adcd07000ba3ca1422c6ee863df17d70e2b14c) +(cherry picked from commit 1fb3cccd83ede1bbe99319254c88fce1285b352d) +--- + Makefile.am | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index 3d3500918..d08e39fa4 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -4130,7 +4130,9 @@ install-data-hook: + if [ ! $(krb5rcachedir) = "__LIBKRB5_DEFAULTS__" ]; then \ + $(MKDIR_P) $(DESTDIR)/$(krb5rcachedir) ; \ + fi ++if BUILD_SAMBA + mv $(DESTDIR)/$(winbindplugindir)/winbind_idmap_sss.so $(DESTDIR)/$(winbindplugindir)/sss.so ++endif + + uninstall-hook: + if [ -f $(abs_builddir)/src/config/.files2 ]; then \ +@@ -4152,7 +4154,9 @@ if BUILD_PYTHON3_BINDINGS + cd $(DESTDIR)$(py3execdir) && \ + rm -f pysss.so pyhbac.so pysss_murmur.so pysss_nss_idmap.so + endif ++if BUILD_SAMBA + rm $(DESTDIR)/$(winbindplugindir)/sss.so ++endif + + clean-local: + if BUILD_PYTHON2_BINDINGS +-- +2.11.0 + diff --git a/sssd/patches/0006-BUILD-Accept-krb5-1.15-for-building-the-PAC-plugin.patch b/sssd/patches/0006-BUILD-Accept-krb5-1.15-for-building-the-PAC-plugin.patch new file mode 100644 index 0000000..0767b72 --- /dev/null +++ b/sssd/patches/0006-BUILD-Accept-krb5-1.15-for-building-the-PAC-plugin.patch @@ -0,0 +1,29 @@ +From fe1591bf812979074f11493c74ee87efa6b92609 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 24 Oct 2016 10:03:32 +0000 +Subject: [PATCH 06/39] BUILD: Accept krb5 1.15 for building the PAC plugin + +Reviewed-by: Sumit Bose sbose@redhat.com +(cherry picked from commit 11d2a1183d7017f3d453d0a7046004b6968fefb5) +(cherry picked from commit 6a96323fb511565908a5a7ce7b1d6e0d40aa647d) +--- + src/external/pac_responder.m4 | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4 +index 928b1d295..6b400d47c 100644 +--- a/src/external/pac_responder.m4 ++++ b/src/external/pac_responder.m4 +@@ -16,7 +16,8 @@ then + Kerberos\ 5\ release\ 1.11* | \ + Kerberos\ 5\ release\ 1.12* | \ + Kerberos\ 5\ release\ 1.13* | \ +- Kerberos\ 5\ release\ 1.14*) ++ Kerberos\ 5\ release\ 1.14* | \ ++ Kerberos\ 5\ release\ 1.15*) + krb5_version_ok=yes + AC_MSG_RESULT([yes]) + ;; +-- +2.11.0 + diff --git a/sssd/patches/0007-dlopen-test-Use-portable-macro-for-location-of-.libs.patch b/sssd/patches/0007-dlopen-test-Use-portable-macro-for-location-of-.libs.patch new file mode 100644 index 0000000..fce0123 --- /dev/null +++ b/sssd/patches/0007-dlopen-test-Use-portable-macro-for-location-of-.libs.patch @@ -0,0 +1,41 @@ +From 00efc45a2f2784b8f7bbd823dd7de6b9201d69b1 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 17 Oct 2016 21:39:57 +0200 +Subject: [PATCH 07/39] dlopen-test: Use portable macro for location of .libs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Petr Čech pcech@redhat.com +(cherry picked from commit bacc66dc6f446d47be18b61d569721481d70386b) +(cherry picked from commit a64409a528257ee0706cc12a1b974a159edac041) +--- + src/tests/dlopen-tests.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c +index 96cc4db9b..6e37dbed1 100644 +--- a/src/tests/dlopen-tests.c ++++ b/src/tests/dlopen-tests.c +@@ -22,7 +22,8 @@ + along with this program. If not, see http://www.gnu.org/licenses/. + */ + +-#define _GNU_SOURCE ++#include "config.h" ++ + #include <stdbool.h> + #include <dlfcn.h> + #include <stdio.h> +@@ -31,7 +32,7 @@ + #include <check.h> + #include "tests/common.h" + +-#define LIBPFX ABS_BUILD_DIR"/.libs/" ++#define LIBPFX ABS_BUILD_DIR "/" LT_OBJDIR + + struct so { + const char *name; +-- +2.11.0 + diff --git a/sssd/patches/0008-dlopen-test-Add-missing-libraries-to-the-check-list.patch b/sssd/patches/0008-dlopen-test-Add-missing-libraries-to-the-check-list.patch new file mode 100644 index 0000000..3372570 --- /dev/null +++ b/sssd/patches/0008-dlopen-test-Add-missing-libraries-to-the-check-list.patch @@ -0,0 +1,53 @@ +From f60c6cec2a432222308d5b6b05ee7e2f93c16bb0 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 17 Oct 2016 21:59:18 +0200 +Subject: [PATCH 08/39] dlopen-test: Add missing libraries to the check list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +nfsidmap plugin(sss.so) and libsss_cert.so were not checked. +Few libraries which are build for testing purposes were added to the list +otherwise we would not be able to detect unchecked libraries. + +Reviewed-by: Petr Čech pcech@redhat.com +(cherry picked from commit 558b8f3cd2439c01e139cf5f812aea9409fe776a) +(cherry picked from commit 9b972260cb805e3537ab9464ef5347348792d7cf) +--- + src/tests/dlopen-tests.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c +index 6e37dbed1..c980ab9f1 100644 +--- a/src/tests/dlopen-tests.c ++++ b/src/tests/dlopen-tests.c +@@ -78,6 +78,7 @@ struct so { + { "libsss_child.so", { LIBPFX"libsss_util.so", + LIBPFX"libsss_child.so", NULL } }, + { "libsss_crypt.so", { LIBPFX"libsss_crypt.so", NULL } }, ++ { "libsss_cert.so", { LIBPFX"libsss_cert.so", NULL } }, + { "libsss_util.so", { LIBPFX"libsss_util.so", NULL } }, + { "libsss_simple.so", { LIBPFX"libdlopen_test_providers.so", + LIBPFX"libsss_simple.so", NULL } }, +@@ -114,6 +115,18 @@ struct so { + #ifdef HAVE_CONFIG_LIB + { "libsss_config.so", { LIBPFX"libsss_config.so", NULL } }, + #endif ++#ifdef BUILD_NFS_IDMAP ++ { "sss.so", { LIBPFX"sss.so", NULL } }, ++#endif ++ /* for testing purposes */ ++ { "libsss_nss_idmap_tests.so", { LIBPFX"libsss_nss_idmap_tests.so", ++ NULL } }, ++#ifdef BUILD_SAMBA ++ { "libdlopen_test_winbind_idmap.so", ++ { LIBPFX"libdlopen_test_winbind_idmap.so", NULL } }, ++ { "libsss_ad_tests.so", { LIBPFX"libdlopen_test_providers.so", ++ LIBPFX"libsss_ad_tests.so", NULL } }, ++#endif + { NULL } + }; + +-- +2.11.0 + diff --git a/sssd/patches/0009-dlopen-test-Move-libraries-to-the-right-sections.patch b/sssd/patches/0009-dlopen-test-Move-libraries-to-the-right-sections.patch new file mode 100644 index 0000000..225f599 --- /dev/null +++ b/sssd/patches/0009-dlopen-test-Move-libraries-to-the-right-sections.patch @@ -0,0 +1,63 @@ +From 87ef46f4bd0745b13ee49f5487bc8a45ea2f3c1d Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 17 Oct 2016 22:17:27 +0200 +Subject: [PATCH 09/39] dlopen-test: Move libraries to the right "sections" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The library winbind_idmap_sss.so is build only when building +with samba. The library libdlopen_test_providers.so was moved +to the group of libraries build for testing purposes. + +Reviewed-by: Petr Čech pcech@redhat.com +(cherry picked from commit d708e53d0df0c1ed4cc0097bebfa2a84d7b20fad) +(cherry picked from commit a52c7df943a7b685609b66c49264c6d1805d31c2) +--- + src/tests/dlopen-tests.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c +index c980ab9f1..c857dff73 100644 +--- a/src/tests/dlopen-tests.c ++++ b/src/tests/dlopen-tests.c +@@ -71,9 +71,6 @@ struct so { + #ifdef HAVE_CIFS_IDMAP_PLUGIN + { "cifs_idmap_sss.so", { LIBPFX"cifs_idmap_sss.so", NULL } }, + #endif +- { "winbind_idmap_sss.so", { LIBPFX"libdlopen_test_winbind_idmap.so", +- LIBPFX"winbind_idmap_sss.so", +- NULL } }, + { "memberof.so", { LIBPFX"memberof.so", NULL } }, + { "libsss_child.so", { LIBPFX"libsss_util.so", + LIBPFX"libsss_child.so", NULL } }, +@@ -87,6 +84,8 @@ struct so { + LIBPFX"libsss_ad.so", NULL } }, + { "libsss_ipa.so", { LIBPFX"libdlopen_test_providers.so", + LIBPFX"libsss_ipa.so", NULL } }, ++ { "winbind_idmap_sss.so", { LIBPFX"libdlopen_test_winbind_idmap.so", ++ LIBPFX"winbind_idmap_sss.so", NULL } }, + #endif /* BUILD_SAMBA */ + { "libsss_krb5.so", { LIBPFX"libdlopen_test_providers.so", + LIBPFX"libsss_krb5.so", NULL } }, +@@ -98,8 +97,6 @@ struct so { + LIBPFX"libsss_ldap_common.so", NULL } }, + { "libsss_proxy.so", { LIBPFX"libdlopen_test_providers.so", + LIBPFX"libsss_proxy.so", NULL } }, +- { "libdlopen_test_providers.so", { LIBPFX"libdlopen_test_providers.so", +- NULL } }, + #ifdef HAVE_PYTHON2_BINDINGS + { "_py2hbac.so", { LIBPFX"_py2hbac.so", NULL } }, + { "_py2sss.so", { LIBPFX"_py2sss.so", NULL } }, +@@ -119,6 +116,8 @@ struct so { + { "sss.so", { LIBPFX"sss.so", NULL } }, + #endif + /* for testing purposes */ ++ { "libdlopen_test_providers.so", { LIBPFX"libdlopen_test_providers.so", ++ NULL } }, + { "libsss_nss_idmap_tests.so", { LIBPFX"libsss_nss_idmap_tests.so", + NULL } }, + #ifdef BUILD_SAMBA +-- +2.11.0 + diff --git a/sssd/patches/0010-dlopen-test-Add-check-for-untested-libraries.patch b/sssd/patches/0010-dlopen-test-Add-check-for-untested-libraries.patch new file mode 100644 index 0000000..40cac80 --- /dev/null +++ b/sssd/patches/0010-dlopen-test-Add-check-for-untested-libraries.patch @@ -0,0 +1,115 @@ +From 916065cfed5ceccfd2ee4127a460b47161c2efd7 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 17 Oct 2016 21:44:18 +0200 +Subject: [PATCH 10/39] dlopen-test: Add check for untested libraries +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Petr Čech pcech@redhat.com +(cherry picked from commit c7b3c43cf669e39f7ce5f4ef1a2e939b31a8b7b9) +(cherry picked from commit 7251859d8cdb2fc57c969f67ac76904fea331cd0) +--- + src/tests/dlopen-tests.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +diff --git a/src/tests/dlopen-tests.c b/src/tests/dlopen-tests.c +index c857dff73..520c91f63 100644 +--- a/src/tests/dlopen-tests.c ++++ b/src/tests/dlopen-tests.c +@@ -30,6 +30,7 @@ + #include <stdlib.h> + #include <limits.h> + #include <check.h> ++#include <dirent.h> + #include "tests/common.h" + + #define LIBPFX ABS_BUILD_DIR "/" LT_OBJDIR +@@ -154,16 +155,84 @@ static bool recursive_dlopen(const char **name, int round, char **errmsg) + return ok; + } + ++static int file_so_filter(const struct dirent *ent) ++{ ++ char *suffix; ++ ++ suffix = rindex(ent->d_name, '.'); ++ if (suffix != NULL ++ && strcmp(suffix, ".so") == 0 ++ && suffix[3] == '\0') { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static char **get_so_files(size_t *_list_size) ++{ ++ int n; ++ struct dirent **namelist; ++ char **libraries; ++ ++ n = scandir(LIBPFX, &namelist, file_so_filter, alphasort); ++ fail_unless(n > 0); ++ ++ libraries = calloc(n + 1, sizeof(char *)); ++ ++ for (int i = 0; i < n; ++i) { ++ libraries[i] = strdup(namelist[i]->d_name); ++ fail_if(libraries[i] == NULL); ++ ++ free(namelist[i]); ++ } ++ free(namelist); ++ ++ *_list_size = (size_t)n; ++ return libraries; ++} ++ ++static void remove_library_from_list(const char *library, char **list, ++ size_t list_size) ++{ ++ for (size_t i = 0; i < list_size; ++i) { ++ if (list[i] != NULL && strcmp(library, list[i]) == 0) { ++ /* found library need to be removed from list */ ++ free(list[i]); ++ list[i] = NULL; ++ return; ++ } ++ } ++ ++ ck_abort_msg("Cannot find expected library: %s", library); ++} ++ + START_TEST(test_dlopen_base) + { + char *errmsg; + bool ok; + int i; ++ size_t found_libraries_size; ++ char **found_libraries = get_so_files(&found_libraries_size); ++ bool unchecked_library = false; + + for (i = 0; so[i].name != NULL; i++) { + ok = recursive_dlopen(so[i].libs, 0, &errmsg); + fail_unless(ok, "Error opening %s: [%s]", so[i].name, errmsg); ++ ++ remove_library_from_list(so[i].name, found_libraries, ++ found_libraries_size); + } ++ ++ for (i = 0; i < found_libraries_size; ++i) { ++ if (found_libraries[i] != NULL) { ++ printf("Unchecked library found: %s\n", found_libraries[i]); ++ unchecked_library = true; ++ } ++ } ++ free(found_libraries); ++ ++ fail_if(unchecked_library); + } + END_TEST + +-- +2.11.0 + diff --git a/sssd/patches/0011-sssctl-Flags-for-command-initialization.patch b/sssd/patches/0011-sssctl-Flags-for-command-initialization.patch new file mode 100644 index 0000000..1aebca3 --- /dev/null +++ b/sssd/patches/0011-sssctl-Flags-for-command-initialization.patch @@ -0,0 +1,202 @@ +From 9b31bc45a3d5728af2523725bd5a2b4aff4f4c78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= mzidek@redhat.com +Date: Wed, 12 Oct 2016 13:09:37 +0200 +Subject: [PATCH 11/39] sssctl: Flags for command initialization +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Allow passing flags for command specific initialization. Currently +only one flag is available to skip the confdb initialization which is +required to improve config-check command. + +Resolves: +https://fedorahosted.org/sssd/ticket/3209 + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit cbee11e912bb391ba254b0bac8c1159c1f634533) +(cherry picked from commit ec1829de7cd529c2c68b4bdb9b6d43ac6bb545d3) +--- + src/tools/common/sss_tools.c | 91 +++++++++++++++++++++++++------------------- + src/tools/common/sss_tools.h | 14 +++++-- + src/tools/sssctl/sssctl.c | 2 +- + 3 files changed, 63 insertions(+), 44 deletions(-) + +diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c +index 686b53a07..0f4f46894 100644 +--- a/src/tools/common/sss_tools.c ++++ b/src/tools/common/sss_tools.c +@@ -182,7 +182,6 @@ errno_t sss_tool_init(TALLOC_CTX *mem_ctx, + struct sss_tool_ctx **_tool_ctx) + { + struct sss_tool_ctx *tool_ctx; +- errno_t ret; + + tool_ctx = talloc_zero(mem_ctx, struct sss_tool_ctx); + if (tool_ctx == NULL) { +@@ -192,45 +191,9 @@ errno_t sss_tool_init(TALLOC_CTX *mem_ctx, + + sss_tool_common_opts(tool_ctx, argc, argv); + +- /* Connect to confdb. */ +- ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n", +- ret, sss_strerror(ret)); +- goto done; +- } ++ *_tool_ctx = tool_ctx; + +- /* Setup domains. */ +- ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n", +- ret, sss_strerror(ret)); +- goto done; +- } +- +- ret = confdb_get_string(tool_ctx->confdb, tool_ctx, +- CONFDB_MONITOR_CONF_ENTRY, +- CONFDB_MONITOR_DEFAULT_DOMAIN, +- NULL, &tool_ctx->default_domain); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n", +- ret, strerror(ret)); +- goto done; +- } +- +- ret = EOK; +- +-done: +- switch (ret) { +- case EOK: +- case ERR_SYSDB_VERSION_TOO_OLD: +- *_tool_ctx = tool_ctx; +- break; +- default: +- break; +- } +- +- return ret; ++ return EOK; + } + + static bool sss_tool_is_delimiter(struct sss_route_cmd *command) +@@ -300,6 +263,47 @@ void sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands) + sss_tool_print_common_opts(min_len); + } + ++static int tool_cmd_init(struct sss_tool_ctx *tool_ctx, ++ struct sss_route_cmd *command) ++{ ++ int ret; ++ ++ if (command->flags & SSS_TOOL_FLAG_SKIP_CMD_INIT) { ++ return EOK; ++ } ++ ++ /* Connect to confdb. */ ++ ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ /* Setup domains. */ ++ ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ ret = confdb_get_string(tool_ctx->confdb, tool_ctx, ++ CONFDB_MONITOR_CONF_ENTRY, ++ CONFDB_MONITOR_DEFAULT_DOMAIN, ++ NULL, &tool_ctx->default_domain); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n", ++ ret, strerror(ret)); ++ goto done; ++ } ++ ++ ret = EOK; ++ ++done: ++ return ret; ++} ++ + errno_t sss_tool_route(int argc, const char **argv, + struct sss_tool_ctx *tool_ctx, + struct sss_route_cmd *commands, +@@ -308,6 +312,7 @@ errno_t sss_tool_route(int argc, const char **argv, + struct sss_cmdline cmdline; + const char *cmd; + int i; ++ int ret; + + if (commands == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: commands can't be NULL!\n"); +@@ -339,6 +344,14 @@ errno_t sss_tool_route(int argc, const char **argv, + return tool_ctx->init_err; + } + ++ ret = tool_cmd_init(tool_ctx, &commands[i]); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "Command initialization failed [%d] %s\n", ++ ret, sss_strerror(ret)); ++ return ret; ++ } ++ + return commands[i].fn(&cmdline, tool_ctx, pvt); + } + } +diff --git a/src/tools/common/sss_tools.h b/src/tools/common/sss_tools.h +index 6d24642ae..49da7d634 100644 +--- a/src/tools/common/sss_tools.h ++++ b/src/tools/common/sss_tools.h +@@ -45,16 +45,22 @@ typedef errno_t + struct sss_tool_ctx *tool_ctx, + void *pvt); + +-#define SSS_TOOL_COMMAND(cmd, msg, err, fn) {cmd, _(msg), err, fn} +-#define SSS_TOOL_COMMAND_NOMSG(cmd, err, fn) {cmd, NULL, err, fn} +-#define SSS_TOOL_DELIMITER(message) {"", _(message), 0, NULL} +-#define SSS_TOOL_LAST {NULL, NULL, 0, NULL} ++#define SSS_TOOL_COMMAND_FLAGS(cmd, msg, err, fn, flags) \ ++ {cmd, _(msg), err, fn, flags} ++#define SSS_TOOL_COMMAND(cmd, msg, err, fn) \ ++ {cmd, _(msg), err, fn, 0} ++#define SSS_TOOL_COMMAND_NOMSG(cmd, err, fn) {cmd, NULL, err, fn, 0} ++#define SSS_TOOL_DELIMITER(message) {"", _(message), 0, NULL, 0} ++#define SSS_TOOL_LAST {NULL, NULL, 0, NULL, 0} ++ ++#define SSS_TOOL_FLAG_SKIP_CMD_INIT 0x01 + + struct sss_route_cmd { + const char *command; + const char *description; + errno_t handles_init_err; + sss_route_fn fn; ++ int flags; + }; + + void sss_tool_usage(const char *tool_name, +diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c +index b0510e6ae..ece1e6df1 100644 +--- a/src/tools/sssctl/sssctl.c ++++ b/src/tools/sssctl/sssctl.c +@@ -276,7 +276,7 @@ int main(int argc, const char **argv) + SSS_TOOL_COMMAND("logs-fetch", "Archive SSSD log files in tarball", 0, sssctl_logs_fetch), + #ifdef HAVE_LIBINI_CONFIG_V1_3 + SSS_TOOL_DELIMITER("Configuration files tools:"), +- SSS_TOOL_COMMAND("config-check", "Perform static analysis of SSSD configuration", 0, sssctl_config_check), ++ SSS_TOOL_COMMAND_FLAGS("config-check", "Perform static analysis of SSSD configuration", 0, sssctl_config_check, SSS_TOOL_FLAG_SKIP_CMD_INIT), + #endif + SSS_TOOL_LAST + }; +-- +2.11.0 + diff --git a/sssd/patches/0012-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch b/sssd/patches/0012-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch new file mode 100644 index 0000000..f804512 --- /dev/null +++ b/sssd/patches/0012-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch @@ -0,0 +1,125 @@ +From 0cf03315bc74555aa70a6fec854d6d66826eb608 Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Tue, 18 Oct 2016 14:59:19 +0200 +Subject: [PATCH 12/39] sysdb: add parent_dom to sysdb_get_direct_parents() + +Currently sysdb_get_direct_parents() only return direct parents from the +same domain as the child object. In setups with sub-domains this might +not be sufficient. A new option parent_dom is added which allows to +specify a domain the direct parents should be lookup up in. If it is +NULL the whole cache is searched. + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 3dd4c3eca80e9223a65f3318821bd0fb5b45aedd) +(cherry picked from commit 9a243dcdbf5a908d23c1a64f3fb33914eefef9e8) +--- + src/db/sysdb.h | 21 +++++++++++++++++++++ + src/db/sysdb_search.c | 7 ++++++- + src/providers/ldap/sdap_async_initgroups.c | 11 +++++++---- + 3 files changed, 34 insertions(+), 5 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 7de3acdf3..f5d3ddb84 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1137,8 +1137,29 @@ errno_t sysdb_remove_attrs(struct sss_domain_info *domain, + enum sysdb_member_type type, + char **remove_attrs); + ++/** ++ * @brief Return direct parents of an object in the cache ++ * ++ * @param[in] mem_ctx Memory context the result should be allocated ++ * on ++ * @param[in] dom domain the object is in ++ * @param[in] parent_dom domain which should be searched for direct ++ * parents if NULL all domains in the given cache ++ * are searched ++ * @param[in] mtype Type of the object, SYSDB_MEMBER_USER or ++ * SYSDB_MEMBER_GROUP ++ * @param[in] name Name of the object ++ * @param[out] _direct_parents List of names of the direct parent groups ++ * ++ * ++ * @return ++ * - EOK: success ++ * - EINVAL: wrong mtype ++ * - ENOMEM: Memory allocation failed ++ */ + errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, ++ struct sss_domain_info *parent_dom, + enum sysdb_member_type mtype, + const char *name, + char ***_direct_parents); +diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c +index cfee5784d..4d63c3838 100644 +--- a/src/db/sysdb_search.c ++++ b/src/db/sysdb_search.c +@@ -1981,6 +1981,7 @@ done: + + errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, ++ struct sss_domain_info *parent_dom, + enum sysdb_member_type mtype, + const char *name, + char ***_direct_parents) +@@ -2029,7 +2030,11 @@ errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, + goto done; + } + +- basedn = sysdb_group_base_dn(tmp_ctx, dom); ++ if (parent_dom == NULL) { ++ basedn = sysdb_base_dn(dom->sysdb, tmp_ctx); ++ } else { ++ basedn = sysdb_group_base_dn(tmp_ctx, parent_dom); ++ } + if (!basedn) { + ret = ENOMEM; + goto done; +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index df39de3cc..7a2eef43d 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -1301,7 +1301,8 @@ sdap_initgr_store_user_memberships(struct sdap_initgr_nested_state *state) + } + } + +- ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER, ++ ret = sysdb_get_direct_parents(tmp_ctx, state->dom, state->dom, ++ SYSDB_MEMBER_USER, + state->username, &sysdb_parent_name_list); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, +@@ -1388,7 +1389,7 @@ sdap_initgr_nested_get_membership_diff(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = sysdb_get_direct_parents(tmp_ctx, dom, SYSDB_MEMBER_GROUP, ++ ret = sysdb_get_direct_parents(tmp_ctx, dom, dom, SYSDB_MEMBER_GROUP, + group_name, &sysdb_parents_names_list); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, +@@ -2070,7 +2071,8 @@ rfc2307bis_group_memberships_build(hash_entry_t *item, void *user_data) + goto done; + } + +- ret = sysdb_get_direct_parents(tmp_ctx, mstate->dom, SYSDB_MEMBER_GROUP, ++ ret = sysdb_get_direct_parents(tmp_ctx, mstate->dom, mstate->dom, ++ SYSDB_MEMBER_GROUP, + group_name, &sysdb_parents_names_list); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, +@@ -2130,7 +2132,8 @@ errno_t save_rfc2307bis_user_memberships( + } + in_transaction = true; + +- ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER, ++ ret = sysdb_get_direct_parents(tmp_ctx, state->dom, state->dom, ++ SYSDB_MEMBER_USER, + state->name, &sysdb_parent_name_list); + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, +-- +2.11.0 + diff --git a/sssd/patches/0013-sdap-make-some-nested-group-related-calls-public.patch b/sssd/patches/0013-sdap-make-some-nested-group-related-calls-public.patch new file mode 100644 index 0000000..debcf01 --- /dev/null +++ b/sssd/patches/0013-sdap-make-some-nested-group-related-calls-public.patch @@ -0,0 +1,81 @@ +From 79044fc1de2dad656b2c664722b4f8568bf4f8d6 Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Tue, 18 Oct 2016 18:16:30 +0200 +Subject: [PATCH 13/39] sdap: make some nested group related calls public + +sdap_nested_groups_store() and rfc2307bis_nested_groups_send/recv() will +be reused for domain local group lookups. + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 49d3f0a487d55571b2bdc9d3f8280b304b964b9d) +(cherry picked from commit f38c62ffe05ab845165f1b597083579d4fe3632f) +--- + src/providers/ldap/sdap_async_initgroups.c | 12 ++---------- + src/providers/ldap/sdap_async_private.h | 16 ++++++++++++++++ + 2 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 7a2eef43d..0f56b8740 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -622,7 +622,7 @@ static int sdap_initgr_rfc2307_recv(struct tevent_req *req) + } + + /* ==Common code for pure RFC2307bis and IPA/AD========================= */ +-static errno_t ++errno_t + sdap_nested_groups_store(struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + struct sdap_options *opts, +@@ -1558,14 +1558,6 @@ static void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq); + static void sdap_initgr_rfc2307bis_done(struct tevent_req *subreq); + errno_t save_rfc2307bis_user_memberships( + struct sdap_initgr_rfc2307bis_state *state); +-struct tevent_req *rfc2307bis_nested_groups_send( +- TALLOC_CTX *mem_ctx, struct tevent_context *ev, +- struct sdap_options *opts, struct sysdb_ctx *sysdb, +- struct sss_domain_info *dom, struct sdap_handle *sh, +- struct sdap_search_base **search_bases, +- struct sysdb_attrs **groups, size_t num_groups, +- hash_table_t *group_hash, size_t nesting); +-static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req); + + static struct tevent_req *sdap_initgr_rfc2307bis_send( + TALLOC_CTX *memctx, +@@ -2616,7 +2608,7 @@ static void rfc2307bis_nested_groups_process(struct tevent_req *subreq) + tevent_req_set_callback(subreq, rfc2307bis_nested_groups_done, req); + } + +-static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req) ++errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req) + { + TEVENT_REQ_RETURN_ON_ERROR(req); + return EOK; +diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h +index f09ddb71f..4af4f7144 100644 +--- a/src/providers/ldap/sdap_async_private.h ++++ b/src/providers/ldap/sdap_async_private.h +@@ -157,4 +157,20 @@ errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, + struct sysdb_attrs *group_attrs, + const char *group_name, + bool *_need_filter); ++ ++struct tevent_req *rfc2307bis_nested_groups_send( ++ TALLOC_CTX *mem_ctx, struct tevent_context *ev, ++ struct sdap_options *opts, struct sysdb_ctx *sysdb, ++ struct sss_domain_info *dom, struct sdap_handle *sh, ++ struct sdap_search_base **search_bases, ++ struct sysdb_attrs **groups, size_t num_groups, ++ hash_table_t *group_hash, size_t nesting); ++errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req); ++ ++errno_t sdap_nested_groups_store(struct sysdb_ctx *sysdb, ++ struct sss_domain_info *domain, ++ struct sdap_options *opts, ++ struct sysdb_attrs **groups, ++ unsigned long count); ++ + #endif /* _SDAP_ASYNC_PRIVATE_H_ */ +-- +2.11.0 + diff --git a/sssd/patches/0014-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch b/sssd/patches/0014-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch new file mode 100644 index 0000000..80b709b --- /dev/null +++ b/sssd/patches/0014-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch @@ -0,0 +1,683 @@ +From b53bcb7675b6b797c4ba2a590deb4e4578d0e5ef Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Tue, 18 Oct 2016 18:18:44 +0200 +Subject: [PATCH 14/39] LDAP/AD: resolve domain local groups for remote users + +If a user from a trusted domain in the same forest is a direct or +indirect member of domain local groups from the local domain those +memberships must be resolved as well. Since those domain local groups +are not valid in the trusted domain a DC from the trusted domain which +is used to lookup the user data is not aware of them. As a consequence +those memberships must be resolved against a local DC in a second step. + +Resolves https://fedorahosted.org/sssd/ticket/3206 + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 25699846bd1c9f8bb513b6271eb4366ab682fbd2) +(cherry picked from commit c1f3b29fee6577714347673d717f71ab997c3006) +--- + src/db/sysdb.h | 1 + + src/providers/ldap/sdap_async_initgroups.c | 158 +++++++++- + src/providers/ldap/sdap_async_initgroups_ad.c | 407 ++++++++++++++++++++++++++ + src/providers/ldap/sdap_async_private.h | 10 + + 4 files changed, 569 insertions(+), 7 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index f5d3ddb84..901268390 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -225,6 +225,7 @@ + SYSDB_OVERRIDE_OBJECT_DN, \ + SYSDB_DEFAULT_OVERRIDE_NAME, \ + SYSDB_UUID, \ ++ SYSDB_ORIG_DN, \ + NULL} + + #define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \ +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 0f56b8740..45fc007e0 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -2317,6 +2317,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req) + struct sdap_rfc2307bis_nested_ctx *state = + tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx); + char *oc_list; ++ const char *class; + + tmp_ctx = talloc_new(state); + if (!tmp_ctx) { +@@ -2324,9 +2325,21 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req) + goto done; + } + +- ret = sdap_get_group_primary_name(state, state->opts, +- state->groups[state->group_iter], +- state->dom, &state->primary_name); ++ ret = sysdb_attrs_get_string(state->groups[state->group_iter], ++ SYSDB_OBJECTCLASS, &class); ++ if (ret == EOK) { ++ /* If there is a objectClass attribute the object is coming from the ++ * cache and the name attribute of the object already has the primary ++ * name. ++ * If the objectClass attribute is missing the object is coming from ++ * LDAP and we have to find the primary name first. */ ++ ret = sysdb_attrs_get_string(state->groups[state->group_iter], ++ SYSDB_NAME, &state->primary_name); ++ } else { ++ ret = sdap_get_group_primary_name(state, state->opts, ++ state->groups[state->group_iter], ++ state->dom, &state->primary_name); ++ } + if (ret != EOK) { + goto done; + } +@@ -3069,6 +3082,103 @@ fail: + tevent_req_error(req, ret); + } + ++static void sdap_ad_check_domain_local_groups_done(struct tevent_req *subreq); ++ ++errno_t sdap_ad_check_domain_local_groups(struct tevent_req *req) ++{ ++ struct sdap_get_initgr_state *state = tevent_req_data(req, ++ struct sdap_get_initgr_state); ++ int ret; ++ struct sdap_domain *local_sdom; ++ const char *orig_name; ++ const char *sysdb_name; ++ struct ldb_result *res; ++ struct tevent_req *subreq; ++ struct sysdb_attrs **groups; ++ ++ /* We only need to check for domain local groups in the AD case and if the ++ * user is not from our domain, i.e. if the user comes from a sub-domain. ++ */ ++ if (state->opts->schema_type != SDAP_SCHEMA_AD ++ || !IS_SUBDOMAIN(state->dom) ++ || !dp_target_enabled(state->id_ctx->be->provider, "ad", DPT_ID)) { ++ return EOK; ++ } ++ ++ local_sdom = sdap_domain_get(state->id_ctx->opts, state->dom->parent); ++ if (local_sdom == NULL || local_sdom->pvt == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", ++ state->dom->parent->name); ++ return EINVAL; ++ } ++ ++ ret = sysdb_attrs_get_string(state->orig_user, SYSDB_NAME, &orig_name); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Missing name in user object.\n"); ++ return ret; ++ } ++ ++ sysdb_name = sss_create_internal_fqname(state, orig_name, state->dom->name); ++ if (sysdb_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "sss_create_internal_fqname failed.\n"); ++ return ENOMEM; ++ } ++ ++ ret = sysdb_initgroups(state, state->dom, sysdb_name, &res); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_initgroups failed for user [%s].\n", ++ sysdb_name); ++ return ret; ++ } ++ ++ if (res->count == 0) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "sysdb_initgroups returned no results for user [%s].\n", ++ sysdb_name); ++ return EINVAL; ++ } ++ ++ /* The user object, the first entry in the res->msgs, is included as well ++ * to cover the case where the remote user is directly added to ++ * a domain local group. */ ++ ret = sysdb_msg2attrs(state, res->count, res->msgs, &groups); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_msg2attrs failed.\n"); ++ return ret; ++ } ++ ++ subreq = sdap_ad_get_domain_local_groups_send(state, state->ev, local_sdom, ++ state->opts, state->sysdb, state->dom->parent, ++ groups, res->count); ++ if (subreq == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "sdap_ad_get_domain_local_groups_send failed.\n"); ++ return ENOMEM; ++ } ++ ++ tevent_req_set_callback(subreq, sdap_ad_check_domain_local_groups_done, ++ req); ++ ++ return EAGAIN; ++} ++ ++static void sdap_ad_check_domain_local_groups_done(struct tevent_req *subreq) ++{ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ int ret; ++ ++ ret = sdap_ad_get_domain_local_groups_recv(subreq); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++ ++ return; ++} ++ + static void sdap_get_initgr_pgid(struct tevent_req *req); + static void sdap_get_initgr_done(struct tevent_req *subreq) + { +@@ -3201,8 +3311,6 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_FUNC, + "Primary group already cached, nothing to do.\n"); +- ret = EOK; +- goto done; + } else { + gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid); + if (gid == NULL) { +@@ -3219,10 +3327,28 @@ static void sdap_get_initgr_done(struct tevent_req *subreq) + goto done; + } + tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req); ++ ++ talloc_free(tmp_ctx); ++ return; + } + +- talloc_free(tmp_ctx); +- return; ++ ret = sdap_ad_check_domain_local_groups(req); ++ if (ret == EAGAIN) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Checking for domain local group memberships.\n"); ++ talloc_free(tmp_ctx); ++ return; ++ } else if (ret == EOK) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "No need to check for domain local group memberships.\n"); ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sdap_ad_check_domain_local_groups failed, " ++ "meberships to domain local groups might be missing.\n"); ++ /* do not let the request fail completely because we already have at ++ * least "some" groups */ ++ ret = EOK; ++ } + + done: + talloc_free(tmp_ctx); +@@ -3247,7 +3373,25 @@ static void sdap_get_initgr_pgid(struct tevent_req *subreq) + return; + } + ++ ret = sdap_ad_check_domain_local_groups(req); ++ if (ret == EAGAIN) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Checking for domain local group memberships.\n"); ++ return; ++ } else if (ret == EOK) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "No need to check for domain local group memberships.\n"); ++ } else { ++ DEBUG(SSSDBG_OP_FAILURE, "sdap_ad_check_domain_local_groups failed.\n"); ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sdap_ad_check_domain_local_groups failed, " ++ "meberships to domain local groups might be missing.\n"); ++ /* do not let the request fail completely because we already have at ++ * least "some" groups */ ++ } ++ + tevent_req_done(req); ++ return; + } + + int sdap_get_initgr_recv(struct tevent_req *req) +diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c +index ad54c1fb8..1fee4ab43 100644 +--- a/src/providers/ldap/sdap_async_initgroups_ad.c ++++ b/src/providers/ldap/sdap_async_initgroups_ad.c +@@ -1412,6 +1412,413 @@ static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req) + return EOK; + } + ++struct sdap_ad_get_domain_local_groups_state { ++ struct tevent_context *ev; ++ struct sdap_id_conn_ctx *conn; ++ struct sdap_options *opts; ++ struct sdap_id_op *op; ++ struct sysdb_ctx *sysdb; ++ struct sss_domain_info *dom; ++ int dp_error; ++ ++ struct sdap_search_base **search_bases; ++ struct sysdb_attrs **groups; ++ size_t num_groups; ++ hash_table_t *group_hash; ++}; ++ ++static void ++sdap_ad_get_domain_local_groups_connect_done(struct tevent_req *subreq); ++static void sdap_ad_get_domain_local_groups_done(struct tevent_req *subreq); ++ ++struct tevent_req * ++sdap_ad_get_domain_local_groups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct sdap_domain *local_sdom, ++ struct sdap_options *opts, ++ struct sysdb_ctx *sysdb, ++ struct sss_domain_info *dom, ++ struct sysdb_attrs **groups, ++ size_t num_groups) ++{ ++ struct sdap_ad_get_domain_local_groups_state *state; ++ struct tevent_req *req; ++ struct tevent_req *subreq; ++ struct ad_id_ctx *ad_id_ctx; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct sdap_ad_get_domain_local_groups_state); ++ if (req == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); ++ return NULL; ++ } ++ ++ state->ev = ev; ++ ad_id_ctx = talloc_get_type(local_sdom->pvt, struct ad_id_ctx); ++ state->conn = ad_id_ctx->ldap_ctx; ++ state->opts = opts; ++ state->sysdb = sysdb; ++ state->dom = dom; ++ state->search_bases = state->conn->id_ctx->opts->sdom->group_search_bases; ++ state->groups = groups; ++ state->num_groups = num_groups; ++ ++ ret = sss_hash_create(state, 32, &state->group_hash); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); ++ goto fail; ++ } ++ ++ state->op = sdap_id_op_create(state, state->conn->conn_cache); ++ if (state->op == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ++ ret = ENOMEM; ++ goto fail; ++ } ++ ++ subreq = sdap_id_op_connect_send(state->op, state, &ret); ++ if (subreq == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n"); ++ goto fail; ++ } ++ ++ tevent_req_set_callback(subreq, ++ sdap_ad_get_domain_local_groups_connect_done, req); ++ ++ return req; ++ ++fail: ++ tevent_req_error(req, ret); ++ tevent_req_post(req, ev); ++ return req; ++} ++ ++static void ++sdap_ad_get_domain_local_groups_connect_done(struct tevent_req *subreq) ++{ ++ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ struct sdap_ad_get_domain_local_groups_state *state = tevent_req_data(req, ++ struct sdap_ad_get_domain_local_groups_state); ++ int dp_error = DP_ERR_FATAL; ++ int ret; ++ ++ ret = sdap_id_op_connect_recv(subreq, &dp_error); ++ talloc_zfree(subreq); ++ ++ if (ret != EOK) { ++ state->dp_error = dp_error; ++ tevent_req_error(req, ret); ++ return; ++ } ++ subreq = rfc2307bis_nested_groups_send(state, state->ev, state->opts, ++ state->sysdb, state->dom, ++ sdap_id_op_handle(state->op), ++ state->search_bases, ++ state->groups, state->num_groups, ++ state->group_hash, 0); ++ if (subreq == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "rfc2307bis_nested_groups_send failed.\n"); ++ state->dp_error = DP_ERR_FATAL; ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ ++ tevent_req_set_callback(subreq, ++ sdap_ad_get_domain_local_groups_done, req); ++ ++ return; ++} ++ ++struct sdap_nested_group { ++ struct sysdb_attrs *group; ++ struct sysdb_attrs **ldap_parents; ++ size_t parents_count; ++}; ++ ++static errno_t ++sdap_ad_get_domain_local_groups_parse_parents(TALLOC_CTX *mem_ctx, ++ struct sdap_nested_group *gr, ++ struct sss_domain_info *dom, ++ struct sysdb_ctx *sysdb, ++ struct sdap_options *opts, ++ const char **_sysdb_name, ++ enum sysdb_member_type *_type, ++ char ***_add_list, ++ char ***_del_list) ++{ ++ int ret; ++ size_t c; ++ char **groupnamelist = NULL; ++ struct sysdb_attrs *groups[1]; ++ enum sysdb_member_type type; ++ const char *sysdb_name; ++ const char *group_name; ++ const char *class; ++ struct sss_domain_info *obj_dom; ++ char *local_groups_base_dn; ++ char **cached_local_parents = NULL; ++ char **add_list = NULL; ++ char **del_list = NULL; ++ TALLOC_CTX *tmp_ctx; ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ++ return ENOMEM; ++ } ++ ++ local_groups_base_dn = talloc_asprintf(tmp_ctx, SYSDB_TMPL_GROUP_BASE, ++ dom->name); ++ if (local_groups_base_dn == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ if (gr->parents_count != 0) { ++ /* Store the parents if needed */ ++ ret = sdap_nested_groups_store(sysdb, dom, opts, ++ gr->ldap_parents, gr->parents_count); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n", ++ ret, strerror(ret)); ++ goto done; ++ } ++ ++ ret = sysdb_attrs_primary_fqdn_list(dom, tmp_ctx, ++ gr->ldap_parents, gr->parents_count, ++ opts->group_map[SDAP_AT_GROUP_NAME].name, ++ &groupnamelist); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_primary_fqdn_list failed.\n"); ++ goto done; ++ } ++ } ++ ++ ret = sysdb_attrs_get_string(gr->group, SYSDB_NAME, &sysdb_name); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sysdb_attrs_get_string failed to get SYSDB_NAME, " ++ "skipping.\n"); ++ goto done; ++ } ++ ++ ret = sysdb_attrs_get_string(gr->group, SYSDB_OBJECTCLASS, &class); ++ if (ret != EOK) { ++ /* If objectclass is missing gr->group is a nested parent found during ++ * the nested group lookup. It might not already stored in the cache. ++ */ ++ DEBUG(SSSDBG_TRACE_LIBS, ++ "sysdb_attrs_get_string failed to get SYSDB_OBJECTCLASS " ++ "for [%s], assuming group.\n", sysdb_name); ++ ++ /* make sure group exists in cache */ ++ groups[0]= gr->group; ++ ret = sdap_nested_groups_store(sysdb, dom, opts, groups, 1); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n", ++ ret, strerror(ret)); ++ goto done; ++ } ++ ++ /* Since the object is coming from LDAP it cannot have the internal ++ * fully-qualified name, so we can expand it unconditionally. */ ++ group_name = NULL; ++ ret = sysdb_attrs_primary_name(dom->sysdb, gr->group, ++ opts->group_map[SDAP_AT_GROUP_NAME].name, ++ &group_name); ++ if (ret != EOK || group_name == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Could not determine primary name\n"); ++ group_name = sysdb_name; ++ } ++ ++ group_name = sss_create_internal_fqname(tmp_ctx, group_name, ++ dom->name); ++ if (group_name != NULL) { ++ sysdb_name = group_name; ++ } ++ ++ type = SYSDB_MEMBER_GROUP; ++ } else { ++ if (class != NULL && strcmp(class, SYSDB_USER_CLASS) == 0) { ++ type = SYSDB_MEMBER_USER; ++ } else { ++ type = SYSDB_MEMBER_GROUP; ++ } ++ } ++ ++ /* We need to get the cached list of groups form the local domain the ++ * object is a member of to compare them with the current list just ++ * retrieved (groupnamelist). Even if this list is empty we have to ++ * proceed because the membership might have been removed recently on the ++ * server. */ ++ ++ obj_dom = find_domain_by_object_name(get_domains_head(dom), ++ sysdb_name); ++ if (obj_dom == NULL) { ++ obj_dom = dom; ++ DEBUG(SSSDBG_OP_FAILURE, "Cannot find domain for [%s], " ++ "trying with local domain [%s].\n", ++ sysdb_name, obj_dom->name); ++ } ++ ++ ret = sysdb_get_direct_parents(tmp_ctx, obj_dom, dom, type, sysdb_name, ++ &cached_local_parents); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE,"sysdb_get_direct_parents failed.\n"); ++ goto done; ++ } ++ ++ if (cached_local_parents != NULL && cached_local_parents[0] == NULL) { ++ talloc_zfree(cached_local_parents); ++ } ++ ++ if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) { ++ if (cached_local_parents != NULL) { ++ for (c = 0; cached_local_parents[c] != NULL; c++) { ++ DEBUG(SSSDBG_TRACE_ALL, "[%s] cached_local_parents [%s].\n", ++ sysdb_name, cached_local_parents[c]); ++ } ++ } ++ ++ if (groupnamelist != NULL) { ++ for (c = 0; groupnamelist[c] != NULL; c++) { ++ DEBUG(SSSDBG_TRACE_ALL, "[%s] groupnamelist [%s].\n", ++ sysdb_name, groupnamelist[c]); ++ } ++ } ++ } ++ ++ ret = diff_string_lists(tmp_ctx, cached_local_parents, groupnamelist, ++ &del_list, &add_list, NULL); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n"); ++ goto done; ++ } ++ ++ if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) { ++ if (add_list != NULL) { ++ for (c = 0; add_list[c] != NULL; c++) { ++ DEBUG(SSSDBG_TRACE_ALL, "add: [%s] will be member of [%s].\n", ++ sysdb_name, add_list[c]); ++ } ++ } ++ if (del_list != NULL) { ++ for (c = 0; del_list[c] != NULL; c++) { ++ DEBUG(SSSDBG_TRACE_ALL, "del: [%s] was member of [%s].\n", ++ sysdb_name, del_list[c]); ++ } ++ } ++ } ++ ++ *_type = type; ++ *_sysdb_name = talloc_steal(mem_ctx, sysdb_name); ++ *_add_list = talloc_steal(mem_ctx, groupnamelist); ++ *_del_list = talloc_steal(mem_ctx, del_list); ++ ret = EOK; ++ ++done: ++ talloc_free(tmp_ctx); ++ ++ return ret; ++} ++ ++static void sdap_ad_get_domain_local_groups_done(struct tevent_req *subreq) ++{ ++ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ struct sdap_ad_get_domain_local_groups_state *state = tevent_req_data(req, ++ struct sdap_ad_get_domain_local_groups_state); ++ int ret; ++ int hret; ++ unsigned long count; ++ hash_value_t *values = NULL; ++ struct sdap_nested_group *gr; ++ size_t c; ++ const char *sysdb_name = NULL; ++ enum sysdb_member_type type; ++ char **add_list = NULL; ++ char **del_list = NULL; ++ ++ ret = rfc2307bis_nested_groups_recv(subreq); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ hret = hash_values(state->group_hash, &count, &values); ++ if (hret != HASH_SUCCESS) { ++ DEBUG(SSSDBG_OP_FAILURE, "hash_values failed.\n"); ++ ret = EIO; ++ goto done; ++ } ++ ++ for (c = 0; c < count; c++) { ++ gr = talloc_get_type(values[c].ptr, ++ struct sdap_nested_group); ++ ++ /* The values from the hash are either user or group objects returned ++ * by sysdb_initgroups() which where used to start the request or ++ * nested parents found during the request. The nested parents contain ++ * the processed LDAP data and can be identified by a missing ++ * objectclass attribute. */ ++ ret = sdap_ad_get_domain_local_groups_parse_parents(state, gr, ++ state->dom, ++ state->sysdb, ++ state->opts, ++ &sysdb_name, ++ &type, ++ &add_list, ++ &del_list); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sdap_ad_get_domain_local_groups_parse_parents failed.\n"); ++ continue; ++ } ++ ++ if ((add_list == NULL && del_list == NULL) ++ || (add_list == NULL && del_list != NULL && del_list[0] == NULL) ++ || (add_list != NULL && add_list[0] == NULL && del_list == NULL) ++ || (add_list != NULL && add_list[0] == NULL ++ && del_list != NULL && del_list[0] == NULL) ) { ++ continue; ++ } ++ ++ DEBUG(SSSDBG_TRACE_INTERNAL, "Updating domain local memberships for %s\n", ++ sysdb_name); ++ ret = sysdb_update_members(state->dom, sysdb_name, type, ++ (const char *const *) add_list, ++ (const char *const *) del_list); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_members failed.\n"); ++ goto done; ++ } ++ } ++ ++ ret = EOK; ++done: ++ talloc_zfree(values); ++ ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { ++ tevent_req_error(req, ret); ++ } ++ ++ return; ++} ++ ++errno_t sdap_ad_get_domain_local_groups_recv(struct tevent_req *req) ++{ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ return EOK; ++} ++ + struct sdap_ad_tokengroups_initgroups_state { + bool use_id_mapping; + struct sss_domain_info *domain; +diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h +index 4af4f7144..266bc0311 100644 +--- a/src/providers/ldap/sdap_async_private.h ++++ b/src/providers/ldap/sdap_async_private.h +@@ -173,4 +173,14 @@ errno_t sdap_nested_groups_store(struct sysdb_ctx *sysdb, + struct sysdb_attrs **groups, + unsigned long count); + ++struct tevent_req * ++sdap_ad_get_domain_local_groups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct sdap_domain *local_sdom, ++ struct sdap_options *opts, ++ struct sysdb_ctx *sysdb, ++ struct sss_domain_info *dom, ++ struct sysdb_attrs **groups, ++ size_t num_groups); ++errno_t sdap_ad_get_domain_local_groups_recv(struct tevent_req *req); + #endif /* _SDAP_ASYNC_PRIVATE_H_ */ +-- +2.11.0 + diff --git a/sssd/patches/0015-PAM-add-a-test-for-filter_responses.patch b/sssd/patches/0015-PAM-add-a-test-for-filter_responses.patch new file mode 100644 index 0000000..e43b619 --- /dev/null +++ b/sssd/patches/0015-PAM-add-a-test-for-filter_responses.patch @@ -0,0 +1,121 @@ +From 84946be361a17bbb593f246849bd1357aa2f79da Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Thu, 20 Oct 2016 11:48:22 +0200 +Subject: [PATCH 15/39] PAM: add a test for filter_responses() + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit c8fe1d922b254aa92e74f428135ada3c8bde87a1) +(cherry picked from commit 0157678081e299660105c753f2d2ac2081960bca) +--- + src/responder/pam/pamsrv.h | 3 +++ + src/responder/pam/pamsrv_cmd.c | 4 ++-- + src/tests/cmocka/test_pam_srv.c | 52 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 57 insertions(+), 2 deletions(-) + +diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h +index e686d03a4..8437d082e 100644 +--- a/src/responder/pam/pamsrv.h ++++ b/src/responder/pam/pamsrv.h +@@ -99,4 +99,7 @@ errno_t + pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, + const char *username, + uint64_t value); ++ ++errno_t filter_responses(struct confdb_ctx *cdb, ++ struct response_data *resp_list); + #endif /* __PAMSRV_H__ */ +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index e52fc7642..b3690d763 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -470,8 +470,8 @@ fail: + return ret; + } + +-static errno_t filter_responses(struct confdb_ctx *cdb, +- struct response_data *resp_list) ++errno_t filter_responses(struct confdb_ctx *cdb, ++ struct response_data *resp_list) + { + int ret; + struct response_data *resp; +diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c +index 4b2dea4be..41d177233 100644 +--- a/src/tests/cmocka/test_pam_srv.c ++++ b/src/tests/cmocka/test_pam_srv.c +@@ -31,6 +31,7 @@ + #include "responder/pam/pam_helpers.h" + #include "sss_client/pam_message.h" + #include "sss_client/sss_cli.h" ++#include "confdb/confdb.h" + + #include "util/crypto/sss_crypto.h" + #ifdef HAVE_NSS +@@ -1759,6 +1760,54 @@ void test_pam_cert_auth(void **state) + assert_int_equal(ret, EOK); + } + ++void test_filter_response(void **state) ++{ ++ int ret; ++ struct pam_data *pd; ++ uint8_t offline_auth_data[(sizeof(uint32_t) + sizeof(int64_t))]; ++ uint32_t info_type; ++ ++ struct sss_test_conf_param pam_params[] = { ++ { CONFDB_PAM_VERBOSITY, "1" }, ++ { NULL, NULL }, /* Sentinel */ ++ }; ++ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ pd = talloc_zero(pam_test_ctx, struct pam_data); ++ assert_non_null(pd); ++ ++ info_type = SSS_PAM_USER_INFO_OFFLINE_AUTH; ++ memset(offline_auth_data, 0, sizeof(offline_auth_data)); ++ memcpy(offline_auth_data, &info_type, sizeof(uint32_t)); ++ ret = pam_add_response(pd, SSS_PAM_USER_INFO, ++ sizeof(offline_auth_data), offline_auth_data); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ ++ pam_params[0].value = "0"; ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ ++ /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with ++ * pam_verbosity 2 or above if cache password never expires. */ ++ pam_params[0].value = "2"; ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ assert_int_equal(ret, EOK); ++ assert_false(pd->resp_list->do_not_send_to_client); ++} ++ + int main(int argc, const char *argv[]) + { + int rv; +@@ -1870,6 +1919,9 @@ int main(int argc, const char *argv[]) + pam_test_setup_no_verification, + pam_test_teardown), + #endif /* HAVE_NSS */ ++ ++ cmocka_unit_test_setup_teardown(test_filter_response, ++ pam_test_setup, pam_test_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ +-- +2.11.0 + diff --git a/sssd/patches/0016-PAM-add-pam_response_filter-option.patch b/sssd/patches/0016-PAM-add-pam_response_filter-option.patch new file mode 100644 index 0000000..1d91a43 --- /dev/null +++ b/sssd/patches/0016-PAM-add-pam_response_filter-option.patch @@ -0,0 +1,501 @@ +From 51cdde0ce897c62a0e29653e896e3e6d43585228 Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Thu, 20 Oct 2016 18:40:01 +0200 +Subject: [PATCH 16/39] PAM: add pam_response_filter option + +Currently the main use-case for this new option is to not set the +KRB5CCNAME environment varible for services like 'sudo-i'. + +Resolves https://fedorahosted.org/sssd/ticket/2296 + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit ce43f710c9638fbbeae077559cd7514370a10c0c) +(cherry picked from commit 74711db46029415cc9590bb0e3f9cc662dac1d0c) +--- + src/confdb/confdb.h | 1 + + src/config/SSSDConfig/__init__.py.in | 1 + + src/config/cfg_rules.ini | 1 + + src/config/etc/sssd.api.conf | 1 + + src/man/sssd.conf.5.xml | 45 +++++++++++ + src/responder/pam/pamsrv.h | 3 +- + src/responder/pam/pamsrv_cmd.c | 111 ++++++++++++++++++++++++-- + src/tests/cmocka/test_pam_srv.c | 149 +++++++++++++++++++++++++++++++++-- + 8 files changed, 297 insertions(+), 15 deletions(-) + +diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h +index 011792fba..2a1e58184 100644 +--- a/src/confdb/confdb.h ++++ b/src/confdb/confdb.h +@@ -115,6 +115,7 @@ + #define CONFDB_PAM_FAILED_LOGIN_DELAY "offline_failed_login_delay" + #define CONFDB_DEFAULT_PAM_FAILED_LOGIN_DELAY 5 + #define CONFDB_PAM_VERBOSITY "pam_verbosity" ++#define CONFDB_PAM_RESPONSE_FILTER "pam_response_filter" + #define CONFDB_PAM_ID_TIMEOUT "pam_id_timeout" + #define CONFDB_PAM_PWD_EXPIRATION_WARNING "pam_pwd_expiration_warning" + #define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users" +diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in +index cde196478..381ff9596 100644 +--- a/src/config/SSSDConfig/__init__.py.in ++++ b/src/config/SSSDConfig/__init__.py.in +@@ -88,6 +88,7 @@ option_strings = { + 'offline_failed_login_attempts' : _('How many failed logins attempts are allowed when offline'), + 'offline_failed_login_delay' : _('How long (minutes) to deny login after offline_failed_login_attempts has been reached'), + 'pam_verbosity' : _('What kind of messages are displayed to the user during authentication'), ++ 'pam_response_filter' : _('Filter PAM responses send the pam_sss'), + 'pam_id_timeout' : _('How many seconds to keep identity information cached for PAM requests'), + 'pam_pwd_expiration_warning' : _('How many days before password expiration a warning should be displayed'), + 'pam_trusted_users' : _('List of trusted uids or user's name'), +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index b6316be8c..ec716b558 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -99,6 +99,7 @@ option = offline_credentials_expiration + option = offline_failed_login_attempts + option = offline_failed_login_delay + option = pam_verbosity ++option = pam_response_filter + option = pam_id_timeout + option = pam_pwd_expiration_warning + option = get_domains_timeout +diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf +index 567d52efe..be24bcea0 100644 +--- a/src/config/etc/sssd.api.conf ++++ b/src/config/etc/sssd.api.conf +@@ -58,6 +58,7 @@ offline_credentials_expiration = int, None, false + offline_failed_login_attempts = int, None, false + offline_failed_login_delay = int, None, false + pam_verbosity = int, None, false ++pam_response_filter = str, None, false + pam_id_timeout = int, None, false + pam_pwd_expiration_warning = int, None, false + get_domains_timeout = int, None, false +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index 8b862eb0c..71ace5208 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -975,6 +975,51 @@ fallback_homedir = /home/%u + </para> + </listitem> + </varlistentry> ++ ++ <varlistentry> ++ <term>pam_response_filter (integer)</term> ++ <listitem> ++ <para> ++ A comma separated list of strings which allows to ++ remove (filter) data send by the PAM responder to ++ pam_sss PAM module. There are different kind of ++ responses send to pam_sss e.g. messages displayed to ++ the user or environment variables which should be ++ set by pam_sss. ++ </para> ++ <para> ++ While messages already can be controlled with the ++ help of the pam_verbosity option this option allows ++ to filter out other kind of responses as well. ++ </para> ++ <para> ++ Currently the following filters are supported: ++ <variablelist> ++ <varlistentry><term>ENV</term> ++ <listitem><para>Do not sent any environment ++ variables to any service.</para></listitem> ++ </varlistentry> ++ <varlistentry><term>ENV:var_name</term> ++ <listitem><para>Do not sent environment ++ variable var_name to any ++ service.</para></listitem> ++ </varlistentry> ++ <varlistentry><term>ENV:var_name:service</term> ++ <listitem><para>Do not sent environment ++ variable var_name to ++ service.</para></listitem> ++ </varlistentry> ++ </variablelist> ++ </para> ++ <para> ++ Default: not set ++ </para> ++ <para> ++ Example: ENV:KRB5CCNAME:sudo-i ++ </para> ++ </listitem> ++ </varlistentry> ++ + <varlistentry> + <term>pam_id_timeout (integer)</term> + <listitem> +diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h +index 8437d082e..75045d039 100644 +--- a/src/responder/pam/pamsrv.h ++++ b/src/responder/pam/pamsrv.h +@@ -101,5 +101,6 @@ pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, + uint64_t value); + + errno_t filter_responses(struct confdb_ctx *cdb, +- struct response_data *resp_list); ++ struct response_data *resp_list, ++ struct pam_data *pd); + #endif /* __PAMSRV_H__ */ +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index b3690d763..0c2e6941c 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -470,14 +470,89 @@ fail: + return ret; + } + ++static errno_t filter_responses_env(struct response_data *resp, ++ struct pam_data *pd, ++ char * const *pam_filter_opts) ++{ ++ size_t c; ++ const char *var_name; ++ size_t var_name_len; ++ const char *service; ++ ++ if (pam_filter_opts == NULL) { ++ return EOK; ++ } ++ ++ for (c = 0; pam_filter_opts[c] != NULL; c++) { ++ if (strncmp(pam_filter_opts[c], "ENV", 3) != 0) { ++ continue; ++ } ++ ++ var_name = NULL; ++ var_name_len = 0; ++ service = NULL; ++ if (pam_filter_opts[c][3] != '\0') { ++ if (pam_filter_opts[c][3] != ':') { ++ /* Neither plain ENV nor ENV:, ignored */ ++ continue; ++ } ++ ++ var_name = pam_filter_opts[c] + 4; ++ /* check if there is a second ':' in the option and use the following ++ * data, if any, as service name. */ ++ service = strchr(var_name, ':'); ++ if (service == NULL) { ++ var_name_len = strlen(var_name); ++ } else { ++ var_name_len = service - var_name; ++ ++ service++; ++ /* handle empty service name "ENV:var:" */ ++ if (*service == '\0') { ++ service = NULL; ++ } ++ } ++ } ++ /* handle empty var name "ENV:" or "ENV::service" */ ++ if (var_name_len == 0) { ++ var_name = NULL; ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Found PAM ENV filter for variable [%.*s] and service [%s].\n", ++ (int) var_name_len, var_name, service); ++ ++ if (service != NULL && pd->service != NULL ++ && strcmp(service, pd->service) != 0) { ++ /* current service does not match the filter */ ++ continue; ++ } ++ ++ if (var_name == NULL) { ++ /* All environment variables should be filtered */ ++ resp->do_not_send_to_client = true; ++ continue; ++ } ++ ++ if (resp->len > var_name_len && resp->data[var_name_len] == '=' ++ && memcmp(resp->data, var_name, var_name_len) == 0) { ++ resp->do_not_send_to_client = true; ++ } ++ } ++ ++ return EOK; ++} ++ + errno_t filter_responses(struct confdb_ctx *cdb, +- struct response_data *resp_list) ++ struct response_data *resp_list, ++ struct pam_data *pd) + { + int ret; + struct response_data *resp; + uint32_t user_info_type; +- int64_t expire_date; +- int pam_verbosity; ++ int64_t expire_date = 0; ++ int pam_verbosity = DEFAULT_PAM_VERBOSITY; ++ char **pam_filter_opts = NULL; + + ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, + CONFDB_PAM_VERBOSITY, DEFAULT_PAM_VERBOSITY, +@@ -488,12 +563,22 @@ errno_t filter_responses(struct confdb_ctx *cdb, + pam_verbosity = DEFAULT_PAM_VERBOSITY; + } + ++ ret = confdb_get_string_as_list(cdb, pd, CONFDB_PAM_CONF_ENTRY, ++ CONFDB_PAM_RESPONSE_FILTER, ++ &pam_filter_opts); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CONF_SETTINGS, "[%s] not available, not fatal.\n", ++ CONFDB_PAM_RESPONSE_FILTER); ++ pam_filter_opts = NULL; ++ } ++ + resp = resp_list; + while(resp != NULL) { + if (resp->type == SSS_PAM_USER_INFO) { + if (resp->len < sizeof(uint32_t)) { + DEBUG(SSSDBG_CRIT_FAILURE, "User info entry is too short.\n"); +- return EINVAL; ++ ret = EINVAL; ++ goto done; + } + + if (pam_verbosity == PAM_VERBOSITY_NO_MESSAGES) { +@@ -511,7 +596,8 @@ errno_t filter_responses(struct confdb_ctx *cdb, + DEBUG(SSSDBG_CRIT_FAILURE, + "User info offline auth entry is " + "too short.\n"); +- return EINVAL; ++ ret = EINVAL; ++ goto done; + } + memcpy(&expire_date, resp->data + sizeof(uint32_t), + sizeof(int64_t)); +@@ -528,6 +614,13 @@ errno_t filter_responses(struct confdb_ctx *cdb, + "User info type [%d] not filtered.\n", + user_info_type); + } ++ } else if (resp->type == SSS_PAM_ENV_ITEM) { ++ resp->do_not_send_to_client = false; ++ ret = filter_responses_env(resp, pd, pam_filter_opts); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "filter_responses_env failed.\n"); ++ goto done; ++ } + } else if (resp->type & SSS_SERVER_INFO) { + resp->do_not_send_to_client = true; + } +@@ -535,7 +628,11 @@ errno_t filter_responses(struct confdb_ctx *cdb, + resp = resp->next; + } + +- return EOK; ++ ret = EOK; ++done: ++ talloc_free(pam_filter_opts); ++ ++ return ret; + } + + static void pam_reply_delay(struct tevent_context *ev, struct tevent_timer *te, +@@ -782,7 +879,7 @@ static void pam_reply(struct pam_auth_req *preq) + inform_user(pd, pam_account_locked_message); + } + +- ret = filter_responses(pctx->rctx->cdb, pd->resp_list); ++ ret = filter_responses(pctx->rctx->cdb, pd->resp_list, pd); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "filter_responses failed, not fatal.\n"); + } +diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c +index 41d177233..3b8327eb3 100644 +--- a/src/tests/cmocka/test_pam_srv.c ++++ b/src/tests/cmocka/test_pam_srv.c +@@ -1766,9 +1766,11 @@ void test_filter_response(void **state) + struct pam_data *pd; + uint8_t offline_auth_data[(sizeof(uint32_t) + sizeof(int64_t))]; + uint32_t info_type; ++ char *env; + + struct sss_test_conf_param pam_params[] = { + { CONFDB_PAM_VERBOSITY, "1" }, ++ { CONFDB_PAM_RESPONSE_FILTER, NULL }, + { NULL, NULL }, /* Sentinel */ + }; + +@@ -1778,6 +1780,15 @@ void test_filter_response(void **state) + pd = talloc_zero(pam_test_ctx, struct pam_data); + assert_non_null(pd); + ++ pd->service = discard_const("MyService"); ++ ++ env = talloc_asprintf(pd, "%s=%s", "MyEnv", "abcdef"); ++ assert_non_null(env); ++ ++ ret = pam_add_response(pd, SSS_PAM_ENV_ITEM, ++ strlen(env) + 1, (uint8_t *) env); ++ assert_int_equal(ret, EOK); ++ + info_type = SSS_PAM_USER_INFO_OFFLINE_AUTH; + memset(offline_auth_data, 0, sizeof(offline_auth_data)); + memcpy(offline_auth_data, &info_type, sizeof(uint32_t)); +@@ -1785,27 +1796,151 @@ void test_filter_response(void **state) + sizeof(offline_auth_data), offline_auth_data); + assert_int_equal(ret, EOK); + +- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ /* pd->resp_list points to the SSS_PAM_USER_INFO and pd->resp_list->next ++ * to the SSS_PAM_ENV_ITEM message. */ ++ ++ ++ /* Test CONFDB_PAM_VERBOSITY option */ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); + assert_int_equal(ret, EOK); + assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with ++ * pam_verbosity 2 or above if cache password never expires. */ ++ pam_params[0].value = "2"; ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_false(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); + + pam_params[0].value = "0"; + ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); + assert_int_equal(ret, EOK); + +- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); + assert_int_equal(ret, EOK); + assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); + +- /* SSS_PAM_USER_INFO_OFFLINE_AUTH message will only be shown with +- * pam_verbosity 2 or above if cache password never expires. */ +- pam_params[0].value = "2"; ++ /* Test CONFDB_PAM_RESPONSE_FILTER option */ ++ pam_params[1].value = "NoSuchOption"; + ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); + assert_int_equal(ret, EOK); + +- ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list); ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); + assert_int_equal(ret, EOK); +- assert_false(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV"; /* filter all environment variables */ ++ /* for all services */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:"; /* filter all environment variables */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV::"; /* filter all environment variables */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:abc:"; /* variable name does not match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:abc:MyService"; /* variable name does not match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV::abc"; /* service name does not match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ /* service name does not match */ ++ pam_params[1].value = "ENV:MyEnv:abc"; ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_false(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:MyEnv"; /* match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:MyEnv:"; /* match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ pam_params[1].value = "ENV:MyEnv:MyService"; /* match */ ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ /* multiple rules with a match */ ++ pam_params[1].value = "ENV:abc:def, " ++ "ENV:MyEnv:MyService, " ++ "ENV:stu:xyz"; ++ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); ++ assert_int_equal(ret, EOK); ++ ++ ret = filter_responses(pam_test_ctx->rctx->cdb, pd->resp_list, pd); ++ assert_int_equal(ret, EOK); ++ assert_true(pd->resp_list->do_not_send_to_client); ++ assert_true(pd->resp_list->next->do_not_send_to_client); ++ ++ talloc_free(pd); + } + + int main(int argc, const char *argv[]) +-- +2.11.0 + diff --git a/sssd/patches/0017-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch b/sssd/patches/0017-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch new file mode 100644 index 0000000..2780009 --- /dev/null +++ b/sssd/patches/0017-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch @@ -0,0 +1,343 @@ +From e6c3d9e680eab264777348389b4bcda73bd5ba6d Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Fri, 28 Oct 2016 13:46:02 +0200 +Subject: [PATCH 17/39] SYSDB: Split sysdb_try_to_find_expected_dn() into + smaller functions + +The function sysdb_try_to_find_expected_dn was performing several matching +algorithms and thus it was getting big and hard to extend. This patch +doesn't contain any functional changes, only shuffles the code around +and splits the monolithic sysdb_try_to_find_expected_dn function into +smaller blocks. + +Reviewed-by: Sumit Bose sbose@redhat.com +(cherry picked from commit e5a984093ad7921c83da75272cede2b0e52ba2d6) +(cherry picked from commit 3f3dc8c737a8e8cfc4a29d7dbaf526ec3973c7a0) +--- + src/db/sysdb_subdomains.c | 278 +++++++++++++++++++++++++++++----------------- + 1 file changed, 179 insertions(+), 99 deletions(-) + +diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c +index ff83f914f..b011bad6c 100644 +--- a/src/db/sysdb_subdomains.c ++++ b/src/db/sysdb_subdomains.c +@@ -1145,74 +1145,29 @@ done: + return ret; + } + +-errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, +- const char *domain_component_name, +- struct sysdb_attrs **usr_attrs, +- size_t count, +- struct sysdb_attrs **exp_usr) ++static errno_t match_cn_users(TALLOC_CTX *tmp_ctx, ++ struct sysdb_attrs **usr_attrs, ++ size_t count, ++ const char *dom_basedn, ++ struct sysdb_attrs **_result) + { +- char *dom_basedn; +- size_t dom_basedn_len; +- char *expected_basedn; +- size_t expected_basedn_len; +- size_t dn_len; ++ errno_t ret; + const char *orig_dn; +- size_t c = 0; +- int ret; +- TALLOC_CTX *tmp_ctx; +- struct ldb_context *ldb_ctx; +- struct ldb_dn *ldb_dom_basedn; +- int dom_basedn_comp_num; +- struct ldb_dn *ldb_dn; +- int dn_comp_num; +- const char *component_name; ++ size_t dn_len; + struct sysdb_attrs *result = NULL; + const char *result_dn_str = NULL; ++ char *cn_users_basedn; ++ size_t cn_users_basedn_len; + +- if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL +- || count == 0) { +- return EINVAL; +- } +- +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); +- return ENOMEM; +- } +- +- ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); +- goto done; +- } +- expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn); +- if (expected_basedn == NULL) { +- ret = ENOMEM; +- goto done; +- } +- +- ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); +- if (ldb_ctx == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); +- ret = EINVAL; +- goto done; +- } +- +- ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn); +- if (ldb_dom_basedn == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ++ cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn); ++ if (cn_users_basedn == NULL) { + ret = ENOMEM; + goto done; + } ++ cn_users_basedn_len = strlen(cn_users_basedn); ++ DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn); + +- dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn); +- dom_basedn_comp_num++; +- +- DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn); +- expected_basedn_len = strlen(expected_basedn); +- dom_basedn_len = strlen(dom_basedn); +- +- for (c = 0; c < count; c++) { ++ for (size_t c = 0; c < count; c++) { + ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); +@@ -1220,9 +1175,9 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + } + dn_len = strlen(orig_dn); + +- if (dn_len > expected_basedn_len +- && strcasecmp(orig_dn + (dn_len - expected_basedn_len), +- expected_basedn) == 0) { ++ if (dn_len > cn_users_basedn_len ++ && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len), ++ cn_users_basedn) == 0) { + DEBUG(SSSDBG_TRACE_ALL, + "Found matching dn [%s].\n", orig_dn); + if (result != NULL) { +@@ -1237,52 +1192,177 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + } + } + +- if (result == NULL) { +- for (c = 0; c < count; c++) { +- ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); ++ ret = EOK; ++done: ++ *_result = result; ++ return ret; ++} ++ ++static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx, ++ struct sss_domain_info *dom, ++ struct sysdb_attrs **usr_attrs, ++ size_t count, ++ struct ldb_dn *ldb_basedn, ++ const char *basedn, ++ const char *domain_component_name, ++ struct sysdb_attrs **_result) ++{ ++ errno_t ret; ++ const char *orig_dn; ++ size_t orig_dn_len; ++ size_t basedn_len; ++ struct ldb_context *ldb_ctx; ++ struct ldb_dn *ldb_orig_dn; ++ int dn_comp_num; ++ int basedn_comp_num; ++ const char *component_name; ++ struct sysdb_attrs *result = NULL; ++ const char *result_dn_str = NULL; ++ ++ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); ++ if (ldb_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); ++ ret = EINVAL; ++ goto done; ++ } ++ ++ basedn_len = strlen(basedn); ++ ++ basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn); ++ basedn_comp_num++; ++ ++ for (size_t c = 0; c < count; c++) { ++ ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); ++ goto done; ++ } ++ orig_dn_len = strlen(orig_dn); ++ ++ if (orig_dn_len > basedn_len ++ /* Does the user's original DN with the non-domain part ++ * stripped match the domain base DN? ++ */ ++ && strcasecmp(orig_dn + (orig_dn_len - basedn_len), ++ basedn) == 0) { ++ ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn); ++ if (ldb_orig_dn == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed"); ++ ret = ENOMEM; + goto done; + } +- dn_len = strlen(orig_dn); +- +- if (dn_len > dom_basedn_len +- && strcasecmp(orig_dn + (dn_len - dom_basedn_len), +- dom_basedn) == 0) { +- ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn); +- if (ldb_dn == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed"); +- ret = ENOMEM; +- goto done; +- } + +- dn_comp_num = ldb_dn_get_comp_num(ldb_dn); +- if (dn_comp_num > dom_basedn_comp_num) { +- component_name = ldb_dn_get_component_name(ldb_dn, +- (dn_comp_num - dom_basedn_comp_num)); +- DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n", +- component_name, +- domain_component_name); +- if (component_name != NULL +- && strcasecmp(component_name, +- domain_component_name) != 0) { +- DEBUG(SSSDBG_TRACE_ALL, +- "Found matching dn [%s].\n", orig_dn); +- if (result != NULL) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Found 2 matching DN [%s] and [%s], " +- "expecting only 1.\n", result_dn_str, orig_dn); +- ret = EINVAL; +- goto done; +- } +- result = usr_attrs[c]; +- result_dn_str = orig_dn; ++ dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn); ++ if (dn_comp_num > basedn_comp_num) { ++ component_name = ldb_dn_get_component_name(ldb_orig_dn, ++ (dn_comp_num - basedn_comp_num)); ++ DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n", ++ component_name, ++ domain_component_name); ++ /* If the component is NOT a DC component, then the entry ++ * must come from our domain, perhaps from a child container. ++ * If it matched the DC component, the entry was from a child ++ * subdomain different from this one. ++ */ ++ if (component_name != NULL ++ && strcasecmp(component_name, ++ domain_component_name) != 0) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Found matching dn [%s].\n", orig_dn); ++ if (result != NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Found 2 matching DN [%s] and [%s], " ++ "expecting only 1.\n", result_dn_str, orig_dn); ++ ret = EINVAL; ++ goto done; + } ++ result = usr_attrs[c]; ++ result_dn_str = orig_dn; + } + } + } + } + ++ ret = EOK; ++ *_result = result; ++done: ++ return ret; ++} ++ ++static errno_t match_basedn(TALLOC_CTX *tmp_ctx, ++ struct sss_domain_info *dom, ++ struct sysdb_attrs **usr_attrs, ++ size_t count, ++ const char *dom_basedn, ++ const char *domain_component_name, ++ struct sysdb_attrs **_result) ++{ ++ struct ldb_context *ldb_ctx; ++ struct ldb_dn *ldb_dom_basedn; ++ ++ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); ++ if (ldb_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); ++ return EINVAL; ++ } ++ ++ ++ ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn); ++ if (ldb_dom_basedn == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ++ return ENOMEM; ++ } ++ ++ return match_non_dc_comp(tmp_ctx, dom, ++ usr_attrs, count, ++ ldb_dom_basedn, dom_basedn, ++ domain_component_name, ++ _result); ++} ++ ++errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, ++ const char *domain_component_name, ++ struct sysdb_attrs **usr_attrs, ++ size_t count, ++ struct sysdb_attrs **exp_usr) ++{ ++ char *dom_basedn; ++ int ret; ++ TALLOC_CTX *tmp_ctx; ++ struct sysdb_attrs *result = NULL; ++ ++ if (dom == NULL || domain_component_name == NULL ++ || usr_attrs == NULL || count == 0) { ++ return EINVAL; ++ } ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ++ return ENOMEM; ++ } ++ ++ ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); ++ ret = EINVAL; ++ goto done; ++ } ++ ++ ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result); ++ if (ret != EOK) { ++ goto done; ++ } ++ ++ if (result == NULL) { ++ ret = match_basedn(tmp_ctx, dom, usr_attrs, ++ count, dom_basedn, domain_component_name, ++ &result); ++ if (ret != EOK) { ++ goto done; ++ } ++ } ++ + if (result == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n"); + ret = ENOENT; +-- +2.11.0 + diff --git a/sssd/patches/0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch b/sssd/patches/0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch new file mode 100644 index 0000000..f7cf404 --- /dev/null +++ b/sssd/patches/0018-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch @@ -0,0 +1,284 @@ +From 8e08e21b64a9ef67a4c40917786536d69d7ec4d3 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Mon, 31 Oct 2016 21:39:57 +0100 +Subject: [PATCH 18/39] SYSDB: Augment sysdb_try_to_find_expected_dn to match + search base as well + +In cases where the domain name in sssd.conf does not match the AD +domain, our previous matching process wouldn't match. This patch +augments the matching as follows: + - the search base is known to sysdb_try_to_find_expected_dn and is + expected to be non-NULL + - the existing matching is ran first + - during the search base, matching, all the non-DC components are + stripped from the search base to 'canonicalize' the search base + - if only a single entry that matches with a non-DC DN component + (matching with a DC component would mean the DN comes from a + different domain) then this entry is a match and is returned + +Resolves: +https://fedorahosted.org/sssd/ticket/3199 + +Reviewed-by: Sumit Bose sbose@redhat.com +(cherry picked from commit 24d8c85fae253f988165c112af208198cf48eef6) +(cherry picked from commit 956fdd727f8d7a28f1456146b3b7dfee49f38626) +--- + src/db/sysdb.h | 1 + + src/db/sysdb_subdomains.c | 99 ++++++++++++++++++++++++++++++ + src/providers/ldap/sdap_async_initgroups.c | 8 ++- + src/tests/cmocka/test_sysdb_subdomains.c | 43 +++++++++++-- + 4 files changed, 144 insertions(+), 7 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 901268390..5dedd97dd 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1297,6 +1297,7 @@ errno_t sysdb_handle_original_uuid(const char *orig_name, + + errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + const char *domain_component_name, ++ const char *ldap_search_base, + struct sysdb_attrs **usr_attrs, + size_t count, + struct sysdb_attrs **exp_usr); +diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c +index b011bad6c..780140484 100644 +--- a/src/db/sysdb_subdomains.c ++++ b/src/db/sysdb_subdomains.c +@@ -1320,8 +1320,97 @@ static errno_t match_basedn(TALLOC_CTX *tmp_ctx, + _result); + } + ++static errno_t match_search_base(TALLOC_CTX *tmp_ctx, ++ struct sss_domain_info *dom, ++ const char *domain_component_name, ++ const char *domain_search_base, ++ struct sysdb_attrs **usr_attrs, ++ size_t count, ++ struct sysdb_attrs **_result) ++{ ++ errno_t ret; ++ bool ok; ++ const char *search_base; ++ struct ldb_context *ldb_ctx; ++ struct sysdb_attrs *result = NULL; ++ struct ldb_dn *ldb_search_base; ++ int search_base_comp_num; ++ int non_dc_comp_num; ++ const char *component_name; ++ ++ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); ++ if (ldb_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); ++ ret = EINVAL; ++ goto done; ++ } ++ ++ ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base); ++ if (ldb_search_base == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ /* strip non-DC components from the search base */ ++ search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base); ++ for (non_dc_comp_num = 0; ++ non_dc_comp_num < search_base_comp_num; ++ non_dc_comp_num++) { ++ ++ component_name = ldb_dn_get_component_name(ldb_search_base, ++ non_dc_comp_num); ++ if (strcasecmp(domain_component_name, component_name) == 0) { ++ break; ++ } ++ } ++ ++ if (non_dc_comp_num == search_base_comp_num) { ++ /* The search base does not have any non-DC components, the search wouldn't ++ * match anyway ++ */ ++ ret = EOK; ++ *_result = NULL; ++ goto done; ++ } ++ ++ ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num); ++ if (!ok) { ++ ret = EINVAL; ++ goto done; ++ } ++ ++ search_base = ldb_dn_get_linearized(ldb_search_base); ++ if (search_base == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result); ++ if (ret != EOK) { ++ goto done; ++ } ++ ++ if (result == NULL) { ++ ret = match_non_dc_comp(tmp_ctx, dom, ++ usr_attrs, count, ++ ldb_search_base, search_base, ++ domain_component_name, ++ &result); ++ if (ret != EOK) { ++ goto done; ++ } ++ } ++ ++ ret = EOK; ++ *_result = result; ++done: ++ return ret; ++} ++ + errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + const char *domain_component_name, ++ const char *domain_search_base, + struct sysdb_attrs **usr_attrs, + size_t count, + struct sysdb_attrs **exp_usr) +@@ -1332,6 +1421,7 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + struct sysdb_attrs *result = NULL; + + if (dom == NULL || domain_component_name == NULL ++ || domain_search_base == NULL + || usr_attrs == NULL || count == 0) { + return EINVAL; + } +@@ -1364,6 +1454,15 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, + } + + if (result == NULL) { ++ ret = match_search_base(tmp_ctx, dom, domain_component_name, ++ domain_search_base, usr_attrs, count, ++ &result); ++ if (ret != EOK) { ++ goto done; ++ } ++ } ++ ++ if (result == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n"); + ret = ENOENT; + goto done; +diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c +index 45fc007e0..9b505e7fa 100644 +--- a/src/providers/ldap/sdap_async_initgroups.c ++++ b/src/providers/ldap/sdap_async_initgroups.c +@@ -2947,7 +2947,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) + DEBUG(SSSDBG_OP_FAILURE, + "Expected one user entry and got %zu\n", count); + +- ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count, ++ /* When matching against a search base, it's sufficient to pick only ++ * the first search base because all bases in a single domain would ++ * have the same DC= components ++ */ ++ ret = sysdb_try_to_find_expected_dn(state->dom, "dc", ++ state->sdom->search_bases[0]->basedn, ++ usr_attrs, count, + &state->orig_user); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c +index c9db56841..52056e043 100644 +--- a/src/tests/cmocka/test_sysdb_subdomains.c ++++ b/src/tests/cmocka/test_sysdb_subdomains.c +@@ -520,7 +520,9 @@ static void test_try_to_find_expected_dn(void **state) + int ret; + struct sysdb_attrs *result; + struct sysdb_attrs *usr_attrs[10] = { NULL }; ++ struct sysdb_attrs *dom_usr_attrs[10] = { NULL }; + struct sss_domain_info *dom; ++ char *dom_basedn; + struct subdom_test_ctx *test_ctx = + talloc_get_type(*state, struct subdom_test_ctx); + +@@ -528,6 +530,9 @@ static void test_try_to_find_expected_dn(void **state) + "child2.test_sysdb_subdomains_2", true); + assert_non_null(dom); + ++ ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn); ++ assert_int_equal(ret, EOK); ++ + usr_attrs[0] = sysdb_new_attrs(test_ctx); + assert_non_null(usr_attrs[0]); + +@@ -535,13 +540,13 @@ static void test_try_to_find_expected_dn(void **state) + "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); + assert_int_equal(ret, EOK); + +- ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL); ++ ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL); + assert_int_equal(ret, EINVAL); + +- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result); ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result); + assert_int_equal(ret, ENOENT); + +- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result); ++ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result); + assert_int_equal(ret, EOK); + assert_ptr_equal(result, usr_attrs[0]); + +@@ -559,11 +564,11 @@ static void test_try_to_find_expected_dn(void **state) + "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); + assert_int_equal(ret, EOK); + +- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result); ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result); + assert_int_equal(ret, EOK); + assert_ptr_equal(result, usr_attrs[1]); + +- ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result); ++ ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result); + assert_int_equal(ret, EINVAL); + + /* Make sure cn=users match is preferred */ +@@ -575,10 +580,36 @@ static void test_try_to_find_expected_dn(void **state) + "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2"); + assert_int_equal(ret, EOK); + +- ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result); ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result); + assert_int_equal(ret, EOK); + assert_ptr_equal(result, usr_attrs[2]); + ++ /* test a case where the domain name does not match the basedn */ ++ dom->name = discard_const("default"); ++ dom_usr_attrs[0] = usr_attrs[0]; ++ ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result); ++ assert_int_equal(ret, ENOENT); ++ ++ dom_usr_attrs[1] = usr_attrs[1]; ++ dom_usr_attrs[2] = usr_attrs[2]; ++ ++ /* Make sure cn=users match is preferred */ ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result); ++ assert_int_equal(ret, EOK); ++ assert_ptr_equal(result, dom_usr_attrs[2]); ++ ++ talloc_free(usr_attrs[2]); ++ usr_attrs[2] = sysdb_new_attrs(test_ctx); ++ assert_non_null(usr_attrs[2]); ++ ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, ++ "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); ++ assert_int_equal(ret, EOK); ++ ++ dom_usr_attrs[2] = usr_attrs[2]; ++ ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result); ++ assert_int_equal(ret, EOK); ++ assert_ptr_equal(result, usr_attrs[1]); + + talloc_free(usr_attrs[0]); + talloc_free(usr_attrs[1]); +-- +2.11.0 + diff --git a/sssd/patches/0019-ad_access_filter-search-for-nested-groups.patch b/sssd/patches/0019-ad_access_filter-search-for-nested-groups.patch new file mode 100644 index 0000000..671758d --- /dev/null +++ b/sssd/patches/0019-ad_access_filter-search-for-nested-groups.patch @@ -0,0 +1,55 @@ +From 7186923d877605f632fa17053a674f8266fd08bb Mon Sep 17 00:00:00 2001 +From: Mike Ely github@taupehat.com +Date: Wed, 2 Nov 2016 11:26:21 -0700 +Subject: [PATCH 19/39] ad_access_filter search for nested groups + +Includes instructions and example for AD nested group access + +Related to https://fedorahosted.org/sssd/ticket/3218 + +Signed-off-by: Mike Ely github@taupehat.com + +Reviewed-by: Sumit Bose sbose@redhat.com +(cherry picked from commit cf5357ae83cc9fe2240038b8bdccec2cb98991fc) +(cherry picked from commit e1c2aead482cd4bf83a7fe5e68630a981389e82b) +--- + src/man/sssd-ad.5.xml | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml +index 8a2f4ade9..2618f8324 100644 +--- a/src/man/sssd-ad.5.xml ++++ b/src/man/sssd-ad.5.xml +@@ -236,6 +236,19 @@ ad_enabled_domains = sales.example.com, eng.example.com + search bases work. + </para> + <para> ++ Nested group membership must be searched for using ++ a special OID <quote>:1.2.840.113556.1.4.1941:</quote> ++ in addition to the full DOM:domain.example.org: syntax ++ to ensure the parser does not attempt to interpret the ++ colon characters associated with the OID. If you do not ++ use this OID then nested group membership will not be ++ resolved. See usage example below and refer here ++ for further information about the OID: ++ <ulink ++ url="https://msdn.microsoft.com/en-us/library/cc223367.aspx%22%3E ++ [MS-ADTS] section LDAP extensions</ulink> ++ </para> ++ <para> + The most specific match is always used. For + example, if the option specified filter + for a domain the user is a member of and a +@@ -255,6 +268,9 @@ DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com) + + # apply filter on forest called EXAMPLE.COM only: + FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com) ++ ++# apply filter for a member of a nested group in dom1: ++DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example,dc=com) + </programlisting> + <para> + Default: Not set +-- +2.11.0 + diff --git a/sssd/patches/0020-BUILD-Fix-linking-with-librt.patch b/sssd/patches/0020-BUILD-Fix-linking-with-librt.patch new file mode 100644 index 0000000..2a57b22 --- /dev/null +++ b/sssd/patches/0020-BUILD-Fix-linking-with-librt.patch @@ -0,0 +1,61 @@ +From 90adb9afec7b3cd2f6548d7f050785777492c827 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 7 Nov 2016 11:53:21 +0100 +Subject: [PATCH 20/39] BUILD: Fix linking with librt + +The posix realime extensions defines timer_* functions +but it does not mention library with these functions. +http://www.unix.org/version2/whatsnew/realtime.html + +The autoconf macro AC_SEARCH_LIBS firstly check the function +timer_create with no libraries, then for each library listed +in 2nd parameter. Possible libraries librt and libposix4 +were used in nspr for similar detection. + +Reviewed-by: Joakim Tjernlund joakim.tjernlund@infinera.com +(cherry picked from commit 6d11fdcd8ef05000dd20b3431f8491790f99a802) +(cherry picked from commit a3b668868a1c10be63be9151d347100172b71c6c) +--- + Makefile.am | 1 + + configure.ac | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/Makefile.am b/Makefile.am +index d08e39fa4..51c67360d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -960,6 +960,7 @@ libsss_util_la_CFLAGS = \ + $(SYSTEMD_LOGIN_CFLAGS) \ + $(NULL) + libsss_util_la_LIBADD = \ ++ $(LIBADD_TIMER) \ + $(SSSD_LIBS) \ + $(SYSTEMD_LOGIN_LIBS) \ + $(UNICODE_LIBS) \ +diff --git a/configure.ac b/configure.ac +index 3dbcf9e1f..d3ef1e162 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -70,6 +70,19 @@ AC_CHECK_FUNCS([ pthread_mutexattr_setrobust \ + pthread_mutex_consistent_np ]) + LIBS=$SAVE_LIBS + ++# Check library for the timer_create function ++SAVE_LIBS=$LIBS ++LIBS= ++LIBADD_TIMER= ++AC_SEARCH_LIBS([timer_create], [rt posix4], ++ [AC_DEFINE([HAVE_LIBRT], [1], ++ [Define if you have the librt library or equivalent.]) ++ LIBADD_TIMER="$LIBS"], ++ [AC_MSG_ERROR([unable to find library fot the timer_create() function])]) ++ ++AC_SUBST([LIBADD_TIMER]) ++LIBS=$SAVE_LIBS ++ + # Check for presence of modern functions for setting file timestamps + AC_CHECK_FUNCS([ utimensat \ + futimens ]) +-- +2.11.0 + diff --git a/sssd/patches/0021-MONITOR-Do-not-set-up-watchdog-for-monitor.patch b/sssd/patches/0021-MONITOR-Do-not-set-up-watchdog-for-monitor.patch new file mode 100644 index 0000000..797fe61 --- /dev/null +++ b/sssd/patches/0021-MONITOR-Do-not-set-up-watchdog-for-monitor.patch @@ -0,0 +1,74 @@ +From 287acba9b1b7d91811d8e8a22ed5e7824e8a26b3 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Mon, 7 Nov 2016 11:58:20 +0100 +Subject: [PATCH 21/39] MONITOR: Do not set up watchdog for monitor +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It makes little sense to set up watchdog for monitor because there is no +entity that would restart the monitor. Therefore we should disable the +watchdog for monitor process. + +Resolves: +https://fedorahosted.org/sssd/ticket/3232 + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit fbe6644aa28d93f492434950680c5618eb567712) +(cherry picked from commit 2d88a121918e800b266d018d43dad9bd374b10a7) +--- + src/monitor/monitor.c | 2 ++ + src/util/server.c | 11 +++++++---- + src/util/util.h | 1 + + 3 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c +index 84a144e56..935febb95 100644 +--- a/src/monitor/monitor.c ++++ b/src/monitor/monitor.c +@@ -2603,6 +2603,8 @@ int main(int argc, const char *argv[]) + + /* we want a pid file check */ + flags |= FLAGS_PID_FILE; ++ /* the monitor should not run a watchdog on itself */ ++ flags |= FLAGS_NO_WATCHDOG; + + /* Open before server_setup() does to have logging + * during configuration checking */ +diff --git a/src/util/server.c b/src/util/server.c +index 953cd3d61..013e572e6 100644 +--- a/src/util/server.c ++++ b/src/util/server.c +@@ -666,10 +666,13 @@ int server_setup(const char *name, int flags, + ret, strerror(ret)); + return ret; + } +- ret = setup_watchdog(ctx->event_ctx, watchdog_interval); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n"); +- return ret; ++ ++ if ((flags & FLAGS_NO_WATCHDOG) == 0) { ++ ret = setup_watchdog(ctx->event_ctx, watchdog_interval); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n"); ++ return ret; ++ } + } + + sss_log(SSS_LOG_INFO, "Starting up"); +diff --git a/src/util/util.h b/src/util/util.h +index 9c39a5cc5..4bfccfa2b 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -88,6 +88,7 @@ + #define FLAGS_INTERACTIVE 0x0002 + #define FLAGS_PID_FILE 0x0004 + #define FLAGS_GEN_CONF 0x0008 ++#define FLAGS_NO_WATCHDOG 0x0010 + + #define PIPE_INIT { -1, -1 } + +-- +2.11.0 + diff --git a/sssd/patches/0022-SYSDB-Adding-lowercase-sudoUser-form.patch b/sssd/patches/0022-SYSDB-Adding-lowercase-sudoUser-form.patch new file mode 100644 index 0000000..ffb4b19 --- /dev/null +++ b/sssd/patches/0022-SYSDB-Adding-lowercase-sudoUser-form.patch @@ -0,0 +1,107 @@ +From b87ca4233342e1537fda5ce731db77cf24e422c3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20=C4=8Cech?= pcech@redhat.com +Date: Wed, 12 Oct 2016 16:48:38 +0200 +Subject: [PATCH 22/39] SYSDB: Adding lowercase sudoUser form +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If domain is not case sensitive we add lowercase form of usernames +to sudoUser attributes. So we actually able to apply sudoRule on +user Administrator@... with login admnistrator@... + +Resolves: +https://fedorahosted.org/sssd/ticket/3203 + +Reviewed-by: Pavel Březina pbrezina@redhat.com +(cherry picked from commit f4a1046bb88d7a0ab3617e49ae94bfa849d10645) +(cherry picked from commit 88239b7f17f599aefa88a8a31c2d0ea44b766c87) +--- + src/db/sysdb_sudo.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c +index 601fb63f2..4bd93ffc6 100644 +--- a/src/db/sysdb_sudo.c ++++ b/src/db/sysdb_sudo.c +@@ -852,6 +852,65 @@ sysdb_sudo_add_sss_attrs(struct sysdb_attrs *rule, + return EOK; + } + ++static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain, ++ struct sysdb_attrs *rule) ++{ ++ TALLOC_CTX *tmp_ctx; ++ const char **users = NULL; ++ const char *lowered = NULL; ++ errno_t ret; ++ ++ if (domain->case_sensitive == true || rule == NULL) { ++ return EOK; ++ } ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ return ENOMEM; ++ } ++ ++ ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_USER, tmp_ctx, ++ &users); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n", ++ SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret)); ++ goto done; ++ } ++ ++ if (users == NULL) { ++ ret = EOK; ++ goto done; ++ } ++ ++ for (int i = 0; users[i] != NULL; i++) { ++ lowered = sss_tc_utf8_str_tolower(tmp_ctx, users[i]); ++ if (lowered == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ if (strcmp(users[i], lowered) == 0) { ++ /* It protects us from adding duplicate. */ ++ continue; ++ } ++ ++ ret = sysdb_attrs_add_string(rule, SYSDB_SUDO_CACHE_AT_USER, lowered); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Unable to add %s attribute [%d]: %s\n", ++ SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret)); ++ goto done; ++ } ++ } ++ ++ ret = EOK; ++ ++done: ++ talloc_zfree(tmp_ctx); ++ return ret; ++} ++ + static errno_t + sysdb_sudo_store_rule(struct sss_domain_info *domain, + struct sysdb_attrs *rule, +@@ -868,6 +927,11 @@ sysdb_sudo_store_rule(struct sss_domain_info *domain, + + DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", name); + ++ ret = sysdb_sudo_add_lowered_users(domain, rule); ++ if (ret != EOK) { ++ return ret; ++ } ++ + ret = sysdb_sudo_add_sss_attrs(rule, name, cache_timeout, now); + if (ret != EOK) { + return ret; +-- +2.11.0 + diff --git a/sssd/patches/0023-TESTS-Extending-sysdb-sudo-store-tests.patch b/sssd/patches/0023-TESTS-Extending-sysdb-sudo-store-tests.patch new file mode 100644 index 0000000..3b6ae0b --- /dev/null +++ b/sssd/patches/0023-TESTS-Extending-sysdb-sudo-store-tests.patch @@ -0,0 +1,225 @@ +From 1cd53e7a9cdb95aeca6a3f9ae4a6e32072f74ee7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20=C4=8Cech?= pcech@redhat.com +Date: Thu, 13 Oct 2016 09:31:52 +0200 +Subject: [PATCH 23/39] TESTS: Extending sysdb sudo store tests +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We covered diference between case sensitive and case insensitive +domains. If domain is case insensitive we add lowercase form of +sudoUser to local sysdb cache. + +Resolves: +https://fedorahosted.org/sssd/ticket/3203 + +Reviewed-by: Pavel Březina pbrezina@redhat.com +(cherry picked from commit 23637e2fd2b1fe42bdd2335893a11ac8016f56bc) +(cherry picked from commit 143b1dcbbe865a139616a22b139e19bd772e46f0) +--- + src/tests/cmocka/test_sysdb_sudo.c | 168 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 167 insertions(+), 1 deletion(-) + +diff --git a/src/tests/cmocka/test_sysdb_sudo.c b/src/tests/cmocka/test_sysdb_sudo.c +index 889de7237..f21ff3655 100644 +--- a/src/tests/cmocka/test_sysdb_sudo.c ++++ b/src/tests/cmocka/test_sysdb_sudo.c +@@ -44,7 +44,7 @@ struct test_user { + const char *name; + uid_t uid; + gid_t gid; +-} users[] = { { "test_user1", 1001, 1001 }, ++} users[] = { { "test_USER1", 1001, 1001 }, + { "test_user2", 1002, 1002 }, + { "test_user3", 1003, 1003 } }; + +@@ -104,6 +104,29 @@ static void create_rule_attrs(struct sysdb_attrs *rule, int i) + assert_int_equal(ret, EOK); + } + ++static void create_rule_attrs_multiple_sudoUser(struct sysdb_attrs *rule) ++{ ++ errno_t ret; ++ ++ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_CN, ++ rules[0].name); ++ assert_int_equal(ret, EOK); ++ ++ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_HOST, ++ rules[0].host); ++ assert_int_equal(ret, EOK); ++ ++ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_RUNASUSER, ++ rules[0].as_user); ++ assert_int_equal(ret, EOK); ++ ++ for (int i = 0; i < 3; i++ ) { ++ ret = sysdb_attrs_add_string_safe(rule, SYSDB_SUDO_CACHE_AT_USER, ++ users[i].name); ++ assert_int_equal(ret, EOK); ++ } ++} ++ + static int get_stored_rules_count(struct sysdb_test_ctx *test_ctx) + { + errno_t ret; +@@ -217,6 +240,143 @@ void test_store_sudo(void **state) + talloc_zfree(msgs); + } + ++void test_store_sudo_case_sensitive(void **state) ++{ ++ errno_t ret; ++ char *filter; ++ const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST, ++ SYSDB_SUDO_CACHE_AT_RUNASUSER, ++ SYSDB_SUDO_CACHE_AT_USER, NULL }; ++ struct ldb_message **msgs = NULL; ++ size_t msgs_count; ++ const char *result; ++ struct ldb_message_element *element; ++ struct sysdb_attrs *rule; ++ struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, ++ struct sysdb_test_ctx); ++ const char *lowered_name = sss_tc_utf8_str_tolower(test_ctx, users[0].name); ++ ++ rule = sysdb_new_attrs(test_ctx); ++ assert_non_null(rule); ++ create_rule_attrs_multiple_sudoUser(rule); ++ ++ test_ctx->tctx->dom->case_sensitive = true; ++ ++ ret = sysdb_sudo_store(test_ctx->tctx->dom, &rule, 1); ++ assert_int_equal(ret, EOK); ++ ++ filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0); ++ assert_non_null(filter); ++ ++ ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter, ++ attrs, &msgs_count, &msgs); ++ assert_int_equal(ret, EOK); ++ ++ assert_int_equal(msgs_count, 1); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_CN, NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].name); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_HOST, ++ NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].host); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_RUNASUSER, ++ NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].as_user); ++ ++ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER, ++ users[0].name); ++ assert_int_equal(ret, 1); ++ ++ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER, ++ lowered_name); ++ assert_int_equal(ret, 0); ++ ++ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER, ++ users[1].name); ++ assert_int_equal(ret, 1); ++ ++ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER, ++ users[2].name); ++ assert_int_equal(ret, 1); ++ ++ element = ldb_msg_find_element(msgs[0], SYSDB_SUDO_CACHE_AT_USER); ++ assert_int_equal(element->num_values, 3); ++ ++ talloc_zfree(lowered_name); ++ talloc_zfree(rule); ++ talloc_zfree(filter); ++ talloc_zfree(msgs); ++} ++ ++void test_store_sudo_case_insensitive(void **state) ++{ ++ errno_t ret; ++ char *filter; ++ const char *attrs[] = { SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_HOST, ++ SYSDB_SUDO_CACHE_AT_RUNASUSER, ++ SYSDB_SUDO_CACHE_AT_USER, NULL }; ++ struct ldb_message **msgs = NULL; ++ size_t msgs_count; ++ const char *result; ++ struct ldb_message_element *element; ++ struct sysdb_attrs *rule; ++ struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, ++ struct sysdb_test_ctx); ++ const char *lowered_name = sss_tc_utf8_str_tolower(test_ctx, users[0].name); ++ ++ rule = sysdb_new_attrs(test_ctx); ++ assert_non_null(rule); ++ create_rule_attrs_multiple_sudoUser(rule); ++ ++ test_ctx->tctx->dom->case_sensitive = false; ++ ++ ret = sysdb_sudo_store(test_ctx->tctx->dom, &rule, 1); ++ assert_int_equal(ret, EOK); ++ ++ filter = sysdb_sudo_filter_user(test_ctx, users[0].name, NULL, 0); ++ assert_non_null(filter); ++ ++ ret = sysdb_search_sudo_rules(test_ctx, test_ctx->tctx->dom, filter, ++ attrs, &msgs_count, &msgs); ++ assert_int_equal(ret, EOK); ++ ++ assert_int_equal(msgs_count, 1); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_CN, NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].name); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_HOST, ++ NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].host); ++ ++ result = ldb_msg_find_attr_as_string(msgs[0], SYSDB_SUDO_CACHE_AT_RUNASUSER, ++ NULL); ++ assert_non_null(result); ++ assert_string_equal(result, rules[0].as_user); ++ ++ for (int i = 0; i < 3; i++) { ++ ret = ldb_msg_check_string_attribute(msgs[0], SYSDB_SUDO_CACHE_AT_USER, ++ users[i].name); ++ assert_int_equal(ret, 1); ++ } ++ ++ /* test there is no duplication of lowercase forms */ ++ element = ldb_msg_find_element(msgs[0], SYSDB_SUDO_CACHE_AT_USER); ++ assert_int_equal(element->num_values, 4); ++ ++ talloc_zfree(lowered_name); ++ talloc_zfree(rule); ++ talloc_zfree(filter); ++ talloc_zfree(msgs); ++} ++ + void test_sudo_purge_by_filter(void **state) + { + errno_t ret; +@@ -648,6 +808,12 @@ int main(int argc, const char *argv[]) + cmocka_unit_test_setup_teardown(test_store_sudo, + test_sysdb_setup, + test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_store_sudo_case_sensitive, ++ test_sysdb_setup, ++ test_sysdb_teardown), ++ cmocka_unit_test_setup_teardown(test_store_sudo_case_insensitive, ++ test_sysdb_setup, ++ test_sysdb_teardown), + + /* sysdb_sudo_purge() */ + cmocka_unit_test_setup_teardown(test_sudo_purge_by_filter, +-- +2.11.0 + diff --git a/sssd/patches/0024-IPA-AD-check-auth-ctx-before-using-it.patch b/sssd/patches/0024-IPA-AD-check-auth-ctx-before-using-it.patch new file mode 100644 index 0000000..e0d1b7d --- /dev/null +++ b/sssd/patches/0024-IPA-AD-check-auth-ctx-before-using-it.patch @@ -0,0 +1,93 @@ +From a859747b84125124ea794aa422f5b811bb0dba2d Mon Sep 17 00:00:00 2001 +From: Sumit Bose sbose@redhat.com +Date: Tue, 8 Nov 2016 11:51:57 +0100 +Subject: [PATCH 24/39] IPA/AD: check auth ctx before using it + +In e6b6b9fa79c67d7d2698bc7e33d2e2f6bb53d483 a feature was introduced to +set the 'canonicalize' option in the system-wide Kerberos configuration +according to the settings in SSSD if the AD or IPA provider were used. +Unfortunately the patch implied that the auth provider is the same as +the id provider which might not always be the case. A different auth +provider caused a crash in the backend which is fixed by this patch. + +Resolves https://fedorahosted.org/sssd/ticket/3234 + +Reviewed-by: Petr Cech pcech@redhat.com +(cherry picked from commit ea11ed3ea6291488dd762033246edc4ce3951aeb) +(cherry picked from commit 37e070c8c2ea79d8d84bae3da3a34c81212744ab) +--- + src/providers/ad/ad_subdomains.c | 13 +++++++++++-- + src/providers/ipa/ipa_subdomains.c | 20 +++++++++++++++++--- + 2 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index 52bf5361f..5e57d218c 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -618,14 +618,23 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *subdoms_ctx) + { + const char *path; + errno_t ret; +- bool canonicalize; ++ bool canonicalize = false; + + path = dp_opt_get_string(subdoms_ctx->ad_id_ctx->ad_options->basic, + AD_KRB5_CONFD_PATH); + +- canonicalize = dp_opt_get_bool( ++ if (subdoms_ctx->ad_id_ctx->ad_options->auth_ctx != NULL ++ && subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts != NULL) { ++ canonicalize = dp_opt_get_bool( + subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts, + KRB5_CANONICALIZE); ++ } else { ++ DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, " ++ "most probably because the auth provider " ++ "is not 'ad'. Kerberos configuration " ++ "snippet to set the 'canonicalize' option " ++ "will not be created.\n"); ++ } + + ret = sss_write_krb5_conf_snippet(path, canonicalize); + if (ret != EOK) { +diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c +index 8653e3f46..b2e96b204 100644 +--- a/src/providers/ipa/ipa_subdomains.c ++++ b/src/providers/ipa/ipa_subdomains.c +@@ -73,16 +73,30 @@ static errno_t + ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx) + { + errno_t ret; ++ bool canonicalize = false; + + DEBUG(SSSDBG_TRACE_INTERNAL, + "Re-initializing domain %s\n", ctx->be_ctx->domain->name); + ++ if (ctx->ipa_id_ctx->ipa_options->auth_ctx != NULL ++ && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx != NULL ++ && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts != NULL ++ ) { ++ canonicalize = dp_opt_get_bool( ++ ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts, ++ KRB5_CANONICALIZE); ++ } else { ++ DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, " ++ "most probably because the auth provider " ++ "is not 'ipa'. Kerberos configuration " ++ "snippet to set the 'canonicalize' option " ++ "will not be created.\n"); ++ } ++ + ret = sss_write_krb5_conf_snippet( + dp_opt_get_string(ctx->ipa_id_ctx->ipa_options->basic, + IPA_KRB5_CONFD_PATH), +- dp_opt_get_bool( +- ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts, +- KRB5_CANONICALIZE)); ++ canonicalize); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n"); + /* Just continue */ +-- +2.11.0 + diff --git a/sssd/patches/0025-SECRETS-Fix-secrets-rule-in-the-allowed-sections.patch b/sssd/patches/0025-SECRETS-Fix-secrets-rule-in-the-allowed-sections.patch new file mode 100644 index 0000000..27f461a --- /dev/null +++ b/sssd/patches/0025-SECRETS-Fix-secrets-rule-in-the-allowed-sections.patch @@ -0,0 +1,50 @@ +From c0a516f5d91290135c6b019a8a9d269edf8214cd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= fidencio@redhat.com +Date: Mon, 17 Oct 2016 17:07:56 +0200 +Subject: [PATCH 25/39] SECRETS: Fix secrets rule in the allowed sections +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We have been matching an invalid subsection of the secrets' section, +like: +[secrets/users/] + +Let's ensure that we only match the following cases: +[secrets] +[secrets/users/[0-9]+] + +Signed-off-by: Fabiano Fidêncio fidencio@redhat.com + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit da8801c363716533f60bc78e10f3a2100cebc3a1) +(cherry picked from commit 2535993d81c7d0dbbd6c6fab6f45b338845535cf) +--- + src/config/cfg_rules.ini | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index ec716b558..24937c969 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -8,7 +8,7 @@ section = autofs + section = ssh + section = pac + section = ifp +-section_re = ^secrets(/users/([0-9]+)?)?$ ++section_re = ^secrets(/users/[0-9]+)?$ + section_re = ^domain/.*$ + + [rule/allowed_sssd_options] +@@ -213,7 +213,7 @@ option = user_attributes + + [rule/allowed_sec_options] + validator = ini_allowed_options +-section_re = ^secrets(/users/([0-9]+)?)?$ ++section_re = ^secrets(/users/[0-9]+)?$ + + option = timeout + option = debug +-- +2.11.0 + diff --git a/sssd/patches/0026-SECRETS-Add-allowed_sec_users_options.patch b/sssd/patches/0026-SECRETS-Add-allowed_sec_users_options.patch new file mode 100644 index 0000000..70c3e1e --- /dev/null +++ b/sssd/patches/0026-SECRETS-Add-allowed_sec_users_options.patch @@ -0,0 +1,70 @@ +From c16214f71f8ab2a5fc122966159ce056e0e9e897 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= fidencio@redhat.com +Date: Mon, 17 Oct 2016 18:58:50 +0200 +Subject: [PATCH 26/39] SECRETS: Add allowed_sec_users_options +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are options (the proxying related ones) that only apply to the +secrets' subsections. In order to make config API able to catch those, +let's create a new section called allowed_sec_users_options) and move +there these proxying options. + +Signed-off-by: Fabiano Fidêncio fidencio@redhat.com + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 682c9c3467055c2149af28826f7458b857b0f8c4) +(cherry picked from commit 9d4cc96f2951412f647223dfe59060fa1e2b7b14) +--- + src/config/cfg_rules.ini | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index 24937c969..882a185d8 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -8,7 +8,8 @@ section = autofs + section = ssh + section = pac + section = ifp +-section_re = ^secrets(/users/[0-9]+)?$ ++section = secrets ++section_re = ^secrets/users/[0-9]+$ + section_re = ^domain/.*$ + + [rule/allowed_sssd_options] +@@ -211,9 +212,10 @@ option = description + option = allowed_uids + option = user_attributes + ++# Secrets service + [rule/allowed_sec_options] + validator = ini_allowed_options +-section_re = ^secrets(/users/[0-9]+)?$ ++section_re = ^secrets$ + + option = timeout + option = debug +@@ -226,12 +228,15 @@ option = reconnection_retries + option = fd_limit + option = client_idle_timeout + option = description +- +-# Secrets service +-option = provider + option = containers_nest_level + option = max_secrets ++ ++[rule/allowed_sec_users_options] ++validator = ini_allowed_options ++section_re = ^secrets/users/[0-9]+$ ++ + # Secrets service - proxy ++option = provider + option = proxy_url + option = auth_type + option = auth_header_name +-- +2.11.0 + diff --git a/sssd/patches/0027-ipa-Nested-netgroups-do-not-work.patch b/sssd/patches/0027-ipa-Nested-netgroups-do-not-work.patch new file mode 100644 index 0000000..d6a2838 --- /dev/null +++ b/sssd/patches/0027-ipa-Nested-netgroups-do-not-work.patch @@ -0,0 +1,62 @@ +From 9ccd49a3bcabd8eb32a559af2cacf2b0fdcfad96 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= mzidek@redhat.com +Date: Thu, 10 Nov 2016 15:04:57 +0100 +Subject: [PATCH 27/39] ipa: Nested netgroups do not work + +We lowercase the keys to the hash table used to store netgroups +but do not lowercase it when reading the table. This results +in nested netgroups not being found when they should and +the processing fails. + +The lowercasing does not seem to be necessary anymore (not +sure if it ever was) so we can skip it. + +Resolves: +https://fedorahosted.org/sssd/ticket/3159 + +Reviewed-by: Petr Cech pcech@redhat.com +(cherry picked from commit ff565da1011aa4312847e28e7af66e57fccf8b90) +(cherry picked from commit 7de33877c7e39f9a5cae6baf815dc18ae5a18597) +--- + src/providers/ipa/ipa_netgroups.c | 15 +++------------ + 1 file changed, 3 insertions(+), 12 deletions(-) + +diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c +index a19e5e03d..17b11af5d 100644 +--- a/src/providers/ipa/ipa_netgroups.c ++++ b/src/providers/ipa/ipa_netgroups.c +@@ -563,7 +563,6 @@ static void ipa_netgr_members_process(struct tevent_req *subreq) + size_t count; + int ret, i; + const char *orig_dn; +- char *orig_dn_lower; + hash_table_t *table; + hash_key_t key; + hash_value_t value; +@@ -638,20 +637,12 @@ static void ipa_netgr_members_process(struct tevent_req *subreq) + goto fail; + } + +- orig_dn_lower = talloc_strdup(table, orig_dn); +- if (orig_dn_lower == NULL) { ++ key.str = talloc_strdup(table, orig_dn); ++ if (key.str == NULL) { + ret = ENOMEM; + goto fail; + } +- /* Transform the DN to lower case. +- * this is important, as the member/memberof attributes +- * have the value also in lower-case +- */ +- key.str = orig_dn_lower; +- while (*orig_dn_lower != '\0') { +- *orig_dn_lower = tolower(*orig_dn_lower); +- orig_dn_lower++; +- } ++ + value.ptr = entities[i]; + ret = hash_enter(table, &key, &value); + if (ret != HASH_SUCCESS) { +-- +2.11.0 + diff --git a/sssd/patches/0028-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch b/sssd/patches/0028-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch new file mode 100644 index 0000000..ea1476b --- /dev/null +++ b/sssd/patches/0028-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch @@ -0,0 +1,61 @@ +From 712f064ed197063016fee16a3438fb22f08759bf Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Wed, 9 Nov 2016 11:59:10 +0100 +Subject: [PATCH 28/39] Qualify ghost user attribute in case + ldap_group_nesting_level is set to 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When the sssd is set to not resolve nested groups with RFC2307bis, then +the LDAP provider takes a different path. We didn't qualify the ghost +users in this case. + +Resolves: +https://fedorahosted.org/sssd/ticket/3236 + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit 538a7f1dd8339b90e0cfc64e7919a34d1d5c10d3) +(cherry picked from commit e0b544e6f664c2ce5ddd8df866d996607ce488cc) +--- + src/providers/ldap/sdap_async_groups.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c +index 08dfa01b1..81503798c 100644 +--- a/src/providers/ldap/sdap_async_groups.c ++++ b/src/providers/ldap/sdap_async_groups.c +@@ -1668,7 +1668,7 @@ static void sdap_process_group_members(struct tevent_req *subreq) + struct sdap_process_group_state *state = + tevent_req_data(req, struct sdap_process_group_state); + struct ldb_message_element *el; +- uint8_t* name_string; ++ char *name_string; + + state->check_count--; + DEBUG(SSSDBG_TRACE_ALL, "Members remaining: %zu\n", state->check_count); +@@ -1694,11 +1694,18 @@ static void sdap_process_group_members(struct tevent_req *subreq) + goto next; + } + +- name_string = el[0].values[0].data; ++ name_string = sss_create_internal_fqname(state, ++ (const char *) el[0].values[0].data, ++ state->dom->name); ++ if (name_string == NULL) { ++ ret = ENOMEM; ++ goto next; ++ } ++ + state->ghost_dns->values[state->ghost_dns->num_values].data = +- talloc_steal(state->ghost_dns->values, name_string); ++ talloc_steal(state->ghost_dns->values, (uint8_t *) name_string); + state->ghost_dns->values[state->ghost_dns->num_values].length = +- strlen((char *)name_string); ++ strlen(name_string); + state->ghost_dns->num_values++; + + next: +-- +2.11.0 + diff --git a/sssd/patches/0029-tests-Add-a-test-for-group-resolution-with-ldap_grou.patch b/sssd/patches/0029-tests-Add-a-test-for-group-resolution-with-ldap_grou.patch new file mode 100644 index 0000000..d9a763e --- /dev/null +++ b/sssd/patches/0029-tests-Add-a-test-for-group-resolution-with-ldap_grou.patch @@ -0,0 +1,56 @@ +From a72d7cf57143ca56834c6bb33b289ba98ed02b91 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Wed, 9 Nov 2016 11:59:34 +0100 +Subject: [PATCH 29/39] tests: Add a test for group resolution with + ldap_group_nesting_level=0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +(cherry picked from commit 65e791f844b4513ca2c3ee23f8cd2979566b3719) +(cherry picked from commit a7be684411aff42e03e181dd81de921185e16c34) +--- + src/tests/intg/test_ldap.py | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py +index 7f0b8ff18..bf25d9509 100644 +--- a/src/tests/intg/test_ldap.py ++++ b/src/tests/intg/test_ldap.py +@@ -951,3 +951,32 @@ def test_remove_user_from_nested_group(ldap_conn, + dict(mem=ent.contains_only("user2"))) + ent.assert_group_by_name("group3", + dict(mem=ent.contains_only())) ++ ++ ++def zero_nesting_sssd_conf(ldap_conn, schema): ++ """Format an SSSD configuration with group nesting disabled""" ++ return \ ++ format_basic_conf(ldap_conn, schema) + \ ++ unindent(""" ++ [domain/LDAP] ++ ldap_group_nesting_level = 0 ++ """).format(INTERACTIVE_TIMEOUT) ++ ++ ++@pytest.fixture ++def rfc2307bis_no_nesting(request, ldap_conn): ++ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ++ ent_list.add_user("user1", 1001, 2001) ++ ent_list.add_group_bis("group1", 20001, member_uids=["user1"]) ++ create_ldap_fixture(request, ldap_conn, ent_list) ++ create_conf_fixture(request, ++ zero_nesting_sssd_conf( ++ ldap_conn, ++ SCHEMA_RFC2307_BIS)) ++ create_sssd_fixture(request) ++ return None ++ ++ ++def test_zero_nesting_level(ldap_conn, rfc2307bis_no_nesting): ++ ent.assert_group_by_name("group1", ++ dict(mem=ent.contains_only("user1"))) +-- +2.11.0 + diff --git a/sssd/patches/0030-BUILD-Fix-a-typo-in-inotify.m4.patch b/sssd/patches/0030-BUILD-Fix-a-typo-in-inotify.m4.patch new file mode 100644 index 0000000..b4a8f59 --- /dev/null +++ b/sssd/patches/0030-BUILD-Fix-a-typo-in-inotify.m4.patch @@ -0,0 +1,37 @@ +From bf0971190884b664ef38d8fc42199fca8e496e54 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Fri, 18 Nov 2016 12:19:02 +0100 +Subject: [PATCH 30/39] BUILD: Fix a typo in inotify.m4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This typo prevented HAVE_INOTIFY from ever being set and as an effect, +prevented /etc/resolv.conf inotify detection from working + +Reviewed-by: Lukáš Slebodník lslebodn@redhat.com +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +(cherry picked from commit 2927dc45b9bc810f4f55bce165bb96405129e693) +(cherry picked from commit 495289cfa922b00278aa91d433489403e792304e) +--- + src/external/inotify.m4 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/external/inotify.m4 b/src/external/inotify.m4 +index 9572f6d2f..25259a817 100644 +--- a/src/external/inotify.m4 ++++ b/src/external/inotify.m4 +@@ -6,8 +6,8 @@ AC_DEFUN([AM_CHECK_INOTIFY], + AC_MSG_CHECKING([whether sys/inotify.h actually works]) + AC_LINK_IFELSE( + [AC_LANG_SOURCE([ +-#ifdef HAVE_SYS_INOTITY_H +-#include <sys/inotify.h>, ++#ifdef HAVE_SYS_INOTIFY_H ++#include <sys/inotify.h> + #endif + int main () { + return (-1 == inotify_init()); +-- +2.11.0 + diff --git a/sssd/patches/0031-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch b/sssd/patches/0031-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch new file mode 100644 index 0000000..6e9cccd --- /dev/null +++ b/sssd/patches/0031-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch @@ -0,0 +1,48 @@ +From 74fb5008403cc7324138740b327bb282aeb19a08 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20=C4=8Cech?= pcech@redhat.com +Date: Wed, 16 Nov 2016 10:09:18 +0100 +Subject: [PATCH 31/39] SYSDB: Fixing of sudorule without a sudoUser + +This patch solved a regression caused by the recent patches +to lowercase sudoUser -- in case sudoUser is missing completely, +we abort the processing of this rule and all others. + +With this patch, we return ERR_MALFORMED_ENTRY and gracefully +skip the malformed rule instead. + +Resolves: +https://fedorahosted.org/sssd/ticket/3241 + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 7e23edbaa7a6bbd0b461d5792535896b6a77928b) +(cherry picked from commit 54f176066dafafdc12f6e0dd112ff6339308aa7c) +--- + src/db/sysdb_sudo.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c +index 4bd93ffc6..f5160f190 100644 +--- a/src/db/sysdb_sudo.c ++++ b/src/db/sysdb_sudo.c +@@ -874,6 +874,7 @@ static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain, + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n", + SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret)); ++ ret = ERR_MALFORMED_ENTRY; + goto done; + } + +@@ -977,6 +978,10 @@ sysdb_sudo_store(struct sss_domain_info *domain, + /* Multiple CNs are error on server side, we can just ignore this + * rule and save the others. Loud debug message is in logs. */ + continue; ++ } else if (ret == ERR_MALFORMED_ENTRY) { ++ /* Attribute SYSDB_SUDO_CACHE_AT_USER is missing but we can ++ * continue with next sudoRule. */ ++ continue; + } else if (ret != EOK) { + goto done; + } +-- +2.11.0 + diff --git a/sssd/patches/0032-UTIL-Fix-implicit-declaration-of-function-htobe32.patch b/sssd/patches/0032-UTIL-Fix-implicit-declaration-of-function-htobe32.patch new file mode 100644 index 0000000..94172b2 --- /dev/null +++ b/sssd/patches/0032-UTIL-Fix-implicit-declaration-of-function-htobe32.patch @@ -0,0 +1,58 @@ +From 2d6fe5942218ee8f24eb6ccd8ffec5fab65c170b Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lukas.slebodnik@intrak.sk +Date: Fri, 18 Nov 2016 17:29:44 +0100 +Subject: [PATCH 32/39] UTIL: Fix implicit declaration of function 'htobe32' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Include internal wrapper header file for endian related functions. +The "util/sss_endian.h" include available header file on different +platform or it provides compatible macros in the worst case. + +Breakage noticed when building SSSD on FreeBSD + + CC src/util/cert/nss/libsss_cert_la-cert.lo +src/util/cert/nss/cert.c: In function 'cert_to_ssh_key': +src/util/cert/nss/cert.c:358: error: implicit declaration of function 'htobe32' +gmake[2]: *** [Makefile:12421: src/util/cert/nss/libsss_cert_la-cert.lo] Error 1 +gmake[2]: Leaving directory '/root/sssd_from_git' +gmake[1]: *** [Makefile:20050: all-recursive] Error 1 +gmake[1]: Leaving directory '/root/sssd_from_git' +gmake: *** [Makefile:7116: all] Error 2 + +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +(cherry picked from commit 58aa8d645fa95641431a2828e985f80c7fc36465) +(cherry picked from commit a70351fddb9c26763b2bf658f56ff043a7b3db6f) +--- + src/util/cert/libcrypto/cert.c | 1 + + src/util/cert/nss/cert.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c +index aba598d7c..c54db86bb 100644 +--- a/src/util/cert/libcrypto/cert.c ++++ b/src/util/cert/libcrypto/cert.c +@@ -22,6 +22,7 @@ + #include <openssl/pem.h> + + #include "util/util.h" ++#include "util/sss_endian.h" + + errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, + size_t der_size, char **pem, size_t *pem_size) +diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c +index b5e0ff961..9d31cfe9b 100644 +--- a/src/util/cert/nss/cert.c ++++ b/src/util/cert/nss/cert.c +@@ -31,6 +31,7 @@ + #include "util/crypto/sss_crypto.h" + #include "util/crypto/nss/nss_util.h" + #include "util/cert.h" ++#include "util/sss_endian.h" + + #define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----" + #define NS_CERT_TRAILER "-----END CERTIFICATE-----" +-- +2.11.0 + diff --git a/sssd/patches/0033-sssctl-Fix-missing-declaration.patch b/sssd/patches/0033-sssctl-Fix-missing-declaration.patch new file mode 100644 index 0000000..5a0eacd --- /dev/null +++ b/sssd/patches/0033-sssctl-Fix-missing-declaration.patch @@ -0,0 +1,46 @@ +From 99b48ffa1a525c0736f67b89c81bfc867977a99c Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lukas.slebodnik@intrak.sk +Date: Fri, 18 Nov 2016 17:58:28 +0100 +Subject: [PATCH 33/39] sssctl: Fix missing declaration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The WEXITSTATUS is defined in stdlib.h on linux. +There is a nice comment in stdlib.h: + /* Define the macros <sys/wait.h> also would define this way. */ + +It's better to not rely on this and use more platfom friendly +way with including "sys/wait.h". For example the libc on FreeBSD +does not provide WEXITSTATUS in stdlib.h. + +I found this macro mentioned only in the manual page for wait(2) +and there is mentioned just the "sys/wait.h" and not "stdlib.h" + +src/tools/sssctl/sssctl.c: In function 'sssctl_run_command': +src/tools/sssctl/sssctl.c:110: error: implicit declaration of function +'WEXITSTATUS' +gmake[2]: *** [Makefile:22383: src/tools/sssctl/sssctl-sssctl.o] Error 1 + +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +(cherry picked from commit 73c9330fa3de6912e45c1ab686d5290f143b8352) +(cherry picked from commit 161ddc1f24082c735801775802a483e96909152c) +--- + src/tools/sssctl/sssctl.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c +index ece1e6df1..e1cf46382 100644 +--- a/src/tools/sssctl/sssctl.c ++++ b/src/tools/sssctl/sssctl.c +@@ -20,6 +20,7 @@ + + #include <stdlib.h> + #include <stdio.h> ++#include <sys/wait.h> + + #include "util/util.h" + #include "tools/sssctl/sssctl.h" +-- +2.11.0 + diff --git a/sssd/patches/0034-UTIL-Fix-compilation-of-sss_utf8-with-libunistring.patch b/sssd/patches/0034-UTIL-Fix-compilation-of-sss_utf8-with-libunistring.patch new file mode 100644 index 0000000..d727c28 --- /dev/null +++ b/sssd/patches/0034-UTIL-Fix-compilation-of-sss_utf8-with-libunistring.patch @@ -0,0 +1,49 @@ +From 6a3c115022b54bce155c04a1c090561cf626006a Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lukas.slebodnik@intrak.sk +Date: Fri, 18 Nov 2016 17:49:35 +0100 +Subject: [PATCH 34/39] UTIL: Fix compilation of sss_utf8 with libunistring +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The internal header file "util/util.h" was removed from sss_utf8.h +as part of commit de5fa34860886ad68fba5e739987e16c342e8f14. +It was neccessary to ensure libipa_hbac can be build with C90 +compatible compiler. + +This header file includes many system header file and after +this change caused missing declaration of the function free() + +src/util/sss_utf8.c: In function ‘sss_utf8_free’: +src/util/sss_utf8.c:40:12: error: implicit declaration of function ‘free’ + [-Werror=implicit-function-declaration] + return free(ptr); + ^~~~ +src/util/sss_utf8.c:40:12: warning: incompatible implicit declaration + of built-in function ‘free’ +src/util/sss_utf8.c:40:12: note: include ‘<stdlib.h>’ or provide + a declaration of ‘free’ +cc1: some warnings being treated as errors + +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +(cherry picked from commit c101cb130df0705a9227dadce22554307eee54db) +(cherry picked from commit 76e2df701559d8723ea632722c94c8dfb820fc93) +--- + src/util/sss_utf8.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/util/sss_utf8.c b/src/util/sss_utf8.c +index 722f28d08..e62e9c6c9 100644 +--- a/src/util/sss_utf8.c ++++ b/src/util/sss_utf8.c +@@ -26,6 +26,7 @@ + #include <errno.h> + + #ifdef HAVE_LIBUNISTRING ++#include <stdlib.h> + #include <unistr.h> + #include <unicase.h> + #elif defined(HAVE_GLIB2) +-- +2.11.0 + diff --git a/sssd/patches/0035-SIFP-Fix-warning-format-security.patch b/sssd/patches/0035-SIFP-Fix-warning-format-security.patch new file mode 100644 index 0000000..731de71 --- /dev/null +++ b/sssd/patches/0035-SIFP-Fix-warning-format-security.patch @@ -0,0 +1,40 @@ +From 86fa0fa9543b4f21a152bcaedbcb3d5608567aa2 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Thu, 1 Dec 2016 13:13:21 +0100 +Subject: [PATCH 35/39] SIFP: Fix warning format-security +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +dbus-1.11.8 added attributes for format string check to +few functions in public header files. And therefore there is a warning. + +src/lib/sifp/sss_sifp_utils.c: In function ‘sss_sifp_set_io_error’: +src/lib/sifp/sss_sifp_utils.c:44:5: error: format not a string literal +and no format arguments [-Werror=format-security] + dbus_set_error(ctx->io_error, error->name, error->message); + ^~~~~~~~~~~~~~ + +Reviewed-by: Pavel Březina pbrezina@redhat.com +(cherry picked from commit 8618716d6ed4eadca2743eb2dfbbb8d11c4fb22f) +(cherry picked from commit 043862847cee673084a56f387d195deb82386de7) +--- + src/lib/sifp/sss_sifp_utils.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/sifp/sss_sifp_utils.c b/src/lib/sifp/sss_sifp_utils.c +index ccd051838..dcac71f50 100644 +--- a/src/lib/sifp/sss_sifp_utils.c ++++ b/src/lib/sifp/sss_sifp_utils.c +@@ -41,7 +41,7 @@ void sss_sifp_set_io_error(sss_sifp_ctx *ctx, DBusError *error) + { + dbus_error_free(ctx->io_error); + dbus_error_init(ctx->io_error); +- dbus_set_error(ctx->io_error, error->name, error->message); ++ dbus_set_error(ctx->io_error, error->name, "%s", error->message); + } + + char * sss_sifp_strdup(sss_sifp_ctx *ctx, const char *str) +-- +2.11.0 + diff --git a/sssd/patches/0036-SSH-Use-default_domain_suffix-for-users-authorized-k.patch b/sssd/patches/0036-SSH-Use-default_domain_suffix-for-users-authorized-k.patch new file mode 100644 index 0000000..168fd3f --- /dev/null +++ b/sssd/patches/0036-SSH-Use-default_domain_suffix-for-users-authorized-k.patch @@ -0,0 +1,80 @@ +From e1a01adb021f7d2b3674c4d8151797e265608c20 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Thu, 24 Nov 2016 18:07:56 +0100 +Subject: [PATCH 36/39] SSH: Use default_domain_suffix for users' authorized + keys + +In commit eeecc48d22a28bb69da56f6ffd8824163fc9bf00 we disabled +default_domain_suffix for the SSH responder, but in a wrong way -- we +disabled the functionality completely, also for users, not only for +computers. This might have been correct at the time, since SSH keys in ID +overrides are a relatively new feature, but it's definitely not correct +in general. + +Instead, this patch restores the use of default_domain_suffix, but only +for looking up public keys of users, not of computers. + +Resolves: +https://fedorahosted.org/sssd/ticket/3259 + +Reviewed-by: Petr Cech pcech@redhat.com +(cherry picked from commit ed71fba97dfcf5b3f0f1834c06660c481b9ab3ce) +(cherry picked from commit 2949fe58ac344c44d756ca309d4b2b7f3590cee3) +--- + src/responder/ssh/sshsrv_cmd.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c +index ab721d66e..2e64893df 100644 +--- a/src/responder/ssh/sshsrv_cmd.c ++++ b/src/responder/ssh/sshsrv_cmd.c +@@ -36,7 +36,8 @@ + #include "responder/ssh/sshsrv_private.h" + + static errno_t +-ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx); ++ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx, ++ char *default_domain); + + static errno_t + ssh_user_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx); +@@ -57,7 +58,7 @@ sss_ssh_cmd_get_user_pubkeys(struct cli_ctx *cctx) + cmd_ctx->cctx = cctx; + cmd_ctx->is_user = true; + +- ret = ssh_cmd_parse_request(cmd_ctx); ++ ret = ssh_cmd_parse_request(cmd_ctx, cctx->rctx->default_domain); + if (ret != EOK) { + goto done; + } +@@ -107,7 +108,7 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) + cmd_ctx->cctx = cctx; + cmd_ctx->is_user = false; + +- ret = ssh_cmd_parse_request(cmd_ctx); ++ ret = ssh_cmd_parse_request(cmd_ctx, NULL); + if (ret != EOK) { + goto done; + } +@@ -681,7 +682,8 @@ done: + } + + static errno_t +-ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) ++ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx, ++ char *default_domain) + { + struct cli_protocol *pctx; + struct ssh_ctx *ssh_ctx; +@@ -754,6 +756,8 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) + return EINVAL; + } + c += domain_len; ++ } else { ++ domain = default_domain; + } + + DEBUG(SSSDBG_TRACE_FUNC, +-- +2.11.0 + diff --git a/sssd/patches/0037-Prevent-use-after-free-in-fd_input_available.patch b/sssd/patches/0037-Prevent-use-after-free-in-fd_input_available.patch new file mode 100644 index 0000000..5d821e5 --- /dev/null +++ b/sssd/patches/0037-Prevent-use-after-free-in-fd_input_available.patch @@ -0,0 +1,72 @@ +From d2f8e3876810cf99228827432ea4f4a59877448d Mon Sep 17 00:00:00 2001 +From: Carl Henrik Lunde chlunde@ifi.uio.no +Date: Thu, 1 Dec 2016 00:09:00 +0100 +Subject: [PATCH 37/39] Prevent use after free in fd_input_available + +When both TEVENT_FD_WRITE and TEVENT_FD_READ are set, and an error/EOF +occurs when reading from the socket, we will get a use after free +in the second call ares_process_fd. The first call will free the watch +structure via a callback. + +Prevent this by calling ares_process_fd only once. + +Invalid read of size 4 + at fd_input_available (async_resolv.c:147) + by epoll_event_loop (tevent_epoll.c:728) + by epoll_event_loop_once (tevent_epoll.c:926) + by std_event_loop_once (tevent_standard.c:114) + by _tevent_loop_once (tevent.c:533) + by tevent_common_loop_wait (tevent.c:637) + by std_event_loop_wait (tevent_standard.c:140) + by server_loop (server.c:702) + by main (data_provider_be.c:587) + Address ... is 112 bytes inside a block of size 136 free'd + at free (vg_replace_malloc.c:530) + by _talloc_free_internal (talloc.c:1116) + by _talloc_free (talloc.c:1647) + by ares__close_sockets (ares__close_sockets.c:50) + by handle_error (ares_process.c:679) + by read_tcp_data (ares_process.c:391) + by processfds (ares_process.c:138) + by fd_input_available (async_resolv.c:144) + by epoll_event_loop (tevent_epoll.c:728) + by epoll_event_loop_once (tevent_epoll.c:926) + by std_event_loop_once (tevent_standard.c:114) + by _tevent_loop_once (tevent.c:533) + by tevent_common_loop_wait (tevent.c:637) + by std_event_loop_wait (tevent_standard.c:140) + by server_loop (server.c:702) + +Resolves: +https://fedorahosted.org/sssd/ticket/3250 + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 9676b464dd428557ff5a648e1351a3972440396f) +(cherry picked from commit fefdd70237cbe82af7d8845131e45401e73b3b07) +--- + src/resolv/async_resolv.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c +index e85955677..47b4db7ec 100644 +--- a/src/resolv/async_resolv.c ++++ b/src/resolv/async_resolv.c +@@ -140,12 +140,9 @@ fd_input_available(struct tevent_context *ev, struct tevent_fd *fde, + return; + } + +- if (flags & TEVENT_FD_READ) { +- ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD); +- } +- if (flags & TEVENT_FD_WRITE) { +- ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd); +- } ++ ares_process_fd(watch->ctx->channel, ++ flags & TEVENT_FD_READ ? watch->fd : ARES_SOCKET_BAD, ++ flags & TEVENT_FD_WRITE ? watch->fd : ARES_SOCKET_BAD); + } + + static void +-- +2.11.0 + diff --git a/sssd/patches/0038-STAP-Only-print-transaction-statistics-if-the-script.patch b/sssd/patches/0038-STAP-Only-print-transaction-statistics-if-the-script.patch new file mode 100644 index 0000000..9de9705 --- /dev/null +++ b/sssd/patches/0038-STAP-Only-print-transaction-statistics-if-the-script.patch @@ -0,0 +1,39 @@ +From 39fe2093254db5d4cd223e7d9c228689ba6382ca Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek jhrozek@redhat.com +Date: Mon, 28 Nov 2016 08:44:04 +0100 +Subject: [PATCH 38/39] STAP: Only print transaction statistics if the script + caught some transactions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the script measured an 'id' run from the cache, there would be no +transactions and dereferencing the aggrefate would throw an error. + +Reviewed-by: Fabiano Fidêncio fidencio@redhat.com +(cherry picked from commit 150a0cc8fe1936002af136e5552ef6cdd210956f) +(cherry picked from commit e6c74de2cbc9b0b713ed6dadbfef80c7c1b5cd51) +--- + contrib/systemtap/id_perf.stp | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/contrib/systemtap/id_perf.stp b/contrib/systemtap/id_perf.stp +index 0ad619506..a7789750f 100644 +--- a/contrib/systemtap/id_perf.stp ++++ b/contrib/systemtap/id_perf.stp +@@ -64,8 +64,10 @@ function print_report() + } + } + +- printf("The most expensive transaction breakdown, per transaction:\n") +- print(@hist_linear(bts[max_trans_time_bt], 0, 500, 50)) ++ if (max_trans_time > 0) { ++ printf("The most expensive transaction breakdown, per transaction:\n") ++ print(@hist_linear(bts[max_trans_time_bt], 0, 500, 50)) ++ } + } + + probe process("/usr/bin/id").begin +-- +2.11.0 + diff --git a/sssd/patches/0039-sudo-do-not-store-usn-if-no-rules-are-found.patch b/sssd/patches/0039-sudo-do-not-store-usn-if-no-rules-are-found.patch new file mode 100644 index 0000000..9598b1d --- /dev/null +++ b/sssd/patches/0039-sudo-do-not-store-usn-if-no-rules-are-found.patch @@ -0,0 +1,50 @@ +From f2fe644510afd2d3bc989a4fea2ce2b2a1a69e9c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= pbrezina@redhat.com +Date: Mon, 5 Dec 2016 14:37:41 +0100 +Subject: [PATCH 39/39] sudo: do not store usn if no rules are found + +When ldap doesn't contain any sudorule during the initial full refresh, +usn is set to 1 instead of remaining unset and we are trying to +search modifyTimestamp>=1 during smart refresh which doesn't return any result +on openldap servers. + +Resolves: +https://fedorahosted.org/sssd/ticket/3257 + +Reviewed-by: Jakub Hrozek jhrozek@redhat.com +(cherry picked from commit 46703740e83a66909974a5ee8d47df6a6e5076e7) +(cherry picked from commit 76e97affaa05ce45709efd59d120595c5992aa21) +--- + src/providers/ldap/sdap_sudo_shared.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c +index 807226020..66b788702 100644 +--- a/src/providers/ldap/sdap_sudo_shared.c ++++ b/src/providers/ldap/sdap_sudo_shared.c +@@ -129,7 +129,7 @@ sdap_sudo_new_usn(TALLOC_CTX *mem_ctx, + char *newusn; + + /* We increment USN number so that we can later use simplify filter +- * (just usn >= last+1 instaed of usn >= last && usn != last). ++ * (just usn >= last+1 instead of usn >= last && usn != last). + */ + usn++; + +@@ -174,6 +174,13 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, + return; + } + ++ if (usn_number == 0) { ++ /* Zero means that there were no rules on the server, so we have ++ * nothing to store. */ ++ DEBUG(SSSDBG_TRACE_FUNC, "SUDO USN value is empty.\n"); ++ return; ++ } ++ + newusn = sdap_sudo_new_usn(srv_opts, usn_number, endptr); + if (newusn == NULL) { + return; +-- +2.11.0 + diff --git a/sssd/patches/0501-Partially-revert-CONFIG-Use-default-config-when-none.patch b/sssd/patches/0501-Partially-revert-CONFIG-Use-default-config-when-none.patch new file mode 100644 index 0000000..40f0f43 --- /dev/null +++ b/sssd/patches/0501-Partially-revert-CONFIG-Use-default-config-when-none.patch @@ -0,0 +1,117 @@ +From 829aa39dffbe35f58b34159b962a2dd8de85fd30 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 12 Dec 2016 18:33:48 +0100 +Subject: [PATCH] Partially revert "CONFIG: Use default config when none + provided" + +This reverts part of commit 59744cff6edb106ae799b2321cb8731edadf409a. + +Removed is copying of default configuration into /etc/sssd/sssd.conf +Sample configurations is still part of installation. +--- + Makefile.am | 3 --- + src/confdb/confdb.h | 1 - + src/confdb/confdb_setup.c | 40 ++++------------------------------------ + 3 files changed, 4 insertions(+), 40 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index a15e68f682f6d8af301e11df8dcaef6d7f27e8c0..45d44146e737fc8460a2ed9ffc0171a6bb494b2b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -462,7 +462,6 @@ AM_CPPFLAGS = \ + -DSSSDDATADIR="$(sssddatadir)" \ + -DSSSD_LIBEXEC_PATH="$(sssdlibexecdir)" \ + -DSSSD_CONF_DIR="$(sssdconfdir)" \ +- -DSSSD_DEFAULT_CONF_DIR="$(sssddefaultconfdir)" \ + -DSSS_NSS_MCACHE_DIR="$(mcpath)" \ + -DSSS_NSS_SOCKET_NAME="$(pipepath)/nss" \ + -DSSS_PAM_SOCKET_NAME="$(pipepath)/pam" \ +@@ -1232,8 +1231,6 @@ sssd_SOURCES = \ + src/confdb/confdb_setup.c \ + src/monitor/monitor_iface_generated.c \ + src/util/nscd.c \ +- src/tools/files.c \ +- src/tools/selinux.c \ + $(NULL) + sssd_LDADD = \ + $(SSSD_LIBS) \ +diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h +index 12beaabf8c949bd111abbe16cb98a205490fb08f..4813072bdafb5d6c9ec56a9ccaa5db6a1120112d 100644 +--- a/src/confdb/confdb.h ++++ b/src/confdb/confdb.h +@@ -40,7 +40,6 @@ + + #define CONFDB_DEFAULT_CFG_FILE_VER 2 + #define CONFDB_FILE "config.ldb" +-#define SSSD_DEFAULT_CONFIG_FILE SSSD_DEFAULT_CONF_DIR"/sssd.conf" + #define SSSD_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf" + #define CONFDB_DEFAULT_CONFIG_DIR SSSD_CONF_DIR"/conf.d" + #define SSSD_MIN_ID 1 +diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c +index d6feab9000d54d2c3761de6d8e990053ade7e85f..a71d9dd1202824b3c9a7e69f1d8fa905ac1b8c02 100644 +--- a/src/confdb/confdb_setup.c ++++ b/src/confdb/confdb_setup.c +@@ -21,14 +21,12 @@ + + #include "config.h" + #include <sys/stat.h> +-#include <unistd.h> + #include "util/util.h" + #include "db/sysdb.h" + #include "confdb.h" + #include "confdb_private.h" + #include "confdb_setup.h" + #include "util/sss_ini.h" +-#include "tools/tools_util.h" + + + static int confdb_test(struct confdb_ctx *cdb) +@@ -161,41 +159,11 @@ static int confdb_init_db(const char *config_file, const char *config_dir, + DEBUG(SSSDBG_TRACE_FUNC, + "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret), + ret); +- if (ret != ENOENT) { +- /* Anything other than ENOENT is unrecoverable */ +- goto done; +- } else { +- /* Copy the default configuration file to the standard location +- * and then retry +- */ +- ret = copy_file_secure(SSSD_DEFAULT_CONFIG_FILE, +- SSSD_CONFIG_FILE, +- 0600, +- getuid(), +- getgid(), +- false); +- if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, +- "Could not copy default configuration: %s", +- sss_strerror(ret)); +- /* sss specific error denoting missing configuration file */ +- ret = ERR_MISSING_CONF; +- goto done; +- } +- +- /* Try again */ +- ret = sss_ini_config_file_open(init_data, config_file); +- if (ret != EOK) { +- DEBUG(SSSDBG_TRACE_FUNC, +- "sss_ini_config_file_open(default) failed: %s [%d]\n", +- strerror(ret), ret); +- if (ret == ENOENT) { +- /* sss specific error denoting missing configuration file */ +- ret = ERR_MISSING_CONF; +- } +- goto done; +- } ++ if (ret == ENOENT) { ++ /* sss specific error denoting missing configuration file */ ++ ret = ERR_MISSING_CONF; + } ++ goto done; + } + + ret = sss_ini_config_access_check(init_data); +-- +2.11.0 + diff --git a/sssd/patches/0502-SYSTEMD-Use-capabilities.patch b/sssd/patches/0502-SYSTEMD-Use-capabilities.patch new file mode 100644 index 0000000..ef612ac --- /dev/null +++ b/sssd/patches/0502-SYSTEMD-Use-capabilities.patch @@ -0,0 +1,25 @@ +From cf3b1babdbd2221b46816d4c6d5cd90d9de069ec Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik lslebodn@redhat.com +Date: Mon, 12 Dec 2016 21:56:16 +0100 +Subject: [PATCH] SYSTEMD: Use capabilities + +copied from selinux policy +--- + src/sysv/systemd/sssd.service.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in +index a4f9125b58e72429cc3ac1e679271367ada27f3c..8c49c0415597b21ddcd85e0675580edc4d171a5f 100644 +--- a/src/sysv/systemd/sssd.service.in ++++ b/src/sysv/systemd/sssd.service.in +@@ -11,6 +11,7 @@ ExecStart=@sbindir@/sssd -D -f + # consult systemd.service(5) for more details + Type=forking + PIDFile=@localstatedir@/run/sssd.pid ++CapabilityBoundingSet=CAP_IPC_LOCK CAP_CHOWN CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE CAP_KILL CAP_NET_ADMIN CAP_SYS_NICE CAP_FOWNER CAP_SETGID CAP_SETUID CAP_SYS_ADMIN CAP_SYS_RESOURCE CAP_BLOCK_SUSPEND + + [Install] + WantedBy=multi-user.target +-- +2.11.0 + diff --git a/sssd/patches/0503-sss_client-Defer-thread-cancellation-until-completio.patch b/sssd/patches/0503-sss_client-Defer-thread-cancellation-until-completio.patch new file mode 100644 index 0000000..396ebbe --- /dev/null +++ b/sssd/patches/0503-sss_client-Defer-thread-cancellation-until-completio.patch @@ -0,0 +1,179 @@ +From d2f93542650c2f9613043acfa8e2f368972a70cd Mon Sep 17 00:00:00 2001 +From: Howard Guo hguo@suse.com +Date: Tue, 11 Oct 2016 10:35:13 +0200 +Subject: [PATCH] sss_client: Defer thread cancellation until completion of + nss/pam operations + +The client code is not cancellation-safe, an application which +has cancelled an NSS operation will experience subtle bugs, +hence thread cancellation is deferred until completion of client +operations. + +Resolves: +https://fedorahosted.org/sssd/ticket/3156 + +Reviewed-by: Sumit Bose sbose@redhat.com +Reviewed-by: Florian Weimer fweimer@redhat.com +--- + Makefile.am | 4 --- + configure.ac | 8 ----- + src/sss_client/common.c | 80 +++++-------------------------------------------- + 3 files changed, 7 insertions(+), 85 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index e037930ff..9f1da4d1e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -792,10 +792,6 @@ endif + + CLIENT_LIBS = $(LTLIBINTL) + +-if HAVE_PTHREAD +-CLIENT_LIBS += -lpthread +-endif +- + if WITH_JOURNALD + SYSLOG_LIBS = $(JOURNALD_LIBS) + endif +diff --git a/configure.ac b/configure.ac +index d3ef1e162..230524bf3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -62,14 +62,6 @@ AC_COMPILE_IFELSE( + + AM_CONDITIONAL([HAVE_PTHREAD], [test x"$HAVE_PTHREAD" != "x"]) + +-SAVE_LIBS=$LIBS +-LIBS="$LIBS -lpthread" +-AC_CHECK_FUNCS([ pthread_mutexattr_setrobust \ +- pthread_mutex_consistent \ +- pthread_mutexattr_setrobust_np \ +- pthread_mutex_consistent_np ]) +-LIBS=$SAVE_LIBS +- + # Check library for the timer_create function + SAVE_LIBS=$LIBS + LIBS= +diff --git a/src/sss_client/common.c b/src/sss_client/common.c +index 20106b1b6..b7a5ed760 100644 +--- a/src/sss_client/common.c ++++ b/src/sss_client/common.c +@@ -1070,86 +1070,28 @@ typedef void (*sss_mutex_init)(void); + struct sss_mutex { + pthread_mutex_t mtx; + +- pthread_once_t once; +- sss_mutex_init init; ++ int old_cancel_state; + }; + +-static void sss_nss_mt_init(void); +-static void sss_pam_mt_init(void); +-static void sss_nss_mc_mt_init(void); ++static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; + +-static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, +- .once = PTHREAD_ONCE_INIT, +- .init = sss_nss_mt_init }; ++static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; + +-static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, +- .once = PTHREAD_ONCE_INIT, +- .init = sss_pam_mt_init }; +- +-static struct sss_mutex sss_nss_mc_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, +- .once = PTHREAD_ONCE_INIT, +- .init = sss_nss_mc_mt_init }; +- +-/* Wrappers for robust mutex support */ +-static int sss_mutexattr_setrobust (pthread_mutexattr_t *attr) +-{ +-#ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST +- return pthread_mutexattr_setrobust(attr, PTHREAD_MUTEX_ROBUST); +-#elif defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) +- return pthread_mutexattr_setrobust_np(attr, PTHREAD_MUTEX_ROBUST_NP); +-#else +-#warning Robust mutexes are not supported on this platform. +- return 0; +-#endif +-} +- +-static int sss_mutex_consistent(pthread_mutex_t *mtx) +-{ +-#ifdef HAVE_PTHREAD_MUTEX_CONSISTENT +- return pthread_mutex_consistent(mtx); +-#elif defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) +- return pthread_mutex_consistent_np(mtx); +-#else +-#warning Robust mutexes are not supported on this platform. +- return 0; +-#endif +-} +- +-/* Generic mutex init, lock, unlock functions */ +-static void sss_mt_init(struct sss_mutex *m) +-{ +- pthread_mutexattr_t attr; +- +- if (pthread_mutexattr_init(&attr) != 0) { +- return; +- } +- if (sss_mutexattr_setrobust(&attr) != 0) { +- return; +- } +- +- pthread_mutex_init(&m->mtx, &attr); +- pthread_mutexattr_destroy(&attr); +-} ++static struct sss_mutex sss_nss_mc_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; + + static void sss_mt_lock(struct sss_mutex *m) + { +- pthread_once(&m->once, m->init); +- if (pthread_mutex_lock(&m->mtx) == EOWNERDEAD) { +- sss_cli_close_socket(); +- sss_mutex_consistent(&m->mtx); +- } ++ pthread_mutex_lock(&m->mtx); ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m->old_cancel_state); + } + + static void sss_mt_unlock(struct sss_mutex *m) + { ++ pthread_setcancelstate(m->old_cancel_state, NULL); + pthread_mutex_unlock(&m->mtx); + } + + /* NSS mutex wrappers */ +-static void sss_nss_mt_init(void) +-{ +- sss_mt_init(&sss_nss_mtx); +-} + void sss_nss_lock(void) + { + sss_mt_lock(&sss_nss_mtx); +@@ -1160,10 +1102,6 @@ void sss_nss_unlock(void) + } + + /* NSS mutex wrappers */ +-static void sss_pam_mt_init(void) +-{ +- sss_mt_init(&sss_pam_mtx); +-} + void sss_pam_lock(void) + { + sss_mt_lock(&sss_pam_mtx); +@@ -1174,10 +1112,6 @@ void sss_pam_unlock(void) + } + + /* NSS mutex wrappers */ +-static void sss_nss_mc_mt_init(void) +-{ +- sss_mt_init(&sss_nss_mc_mtx); +-} + void sss_nss_mc_lock(void) + { + sss_mt_lock(&sss_nss_mc_mtx); +-- +2.11.0 + diff --git a/sssd/sssd.nm b/sssd/sssd.nm index de78e07..01aa8e9 100644 --- a/sssd/sssd.nm +++ b/sssd/sssd.nm @@ -4,11 +4,11 @@ ###############################################################################
name = sssd -version = 1.14.1 +version = 1.14.2 release = 1
groups = System/Tools -url = http://fedorahosted.org/sssd/ +url = https://github.com/SSSD/sssd license = GPLv3+ summary = System Security Services Daemon.
@@ -19,7 +19,7 @@ description account sources. end
-source_dl = https://fedorahosted.org/released/sssd/ +source_dl = https://releases.pagure.org/SSSD/sssd/
build # The system security services daemon and many tools requires @@ -34,18 +34,17 @@ build cifs-utils-devel >= 6.6 cyrus-sasl-devel dbus-devel - ding-libs-devel >= 0.6.0 + ding-libs-devel >= 0.6.1 docbook-xsl gettext-devel glib2-devel krb5-devel >= 1.10.3 libcollection-devel - libdhash-devel - libini_config-devel - libldb-devel + libdhash-devel >= 0.6.1 + libini_config-devel >= 0.6.1 + libldb-devel >= 1.1.20 libnl3-devel libnfsidmap-devel - libsemanage-devel libtalloc-devel libtdb-devel libtevent-devel @@ -79,7 +78,9 @@ build --disable-static \ --disable-rpath \ --disable-config-lib \ - --without-secrets + --without-secrets \ + --without-semanage \ + --without-selinux
test make check
hooks/post-receive -- IPFire 3.x development tree