The Identity, Policy and Audit system
CentOS Sources
2018-04-10 3f51ca75c60b6d8c09971f97742983b8d6847c58
import ipa-4.5.4-10.el7
37 files added
237 files deleted
7 files modified
29176 ■■■■ changed files
.gitignore 2 ●●● patch | view | raw | blame | history
.ipa.metadata 2 ●●● patch | view | raw | blame | history
SOURCES/0001-Add-options-to-allow-ticket-caching.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0001-ds-ignore-time-skew-during-initial-replication-step.patch 86 ●●●●● patch | view | raw | blame | history
SOURCES/0002-Use-connection-keep-alive.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/0003-Add-debug-logging-for-keep-alive.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch 75 ●●●●● patch | view | raw | blame | history
SOURCES/0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/0007-ipa-extdom-extop-refactor-nsswitch-operations.patch 1728 ●●●●● patch | view | raw | blame | history
SOURCES/0007-man-ipa-cacert-manage-install-needs-clarification.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0008-Add-the-sub-operation-for-fqdn-index-config.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/0008-certs-do-not-implicitly-create-DS-pin.txt.patch 48 ●●●●● patch | view | raw | blame | history
SOURCES/0009-Add-indexing-to-improve-host-find-performance.patch 121 ●●●●● patch | view | raw | blame | history
SOURCES/0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch 74 ●●●●● patch | view | raw | blame | history
SOURCES/0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch 43 ●●●●● patch | view | raw | blame | history
SOURCES/0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch 87 ●●●●● patch | view | raw | blame | history
SOURCES/0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch 83 ●●●●● patch | view | raw | blame | history
SOURCES/0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/0012-Fix-cert-find-for-CA-less-installations.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch 43 ●●●●● patch | view | raw | blame | history
SOURCES/0013-Backup-ipa-specific-httpd-unit-file.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0013-Fix-ipa-restore-python2.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0014-Backup-ipa-custodia-conf-and-keys.patch 154 ●●●●● patch | view | raw | blame | history
SOURCES/0014-WebUI-check-principals-in-lowercase.patch 36 ●●●●● patch | view | raw | blame | history
SOURCES/0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch 105 ●●●●● patch | view | raw | blame | history
SOURCES/0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch 66 ●●●●● patch | view | raw | blame | history
SOURCES/0016-Fix-ca-less-IPA-install-on-fips-mode.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0016-WebUI-Add-support-for-login-for-AD-users.patch 341 ●●●●● patch | view | raw | blame | history
SOURCES/0017-cert-do-not-limit-internal-searches-in-cert-find.patch 105 ●●●●● patch | view | raw | blame | history
SOURCES/0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch 281 ●●●●● patch | view | raw | blame | history
SOURCES/0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch 132 ●●●●● patch | view | raw | blame | history
SOURCES/0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch 71 ●●●●● patch | view | raw | blame | history
SOURCES/0019-IPA-certauth-plugin.patch 609 ●●●●● patch | view | raw | blame | history
SOURCES/0019-ipaserver-plugins-trust.py-pep8-compliance.patch 786 ●●●●● patch | view | raw | blame | history
SOURCES/0020-Don-t-use-admin-cert-during-KRA-installation.patch 56 ●●●●● patch | view | raw | blame | history
SOURCES/0020-configure-fix-disable-server-with-certauth-plugin.patch 55 ●●●●● patch | view | raw | blame | history
SOURCES/0021-389-ds-base-crashed-as-part-of-ipa-server-intall-in-.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/0021-ipa-kdb-do-not-depend-on-certauth_plugin.h.patch 85 ●●●●● patch | view | raw | blame | history
SOURCES/0022-Prevent-set_directive-from-clobbering-other-keys.patch 84 ●●●●● patch | view | raw | blame | history
SOURCES/0022-WebUI-Add-support-for-suppressing-warnings.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/0023-WebUI-suppress-truncation-warning-in-select-widget.patch 37 ●●●●● patch | view | raw | blame | history
SOURCES/0023-pep8-reduce-line-lengths-in-CAInstance.__enable_crl_.patch 113 ●●●●● patch | view | raw | blame | history
SOURCES/0024-WebUI-Fix-showing-vault-in-selfservice-view.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/0024-installutils-refactor-set_directive.patch 92 ●●●●● patch | view | raw | blame | history
SOURCES/0025-Add-tests-for-installutils.set_directive.patch 79 ●●●●● patch | view | raw | blame | history
SOURCES/0025-Set-KDC-Disable-Last-Success-by-default.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0026-Add-safe-DirectiveSetter-context-manager.patch 365 ●●●●● patch | view | raw | blame | history
SOURCES/0026-WebUI-Allow-to-add-certs-to-certmapping-with-CERT-LI.patch 69 ●●●●● patch | view | raw | blame | history
SOURCES/0027-Bump-samba-version-for-FIPS-and-priv.-separation.patch 40 ●●●●● patch | view | raw | blame | history
SOURCES/0027-Old-pylint-doesn-t-support-bad-python3-option.patch 27 ●●●●● patch | view | raw | blame | history
SOURCES/0028-Reworked-the-renaming-mechanism.patch 296 ●●●●● patch | view | raw | blame | history
SOURCES/0028-WebUI-make-keytab-tables-on-service-and-host-pages-w.patch 158 ●●●●● patch | view | raw | blame | history
SOURCES/0029-Allow-renaming-of-the-HBAC-rule-objects.patch 103 ●●●●● patch | view | raw | blame | history
SOURCES/0029-Idviews-fix-objectclass-violation-on-idview-add.patch 108 ●●●●● patch | view | raw | blame | history
SOURCES/0030-Allow-renaming-of-the-sudorule-objects.patch 100 ●●●●● patch | view | raw | blame | history
SOURCES/0030-Fixing-the-cert-request-comparing-whole-email-addres.patch 107 ●●●●● patch | view | raw | blame | history
SOURCES/0031-Add-force-join-into-ipa-replica-install-manpage.patch 29 ●●●●● patch | view | raw | blame | history
SOURCES/0031-Create-temporaty-directories-at-the-begining-of-unin.patch 36 ●●●●● patch | view | raw | blame | history
SOURCES/0032-Changed-ownership-of-ldiffile-to-DS_USER.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0032-dogtag-ipa-ca-renew-agent-submit-fix-the-is_replicat.patch 38 ●●●●● patch | view | raw | blame | history
SOURCES/0033-Checks-if-Dir-Server-is-installed-and-running-before.patch 57 ●●●●● patch | view | raw | blame | history
SOURCES/0033-Simplify-KRA-transport-cert-cache.patch 195 ●●●●● patch | view | raw | blame | history
SOURCES/0034-WebUI-Add-positive-number-validator.patch 96 ●●●●● patch | view | raw | blame | history
SOURCES/0034-rpcserver.login_x509-Actually-return-reply-from-__ca.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0035-Backup-CA-cert-from-kerberos-folder.patch 27 ●●●●● patch | view | raw | blame | history
SOURCES/0035-WebUI-change-validator-of-page-size-settings.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0036-WebUI-fix-jslint-error.patch 30 ●●●●● patch | view | raw | blame | history
SOURCES/0036-spec-file-Bump-requires-to-make-Certificate-Login-in.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/0037-Use-Custodia-0.3.1-features.patch 236 ●●●●● patch | view | raw | blame | history
SOURCES/0037-ipa-advise-for-smartcards-updated.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0038-spec-file-bump-krb5-devel-BuildRequires-for-certauth.patch 40 ●●●●● patch | view | raw | blame | history
SOURCES/0039-Avoid-growing-FILE-ccaches-unnecessarily.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0040-Handle-failed-authentication-via-cookie.patch 120 ●●●●● patch | view | raw | blame | history
SOURCES/0041-Work-around-issues-fetching-session-data.patch 331 ●●●●● patch | view | raw | blame | history
SOURCES/0042-Prevent-churn-on-ccaches.patch 71 ●●●●● patch | view | raw | blame | history
SOURCES/0043-Generate-PIN-for-PKI-to-help-Dogtag-in-FIPS.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/0044-httpinstance.disable_system_trust-Don-t-fail-if-modu.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0045-extdom-do-reverse-search-for-domain-separator.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/0046-extdom-improve-cert-request.patch 243 ●●●●● patch | view | raw | blame | history
SOURCES/0047-spec-file-bump-libsss_nss_idmap-devel-BuildRequires.patch 37 ●●●●● patch | view | raw | blame | history
SOURCES/0048-server-make-sure-we-test-for-sss_nss_getlistbycert.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0049-Upgrade-configure-PKINIT-after-adding-anonymous-prin.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0050-Remove-unused-variable-from-failed-anonymous-PKINIT-.patch 28 ●●●●● patch | view | raw | blame | history
SOURCES/0051-Split-out-anonymous-PKINIT-test-to-a-separate-method.patch 37 ●●●●● patch | view | raw | blame | history
SOURCES/0052-Ensure-KDC-is-propery-configured-after-upgrade.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0053-adtrust-make-sure-that-runtime-hostname-result-is-co.patch 77 ●●●●● patch | view | raw | blame | history
SOURCES/0054-Allow-erasing-ipaDomainResolutionOrder-attribute.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/0055-Always-check-and-create-anonymous-principal-during-K.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/0056-Remove-duplicate-functionality-in-upgrade.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/0057-Fix-the-order-of-cert-files-check.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0058-Don-t-allow-setting-pkinit-related-options-on-DL0.patch 95 ●●●●● patch | view | raw | blame | history
SOURCES/0059-replica-prepare-man-remove-pkinit-option-refs.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/0060-Remove-redundant-option-check-for-cert-files.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/0061-Hide-request_type-doc-string-in-cert-request-help.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0062-Get-correct-CA-cert-nickname-in-CA-less.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/0063-Remove-publish_ca_cert-method-from-NSSDatabase.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/0064-httpinstance-make-sure-NSS-database-is-backed-up.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0065-IPA-KDB-use-relative-path-in-ipa-certmap-config-snip.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/0066-Add-pki_pin-only-when-needed.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/0067-idrange-add-properly-handle-empty-dom-name-option.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0068-ipa-sam-create-the-gidNumber-attribute-in-the-truste.patch 145 ●●●●● patch | view | raw | blame | history
SOURCES/0069-Upgrade-add-gidnumber-to-trusted-domain-entry.patch 104 ●●●●● patch | view | raw | blame | history
SOURCES/0070-dsinstance-reconnect-ldap2-after-DS-is-restarted-by-.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/0071-httpinstance-avoid-httpd-restart-during-certificate-.patch 52 ●●●●● patch | view | raw | blame | history
SOURCES/0072-dsinstance-httpinstance-consolidate-certificate-requ.patch 289 ●●●●● patch | view | raw | blame | history
SOURCES/0073-install-request-service-certs-after-host-keytab-is-s.patch 135 ●●●●● patch | view | raw | blame | history
SOURCES/0074-renew-agent-revert-to-host-keytab-authentication.patch 53 ●●●●● patch | view | raw | blame | history
SOURCES/0075-renew-agent-restart-scripts-connect-to-LDAP-after-ki.patch 117 ●●●●● patch | view | raw | blame | history
SOURCES/0076-ipaserver-dcerpc-unify-error-processing.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/0077-trust-always-use-oddjobd-helper-for-fetching-trust-i.patch 86 ●●●●● patch | view | raw | blame | history
SOURCES/0078-WebUI-cert-login-Configure-name-of-parameter-used-to.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0079-Create-system-users-for-FreeIPA-services-during-pack.patch 414 ●●●●● patch | view | raw | blame | history
SOURCES/0080-Fix-s4u2self-with-adtrust.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/0081-Add-debug-log-in-case-cookie-retrieval-went-wrong.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0082-server-install-remove-broken-no-pkinit-check.patch 36 ●●●●● patch | view | raw | blame | history
SOURCES/0083-Add-the-force-join-option-to-replica-install.patch 55 ●●●●● patch | view | raw | blame | history
SOURCES/0084-replicainstall-better-client-install-exception-handl.patch 120 ●●●●● patch | view | raw | blame | history
SOURCES/0085-Fix-CA-less-to-CA-full-upgrade.patch 110 ●●●●● patch | view | raw | blame | history
SOURCES/0086-cert-defer-cert-find-result-post-processing.patch 221 ●●●●● patch | view | raw | blame | history
SOURCES/0087-server-install-No-double-Kerberos-install.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/0088-ext.-CA-correctly-write-the-cert-chain.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0089-Fix-RA-cert-import-during-DL0-replication.patch 122 ●●●●● patch | view | raw | blame | history
SOURCES/0090-configure-fix-AC_CHECK_LIB-usage.patch 64 ●●●●● patch | view | raw | blame | history
SOURCES/0091-Fix-CAInstance.import_ra_cert-for-empty-passwords.patch 30 ●●●●● patch | view | raw | blame | history
SOURCES/0092-upgrade-adtrust-update_tdo_gidnumber-plugin-must-che.patch 37 ●●●●● patch | view | raw | blame | history
SOURCES/0093-compat-manage-behave-the-same-for-all-users.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0094-Move-the-compat-plugin-setup-at-the-end-of-install.patch 317 ●●●●● patch | view | raw | blame | history
SOURCES/0095-compat-ignore-cn-topology-cn-ipa-cn-etc-subtree.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/0096-spec-file-bump-krb5-Requires-for-certauth-fixes.patch 68 ●●●●● patch | view | raw | blame | history
SOURCES/0097-Hide-PKI-Client-database-password-in-log-file.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/0098-Vault-Explicitly-default-to-3DES-CBC.patch 50 ●●●●● patch | view | raw | blame | history
SOURCES/0099-separate-function-to-set-ipaConfigString-values-on-s.patch 244 ●●●●● patch | view | raw | blame | history
SOURCES/0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch 205 ●●●●● patch | view | raw | blame | history
SOURCES/0101-API-for-retrieval-of-master-s-PKINIT-status-and-publ.patch 99 ●●●●● patch | view | raw | blame | history
SOURCES/0102-Use-only-anonymous-PKINIT-to-fetch-armor-ccache.patch 79 ●●●●● patch | view | raw | blame | history
SOURCES/0103-Stop-requesting-anonymous-keytab-and-purge-all-refer.patch 110 ●●●●● patch | view | raw | blame | history
SOURCES/0104-Use-local-anchor-when-armoring-password-requests.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0105-Upgrade-configure-local-full-PKINIT-depending-on-the.patch 52 ●●●●● patch | view | raw | blame | history
SOURCES/0106-Do-not-test-anonymous-PKINIT-after-install-upgrade.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/0107-vault-piped-input-for-ipa-vault-add-fails.patch 104 ●●●●● patch | view | raw | blame | history
SOURCES/0108-automount-install-fix-checking-of-SSSD-functionality.patch 83 ●●●●● patch | view | raw | blame | history
SOURCES/0109-Fix-CA-server-cert-validation-in-FIPS.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/0110-restore-restart-reload-gssproxy-after-restore.patch 77 ●●●●● patch | view | raw | blame | history
SOURCES/0111-kerberos-session-use-CA-cert-with-full-cert-chain-fo.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0112-ipa-client-install-remove-extra-space-in-pkinit_anch.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0113-Refresh-Dogtag-RestClient.ca_host-property.patch 114 ●●●●● patch | view | raw | blame | history
SOURCES/0114-Remove-the-cachedproperty-class.patch 71 ●●●●● patch | view | raw | blame | history
SOURCES/0115-ipa-server-install-with-external-CA-fix-pkinit-cert-.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/0116-kra-install-update-installation-failure-message.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0117-Make-sure-remote-hosts-have-our-keys.patch 114 ●●●●● patch | view | raw | blame | history
SOURCES/0118-Use-proper-SELinux-context-with-http.keytab.patch 40 ●●●●● patch | view | raw | blame | history
SOURCES/0119-ipa-kra-install-fix-check_host_keys.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0120-python2-ipalib-add-missing-python-dependency.patch 30 ●●●●● patch | view | raw | blame | history
SOURCES/0121-installer-service-fix-typo-in-service-entry.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0122-upgrade-add-missing-suffix-to-http-instance.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0123-Turn-on-NSSOCSP-check-in-mod_nss-conf.patch 227 ●●●●● patch | view | raw | blame | history
SOURCES/0124-cert-show-writable-files-does-not-mean-dirs.patch 31 ●●●●● patch | view | raw | blame | history
SOURCES/0125-Bump-version-of-ipa.conf-file.patch 30 ●●●●● patch | view | raw | blame | history
SOURCES/0126-ipa-kra-install-manpage-document-domain-level-1.patch 72 ●●●●● patch | view | raw | blame | history
SOURCES/0127-renew-agent-respect-CA-renewal-master-setting.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/0128-server-upgrade-always-fix-certmonger-tracking-reques.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/0129-cainstance-use-correct-profile-for-lightweight-CA-ce.patch 182 ●●●●● patch | view | raw | blame | history
SOURCES/0130-renew-agent-allow-reusing-existing-certs.patch 260 ●●●●● patch | view | raw | blame | history
SOURCES/0131-renew-agent-always-export-CSR-on-IPA-CA-certificate-.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/0132-renew-agent-get-rid-of-virtual-profiles.patch 321 ●●●●● patch | view | raw | blame | history
SOURCES/0133-ipa-cacert-manage-add-external-ca-type.patch 97 ●●●●● patch | view | raw | blame | history
SOURCES/0134-Fixing-adding-authenticator-indicators-to-host.patch 70 ●●●●● patch | view | raw | blame | history
SOURCES/0135-Added-plugins-directory-to-ipaclient-subpackages.patch 35 ●●●●● patch | view | raw | blame | history
SOURCES/0136-ipaclient-fix-missing-RPM-ownership.patch 71 ●●●●● patch | view | raw | blame | history
SOURCES/0137-otptoken-add-yubikey-When-digits-not-provided-use-de.patch 36 ●●●●● patch | view | raw | blame | history
SOURCES/0138-ipa-server-install-fix-uninstall.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0139-ca-install-merge-duplicated-code-for-DM-password.patch 85 ●●●●● patch | view | raw | blame | history
SOURCES/0140-installutils-add-DM-password-validator.patch 55 ●●●●● patch | view | raw | blame | history
SOURCES/0141-ca-kra-install-validate-DM-password.patch 73 ●●●●● patch | view | raw | blame | history
SOURCES/0142-ipa-kra-install-fix-pkispawn-setting-for-pki_securit.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0143-certdb-add-named-trust-flag-constants.patch 344 ●●●●● patch | view | raw | blame | history
SOURCES/0144-certdb-certs-make-trust-flags-argument-mandatory.patch 181 ●●●●● patch | view | raw | blame | history
SOURCES/0145-certdb-use-custom-object-for-trust-flags.patch 358 ●●●●● patch | view | raw | blame | history
SOURCES/0146-install-trust-IPA-CA-for-PKINIT.patch 202 ●●●●● patch | view | raw | blame | history
SOURCES/0147-client-install-fix-client-PKINIT-configuration.patch 254 ●●●●● patch | view | raw | blame | history
SOURCES/0148-install-introduce-generic-Kerberos-Augeas-lens.patch 98 ●●●●● patch | view | raw | blame | history
SOURCES/0149-server-install-fix-KDC-PKINIT-configuration.patch 292 ●●●●● patch | view | raw | blame | history
SOURCES/0150-ipapython.ipautil.run-Add-option-to-set-umask-before.patch 85 ●●●●● patch | view | raw | blame | history
SOURCES/0151-certs-do-not-export-keys-world-readable-in-install_k.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0152-certs-do-not-export-CA-certs-in-install_pem_from_p12.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0153-server-install-fix-KDC-certificate-validation-in-CA-.patch 203 ●●●●● patch | view | raw | blame | history
SOURCES/0154-replica-install-respect-pkinit-cert-file.patch 56 ●●●●● patch | view | raw | blame | history
SOURCES/0155-cacert-manage-support-PKINIT.patch 74 ●●●●● patch | view | raw | blame | history
SOURCES/0156-server-certinstall-support-PKINIT.patch 163 ●●●●● patch | view | raw | blame | history
SOURCES/0157-ipa-ca-install-append-CA-cert-chain-into-etc-ipa-ca..patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/0158-ca-cert-show-check-certificate_out-in-options.patch 73 ●●●●● patch | view | raw | blame | history
SOURCES/0159-Fix-rare-race-condition-with-missing-ccache-file.patch 47 ●●●●● patch | view | raw | blame | history
SOURCES/0160-Remove-pkinit-anonymous-command.patch 176 ●●●●● patch | view | raw | blame | history
SOURCES/0161-krb5-make-sure-KDC-certificate-is-readable.patch 108 ●●●●● patch | view | raw | blame | history
SOURCES/0162-Change-python-cryptography-to-python2-cryptography.patch 41 ●●●●● patch | view | raw | blame | history
SOURCES/0163-Allow-for-multivalued-server-attributes.patch 270 ●●●●● patch | view | raw | blame | history
SOURCES/0164-Refactor-the-role-attribute-member-reporting-code.patch 179 ●●●●● patch | view | raw | blame | history
SOURCES/0165-Add-an-attribute-reporting-client-PKINIT-capable-ser.patch 275 ●●●●● patch | view | raw | blame | history
SOURCES/0166-Add-the-list-of-PKINIT-servers-as-a-virtual-attribut.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0167-Add-pkinit-status-command.patch 201 ●●●●● patch | view | raw | blame | history
SOURCES/0168-test_serverroles-Get-rid-of-MockLDAP-and-use-ldap2-i.patch 238 ●●●●● patch | view | raw | blame | history
SOURCES/0169-only-stop-disable-simple-service-if-it-is-installed.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/0170-Fix-index-definition-for-ipaAnchorUUID.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0171-httpinstance-wait-until-the-service-entry-is-replica.patch 126 ●●●●● patch | view | raw | blame | history
SOURCES/0172-kdc.key-should-not-be-visible-to-all.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0173-ipa-kdb-reload-certificate-mapping-rules-periodicall.patch 221 ●●●●● patch | view | raw | blame | history
SOURCES/0174-Avoid-possible-endless-recursion-in-RPC-call.patch 127 ●●●●● patch | view | raw | blame | history
SOURCES/0175-rpc-preparations-for-recursion-fix.patch 103 ●●●●● patch | view | raw | blame | history
SOURCES/0176-rpc-avoid-possible-recursion-in-create_connection.patch 175 ●●●●● patch | view | raw | blame | history
SOURCES/0177-Changing-cert-find-to-do-not-use-only-primary-key-to.patch 102 ●●●●● patch | view | raw | blame | history
SOURCES/0178-ipa-kdb-add-pkinit-authentication-indicator-in-case-.patch 101 ●●●●● patch | view | raw | blame | history
SOURCES/0179-fix-incorrect-suffix-handling-in-topology-checks.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/0180-server-certinstall-update-KDC-master-entry.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0181-pkinit-manage-introduce-ipa-pkinit-manage.patch 259 ●●●●● patch | view | raw | blame | history
SOURCES/0182-server-upgrade-do-not-enable-PKINIT-by-default.patch 42 ●●●●● patch | view | raw | blame | history
SOURCES/0183-Turn-off-OCSP-check.patch 196 ●●●●● patch | view | raw | blame | history
SOURCES/0184-Only-warn-when-specified-server-IP-addresses-don-t-m.patch 244 ●●●●● patch | view | raw | blame | history
SOURCES/0185-ipa-kdb-use-canonical-principal-in-certauth-plugin.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0186-Bump-version-of-python-gssapi.patch 66 ●●●●● patch | view | raw | blame | history
SOURCES/0187-Add-code-to-be-able-to-set-default-kinit-lifetime.patch 84 ●●●●● patch | view | raw | blame | history
SOURCES/0188-Revert-setting-sessionMaxAge-for-old-clients.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/0189-Extend-the-advice-printing-code-by-some-useful-abstr.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/0190-Prepare-advise-plugin-for-smart-card-auth-configurat.patch 293 ●●●●● patch | view | raw | blame | history
SOURCES/0191-trust-mod-allow-modifying-list-of-UPNs-of-a-trusted-.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/0192-WebUI-add-support-for-changing-trust-UPN-suffixes.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0193-kra-promote-Get-ticket-before-calling-custodia.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/0194-Fix-local-IP-address-validation.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0195-ipa-dns-install-remove-check-for-local-ip-address.patch 32 ●●●●● patch | view | raw | blame | history
SOURCES/0196-refactor-CheckedIPAddress-class.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/0197-CheckedIPAddress-remove-match_local-param.patch 141 ●●●●● patch | view | raw | blame | history
SOURCES/0198-Remove-ip_netmask-from-option-parser.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/0199-replica-install-add-missing-check-for-non-local-IP-a.patch 29 ●●●●● patch | view | raw | blame | history
SOURCES/0200-Remove-network-and-broadcast-address-warnings.patch 146 ●●●●● patch | view | raw | blame | history
SOURCES/0201-ipa-sam-replace-encode_nt_key-with-E_md4hash.patch 80 ●●●●● patch | view | raw | blame | history
SOURCES/0202-ipa_pwd_extop-do-not-generate-NT-hashes-in-FIPS-mode.patch 102 ●●●●● patch | view | raw | blame | history
SOURCES/0203-Make-sure-we-check-ccaches-in-all-rpcserver-paths.patch 126 ●●●●● patch | view | raw | blame | history
SOURCES/0204-replica-install-drop-in-IPA-specific-config-to-tmpfi.patch 34 ●●●●● patch | view | raw | blame | history
SOURCES/0205-Add-CommonNameToSANDefault-to-default-cert-profile.patch 62 ●●●●● patch | view | raw | blame | history
SOURCES/0206-smart-card-advises-configure-systemwide-NSS-DB-also-.patch 131 ●●●●● patch | view | raw | blame | history
SOURCES/0207-smart-card-advises-add-steps-to-store-smart-card-sig.patch 125 ●●●●● patch | view | raw | blame | history
SOURCES/0208-Allow-to-pass-in-multiple-CA-cert-paths-to-the-smart.patch 150 ●●●●● patch | view | raw | blame | history
SOURCES/0209-add-a-class-that-tracks-the-indentation-in-the-gener.patch 77 ●●●●● patch | view | raw | blame | history
SOURCES/0210-delegate-the-indentation-handling-in-advises-to-dedi.patch 267 ●●●●● patch | view | raw | blame | history
SOURCES/0211-advise-add-an-infrastructure-for-formatting-Bash-com.patch 104 ●●●●● patch | view | raw | blame | history
SOURCES/0212-delegate-formatting-of-compound-Bash-statements-to-d.patch 93 ●●●●● patch | view | raw | blame | history
SOURCES/0213-Fix-indentation-of-statements-in-Smart-card-advises.patch 36 ●●●●● patch | view | raw | blame | history
SOURCES/0214-Use-the-compound-statement-formatting-API-for-config.patch 48 ●●●●● patch | view | raw | blame | history
SOURCES/0215-smart-card-advises-use-a-wrapper-around-Bash-for-loo.patch 121 ●●●●● patch | view | raw | blame | history
SOURCES/0216-smart-card-advise-use-password-when-changing-trust-f.patch 54 ●●●●● patch | view | raw | blame | history
SOURCES/0217-smart-card-advises-ensure-that-krb5-pkinit-is-instal.patch 46 ●●●●● patch | view | raw | blame | history
SOURCES/0218-NULL-LDAP-context-in-call-to-ldap_search_ext_s-durin.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0219-Restore-old-version-of-caIPAserviceCert-for-upgrade-.patch 187 ●●●●● patch | view | raw | blame | history
SOURCES/0220-ipa-otptoken-import-Make-PBKDF2-refer-to-the-pkcs5-n.patch 84 ●●●●● patch | view | raw | blame | history
SOURCES/0221-Adds-whoami-DS-plugin-in-case-that-plugin-is-missing.patch 59 ●●●●● patch | view | raw | blame | history
SOURCES/0222-Fix-ipa-config-mod-ca-renewal-master.patch 88 ●●●●● patch | view | raw | blame | history
SOURCES/0223-Backport-PR-988-to-ipa-4-5-Fix-Certificate-renewal-w.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/0224-Backport-PR-1008-to-ipa-4-5-Fix-ipa-server-upgrade-T.patch 213 ●●●●● patch | view | raw | blame | history
SOURCES/0225-Fixing-how-sssd.conf-is-updated-when-promoting-a-cli.patch 92 ●●●●● patch | view | raw | blame | history
SOURCES/0226-Backport-4-5-Fix-ipa-server-upgrade-with-server-cert.patch 199 ●●●●● patch | view | raw | blame | history
SOURCES/0227-Always-check-peer-has-keys-before-connecting.patch 73 ●●●●● patch | view | raw | blame | history
SOURCES/0228-Make-sure-upgrade-also-checks-for-IPv6-stack.patch 61 ●●●●● patch | view | raw | blame | history
SOURCES/0229-control-logging-of-host_port_open-from-caller.patch 103 ●●●●● patch | view | raw | blame | history
SOURCES/0230-log-progress-of-wait_for_open_ports.patch 44 ●●●●● patch | view | raw | blame | history
SOURCES/0231-Store-help-in-Schema-before-writing-to-disk.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/0232-Disable-pylint-in-get_help-function-because-of-type-.patch 33 ●●●●● patch | view | raw | blame | history
SOURCES/0233-Less-confusing-message-for-PKINIT-configuration-duri.patch 50 ●●●●● patch | view | raw | blame | history
SOURCES/0234-server.py-Removes-dns-server-configuration-from-ldap.patch 45 ●●●●● patch | view | raw | blame | history
SOURCES/0235-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch 75 ●●●●● patch | view | raw | blame | history
SOURCES/0236-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch 51 ●●●●● patch | view | raw | blame | history
SOURCES/1001-Change-branding-to-IPA-and-Identity-Management.patch 73 ●●●● patch | view | raw | blame | history
SOURCES/1002-Package-copy-schema-to-ca.py.patch 8 ●●●● patch | view | raw | blame | history
SOURCES/1003-Revert-Increased-mod_wsgi-socket-timeout.patch 4 ●●●● patch | view | raw | blame | history
SOURCES/1004-Remove-csrgen.patch 49 ●●●●● patch | view | raw | blame | history
SOURCES/ipa-centos-branding.patch 38 ●●●●● patch | view | raw | blame | history
SPECS/ipa.spec 518 ●●●●● patch | view | raw | blame | history
.gitignore
@@ -1,4 +1,4 @@
SOURCES/freeipa-4.5.0.tar.gz
SOURCES/freeipa-4.5.4.tar.gz
SOURCES/header-logo.png
SOURCES/login-screen-background.jpg
SOURCES/login-screen-logo.png
.ipa.metadata
@@ -1,4 +1,4 @@
686e9b1375659524de83e1b78df66b355715438e SOURCES/freeipa-4.5.0.tar.gz
2707c6f6de4ab05e1cbd741297b655e1d1ef1c24 SOURCES/freeipa-4.5.4.tar.gz
77c318cf1f4fc25cf847de0692a77859a767c0e3 SOURCES/header-logo.png
8727245558422bf966d60677568925f081b8e299 SOURCES/login-screen-background.jpg
24a29d79efbd0906777be4639957abda111fca4b SOURCES/login-screen-logo.png
SOURCES/0001-Add-options-to-allow-ticket-caching.patch
File was deleted
SOURCES/0001-ds-ignore-time-skew-during-initial-replication-step.patch
New file
@@ -0,0 +1,86 @@
From a3bcb05ce1c554aa98af9343bec7335521db3a3e Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 16 Oct 2017 13:32:38 +0300
Subject: [PATCH] ds: ignore time skew during initial replication step
Initial replica creation can go with ignoring time skew checks.
We should, however, force time skew checks during normal operation.
Fixes https://pagure.io/freeipa/issue/7211
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/share/Makefile.am                    |  1 +
 install/share/replica-prevent-time-skew.ldif |  4 ++++
 ipaserver/install/dsinstance.py              | 24 ++++++++++++++++++++++++
 3 files changed, 29 insertions(+)
 create mode 100644 install/share/replica-prevent-time-skew.ldif
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index 85a061c6976dcc55b0ba2250423a344e14f2ce97..46b3d77663113f770765c8bd1d8a916791d628f4 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -38,6 +38,7 @@ dist_app_DATA =                \
     default-trust-view.ldif        \
     delegation.ldif            \
     replica-acis.ldif        \
+    replica-prevent-time-skew.ldif  \
     ds-nfiles.ldif            \
     dns.ldif            \
     dnssec.ldif            \
diff --git a/install/share/replica-prevent-time-skew.ldif b/install/share/replica-prevent-time-skew.ldif
new file mode 100644
index 0000000000000000000000000000000000000000..5d301feddb56347f3b35be89edaae1a7d91e07de
--- /dev/null
+++ b/install/share/replica-prevent-time-skew.ldif
@@ -0,0 +1,4 @@
+dn: cn=config
+changetype: modify
+replace: nsslapd-ignore-time-skew
+nsslapd-ignore-time-skew: $SKEWVALUE
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index c9db8ac28c3ca10539b745ca09f4d8aaece02e0c..7a88612997a3fa96cf394852401fb01e5e4501d5 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -392,7 +392,21 @@ class DsInstance(service.Service):
         self.step("restarting directory server", self.__restart_instance)
         self.step("creating DS keytab", self.request_service_keytab)
+
+        # 389-ds allows to ignore time skew during replication. It is disabled
+        # by default to avoid issues with non-contiguous CSN values which
+        # derived from a time stamp when the change occurs. However, there are
+        # cases when we are interested only in the changes coming from the
+        # other side and should therefore allow ignoring the time skew.
+        #
+        # This helps with initial replication or force-sync because
+        # the receiving side has no valuable changes itself yet.
+        self.step("ignore time skew for initial replication",
+                  self.__replica_ignore_initial_time_skew)
+
         self.step("setting up initial replication", self.__setup_replica)
+        self.step("prevent time skew after initial replication",
+                  self.replica_manage_time_skew)
         self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
         self.step("updating schema", self.__update_schema)
         # See LDIFs for automember configuration during replica install
@@ -929,6 +943,16 @@ class DsInstance(service.Service):
     def __add_replication_acis(self):
         self._ldap_mod("replica-acis.ldif", self.sub_dict)
+    def __replica_ignore_initial_time_skew(self):
+        self.replica_manage_time_skew(prevent=False)
+
+    def replica_manage_time_skew(self, prevent=True):
+        if prevent:
+            self.sub_dict['SKEWVALUE'] = 'off'
+        else:
+            self.sub_dict['SKEWVALUE'] = 'on'
+        self._ldap_mod("replica-prevent-time-skew.ldif", self.sub_dict)
+
     def __setup_s4u2proxy(self):
         self._ldap_mod("replica-s4u2proxy.ldif", self.sub_dict)
--
2.9.5
SOURCES/0002-Use-connection-keep-alive.patch
File was deleted
SOURCES/0002-ipa-replica-manage-implicitly-ignore-initial-time-sk.patch
New file
@@ -0,0 +1,41 @@
From 469f8ba59eb369267a9d404291ce7794f996d9f4 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 16 Oct 2017 13:46:38 +0300
Subject: [PATCH] ipa-replica-manage: implicitly ignore initial time skew in
 force-sync
When performing force synchronization, implicitly ignore initial
time skew (if any) and restore it afterwards.
This also changes semantics of force-sync by waiting until the end of
the initial replication.
Fixes https://pagure.io/freeipa/issue/7211
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/tools/ipa-replica-manage | 6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index f802201b7f93facb1e78463aa02eab66a1ae23ea..c00d8ca3a0fa8228c5aa782a270991f14ee16974 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -1231,8 +1231,14 @@ def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False):
         repl = replication.ReplicationManager(realm, thishost, dirman_passwd)
         repl.force_sync(repl.conn, fromhost)
     else:
+        ds = dsinstance.DsInstance(realm_name=realm)
+        ds.ldapi = os.getegid() == 0
+        ds.replica_manage_time_skew(prevent=False)
         repl = replication.ReplicationManager(realm, fromhost, dirman_passwd)
         repl.force_sync(repl.conn, thishost)
+        agreement = repl.get_replication_agreement(thishost)
+        repl.wait_for_repl_init(repl.conn, agreement.dn)
+        ds.replica_manage_time_skew(prevent=True)
 def show_DNA_ranges(hostname, master, realm, dirman_passwd, nextrange=False,
                     nolookup=False):
--
2.9.5
SOURCES/0003-Add-debug-logging-for-keep-alive.patch
File was deleted
SOURCES/0003-Checks-if-replica-s4u2proxy.ldif-should-be-applied.patch
New file
@@ -0,0 +1,51 @@
From 17fab4982fcb8b8af6c20130907dd3d4bad7f699 Mon Sep 17 00:00:00 2001
From: Felipe Barreto <fbarreto@redhat.com>
Date: Fri, 13 Oct 2017 09:19:43 +0200
Subject: [PATCH] Checks if replica-s4u2proxy.ldif should be applied
Before applying replica-s3u2proxy.ldif, we check
if the values are already there. The values can be
there if a replica installation was done in the past
and some info was left behind. Also, the code checks
the values independently.
https://pagure.io/freeipa/issue/7174
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipaserver/install/dsinstance.py | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 7a88612997a3fa96cf394852401fb01e5e4501d5..923f483340a26a614001701ce6c235dd73501501 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -954,7 +954,24 @@ class DsInstance(service.Service):
         self._ldap_mod("replica-prevent-time-skew.ldif", self.sub_dict)
     def __setup_s4u2proxy(self):
-        self._ldap_mod("replica-s4u2proxy.ldif", self.sub_dict)
+
+        def __add_principal(last_cn, principal, self):
+            dn = DN(('cn', last_cn), ('cn', 's4u2proxy'),
+                    ('cn', 'etc'), self.suffix)
+
+            value = '{principal}/{fqdn}@{realm}'.format(fqdn=self.fqdn,
+                                                        realm=self.realm,
+                                                        principal=principal)
+
+            entry = api.Backend.ldap2.get_entry(dn, ['memberPrincipal'])
+            try:
+                entry['memberPrincipal'].append(value)
+                api.Backend.ldap2.update_entry(entry)
+            except errors.EmptyModlist:
+                pass
+
+        __add_principal('ipa-http-delegation', 'HTTP', self)
+        __add_principal('ipa-ldap-delegation-targets', 'ldap', self)
     def __create_indices(self):
         self._ldap_mod("indices.ldif")
--
2.9.5
SOURCES/0004-Increase-Apache-HTTPD-s-default-keep-alive-timeout.patch
File was deleted
SOURCES/0004-ldap-limit-the-retro-changelog-to-dns-subtree.patch
New file
@@ -0,0 +1,32 @@
From d3c36fb83314c3fd1b87572a1c80687f06d7e2d5 Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkrizek@redhat.com>
Date: Mon, 23 Oct 2017 14:06:20 +0200
Subject: [PATCH] ldap: limit the retro changelog to dns subtree
The content synchronization plugin can be limited to the dns subtree in
Directory Server. This increases performance and helps to prevent some
potential issues.
Fixes: https://pagure.io/freeipa/issue/6515
Signed-off-by: Tomas Krizek <tkrizek@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/updates/20-syncrepl.update | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/updates/20-syncrepl.update b/install/updates/20-syncrepl.update
index faa13f645f492ea35824fe57632b56d52afa8a6e..318eda16870afa06d6c6d9098cbffdc085f2dba2 100644
--- a/install/updates/20-syncrepl.update
+++ b/install/updates/20-syncrepl.update
@@ -4,7 +4,7 @@ only:nsslapd-pluginEnabled: on
 # Remember original nsuniqueid for objects referenced from cn=changelog
 add:nsslapd-attribute: nsuniqueid:targetUniqueId
 add:nsslapd-changelogmaxage: 2d
-add:nsslapd-exclude-suffix: o=ipaca
+add:nsslapd-include-suffix: cn=dns,$SUFFIX
 # Keep memberOf and referential integrity plugins away from cn=changelog.
 # It is necessary for performance reasons because we don't have appropriate
--
2.9.5
SOURCES/0005-Fix-ipa-replica-conncheck-when-called-with-principal.patch
New file
@@ -0,0 +1,45 @@
From 20f2650a8a23d288571fde552ed1c242cd972d88 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Fri, 27 Oct 2017 09:05:20 +0200
Subject: [PATCH] Fix ipa-replica-conncheck when called with --principal
ipa-replica-conncheck can be called with --principal / --password or
with an existing Kerberos credential cache in order to supply the
authorized identity logging in to the master machine (in
auto-master-check mode).
In domain-level 0, the tool is called with --principal and password
and tries to obtain a TGT by performing kinit, but does not set the
env var KRB5CCNAME. Subsequent calls to IPA API do not use the
credential cache and fail. In this case, ipa-replica-conncheck falls
back to using SSH to check master connectivity instead of IPA API,
and the ssh check is less robust.
The code should set the KRB5CCNAME env var for IPA API to use the
credential cache.
Fixes:
https://pagure.io/freeipa/issue/7221
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/tools/ipa-replica-conncheck | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index 03281d1c7b6ee9f1d4cabebceb0c7e64b09601c0..545cdf00ca74289e6532a40de4c9abad5af4cee0 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -534,6 +534,9 @@ def main():
                 if result.returncode != 0:
                     raise RuntimeError("Could not get ticket for master server: %s" %
                                         result.error_output)
+                # Now that the cred cache file is initialized,
+                # use it for the IPA API calls
+                os.environ['KRB5CCNAME'] = CCACHE_FILE
             try:
                 root_logger.info("Check RPC connection to remote master")
--
2.9.5
SOURCES/0005-ipapython.ipautil.nolog_replace-Do-not-replace-empty.patch
File was deleted
SOURCES/0006-Include-the-CA-basic-constraint-in-CSRs-when-renewin.patch
New file
@@ -0,0 +1,75 @@
From 148e78d74206730c31dd7bc87eece5c5bd1440ac Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 9 Aug 2017 17:28:35 -0400
Subject: [PATCH] Include the CA basic constraint in CSRs when renewing a CA
The CSR generated by `ipa-cacert-manage renew --external-ca` did
not include the CA basic constraint:
  X509v3 Basic Constraints: critical
      CA:TRUE
Add a flag to certmonger::resubmit_request to specify that a
CA is being requested.
Note that this also sets pathlen to -1 which means an unlimited
pathlen. Leave it up to the issuing CA to set this.
https://pagure.io/freeipa/issue/7088
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
 ipalib/install/certmonger.py           | 13 +++++++++++--
 ipaserver/install/ipa_cacert_manage.py |  3 ++-
 2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/ipalib/install/certmonger.py b/ipalib/install/certmonger.py
index c286996ee2318e241b4af190d1a01f42e28aa9f3..d2b782ddb0c746a3dfd96d0222bb31c6a960fdff 100644
--- a/ipalib/install/certmonger.py
+++ b/ipalib/install/certmonger.py
@@ -519,16 +519,25 @@ def modify(request_id, ca=None, profile=None):
         request.obj_if.modify(update)
-def resubmit_request(request_id, ca=None, profile=None):
+def resubmit_request(request_id, ca=None, profile=None, is_ca=False):
+    """
+    :param request_id: the certmonger numeric request ID
+    :param ca: the nickname for the certmonger CA, e.g. IPA or SelfSign
+    :param profile: the dogtag template profile to use, e.g. SubCA
+    :param is_ca: boolean that if True adds the CA basic constraint
+    """
     request = _get_request({'nickname': request_id})
     if request:
-        if ca or profile:
+        if ca or profile or is_ca:
             update = {}
             if ca is not None:
                 cm = _certmonger()
                 update['CA'] = cm.obj_if.find_ca_by_nickname(ca)
             if profile is not None:
                 update['template-profile'] = profile
+            if is_ca:
+                update['template-is-ca'] = True
+                update['template-ca-path-length'] = -1  # no path length
             request.obj_if.modify(update)
         request.obj_if.resubmit()
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index fcbf09155a3abc9ce9481aa2519ed39aaa6aa9bb..9607620d6c3e63b70b9e586f94282bf478c8c53e 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -310,7 +310,8 @@ class CACertManage(admintool.AdminTool):
         timeout = api.env.startup_timeout + 60
         self.log.debug("resubmitting certmonger request '%s'", self.request_id)
-        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile)
+        certmonger.resubmit_request(self.request_id, ca=ca, profile=profile,
+                                    is_ca=True)
         try:
             state = certmonger.wait_for_request(self.request_id, timeout)
         except RuntimeError:
--
2.9.5
SOURCES/0006-tasks-run-systemctl-daemon-reload-after-httpd.servic.patch
File was deleted
SOURCES/0007-ipa-extdom-extop-refactor-nsswitch-operations.patch
New file
@@ -0,0 +1,1728 @@
From 8a80363e07b5c9309d785bf3b41f506f32a750a5 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 14 Nov 2017 12:44:02 +0200
Subject: [PATCH] ipa-extdom-extop: refactor nsswitch operations
Refactor nsswitch operations in ipa-extdom-extop plugin to allow use
of timeout-enabled nsswitch calls provided by libsss_nss_idmap.
Standard POSIX nsswitch API has no way to cancel requests which may
cause ipa-extdom-extop requests to hang far too long and potentially
exhaust LDAP server workers. In addition, glibc nsswitch API iterates
through all nsswitch modules one by one and with multiple parallel
requests a lock up may happen in an unrelated nsswitch module like
nss_files.so.2.
A solution to the latter issue is to directly load nss_sss.so.2 plugin
and utilize it. This, however, does not solve a problem with lack of
cancellable API.
With SSSD 1.16.1, libsss_nss_idmap provides a timeout-enabled variant of
nsswitch API that is directly integrated with SSSD client side machinery
used by nss_sss.so.2. As result, this API can be used instead of loading
nss_sss.so.2 directly.
To support older SSSD version, both direct loading of nss_sss.so.2 and
new timeout-enabled API are supported by this changeset. An API to
abstract both is designed to be a mix between internal glibc nsswitch
API and external nsswitch API that libsss_nss_idmap mimics. API does not
expose per-call timeout. Instead, it allows to set a timeout per
nsswitch operation context to reduce requirements on information
a caller has to maintain.
A choice which API to use is made at configure time.
In order to test the API, a cmocka test is updated to explicitly load
nss_files.so.2 as a backend. Since use of nss_sss.so.2 would always
depend on availablility of SSSD, predictable testing would not be
possible without it otherwise. Also, cmocka test does not use
nss_wrapper anymore because nss_wrapper overrides higher level glibc
nsswitch API while we are loading an individual nsswitch module
directly.
As result, cmocka test overrides fopen() call used by nss_files.so.2 to
load /etc/passwd and /etc/group. An overridden version changes paths to
/etc/passwd and /etc/group to a local test_data/passwd and
test_data/group. This way we can continue testing a backend API for
ipa-extdom-extop with the same data as with nss_wrapper.
Fixes https://pagure.io/freeipa/issue/5464
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Simo Sorce <ssorce@redhat.com>
Reviewed-By: Robbie Harwood <rharwood@redhat.com>
---
 configure.ac                                       |  25 +-
 .../ipa-slapi-plugins/ipa-extdom-extop/Makefile.am |  17 +-
 .../ipa-extdom-extop/back_extdom.h                 |  79 ++++++
 .../ipa-extdom-extop/back_extdom_nss_sss.c         | 276 +++++++++++++++++++++
 .../ipa-extdom-extop/back_extdom_sss_idmap.c       | 260 +++++++++++++++++++
 .../ipa-extdom-extop/ipa_extdom.h                  |  13 +-
 .../ipa-extdom-extop/ipa_extdom_cmocka_tests.c     | 241 +++++++++++++++---
 .../ipa-extdom-extop/ipa_extdom_common.c           | 242 +++++++++---------
 .../ipa-extdom-extop/ipa_extdom_extop.c            |  17 ++
 .../ipa-extdom-extop/test_data/test_setup.sh       |   3 -
 freeipa.spec.in                                    |   1 -
 server.m4                                          |  10 +
 12 files changed, 994 insertions(+), 190 deletions(-)
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
 delete mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
diff --git a/configure.ac b/configure.ac
index e7a8b11153209fdfb4903cd3876e21a871a92f03..8a99b028886790aca211ddf164772920221f3ec7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,30 +140,6 @@ PKG_CHECK_EXISTS(cmocka,
 )
 AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
-dnl A macro to check presence of a cwrap (http://cwrap.org) wrapper on the system
-dnl Usage:
-dnl     AM_CHECK_WRAPPER(name, conditional)
-dnl If the cwrap library is found, sets the HAVE_$name conditional
-AC_DEFUN([AM_CHECK_WRAPPER],
-[
-    FOUND_WRAPPER=0
-
-    AC_MSG_CHECKING([for $1])
-    PKG_CHECK_EXISTS([$1],
-                     [
-                        AC_MSG_RESULT([yes])
-                        FOUND_WRAPPER=1
-                     ],
-                     [
-                        AC_MSG_RESULT([no])
-                        AC_MSG_WARN([cwrap library $1 not found, some tests will not run])
-                     ])
-
-    AM_CONDITIONAL($2, [ test x$FOUND_WRAPPER = x1])
-])
-
-AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER)
-
 dnl ---------------------------------------------------------------------------
 dnl - Check for POPT
 dnl ---------------------------------------------------------------------------
@@ -235,6 +211,7 @@ dnl ---------------------------------------------------------------------------
 AM_COND_IF([ENABLE_SERVER], [
     m4_include(server.m4)
 ])
+AM_CONDITIONAL([USE_SSS_NSS_TIMEOUT], [test "x$ac_cv_have_decl_sss_nss_getpwnam_timeout" = xyes])
 dnl ---------------------------------------------------------------------------
 dnl - Check if IPA certauth plugin can be build
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
index 1213965c96607bf14c6c92ce592585aed1a125db..cbdd570eabeb12b95fdc26213a64749f9ba9fdde 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
@@ -25,6 +25,7 @@ libipa_extdom_extop_la_SOURCES =     \
     ipa_extdom.h            \
     ipa_extdom_extop.c        \
     ipa_extdom_common.c        \
+    back_extdom.h            \
     $(NULL)
 libipa_extdom_extop_la_LDFLAGS = -avoid-version
@@ -34,20 +35,29 @@ libipa_extdom_extop_la_LIBADD =     \
     $(SSSNSSIDMAP_LIBS)        \
     $(NULL)
+# We have two backends for nss operations:
+# (1) directly loading nss_sss.so.2
+# (2) using timeout-enabled API from libsss_nss_idmap
+# We prefer (2) if available
+if USE_SSS_NSS_TIMEOUT
+libipa_extdom_extop_la_SOURCES += back_extdom_sss_idmap.c
+else
+libipa_extdom_extop_la_SOURCES += back_extdom_nss_sss.c
+endif
+
+
 TESTS =
 check_PROGRAMS =
 if HAVE_CMOCKA
-if HAVE_NSS_WRAPPER
-TESTS_ENVIRONMENT = . ./test_data/test_setup.sh;
 TESTS += extdom_cmocka_tests
 check_PROGRAMS += extdom_cmocka_tests
 endif
-endif
 extdom_cmocka_tests_SOURCES =         \
     ipa_extdom_cmocka_tests.c    \
     ipa_extdom_common.c        \
+    back_extdom_nss_sss.c        \
     $(NULL)
 extdom_cmocka_tests_CFLAGS = $(CMOCKA_CFLAGS)
 extdom_cmocka_tests_LDFLAGS =     \
@@ -58,6 +68,7 @@ extdom_cmocka_tests_LDADD =     \
     $(LDAP_LIBS)        \
     $(DIRSRV_LIBS)        \
     $(SSSNSSIDMAP_LIBS)    \
+    -ldl            \
     $(NULL)
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2937c8c8ecf8b960b5b31e9449c719bfda86de4
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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, write to the
+ *
+ *   Free Software Foundation, Inc.
+ *   59 Temple Place, Suite 330
+ *   Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef BACK_EXTDOM_H
+#define BACK_EXTDOM_H
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+
+/* Possible results of lookup using a nss_* function.
+ * Note: don't include nss.h as its path gets overriden by NSS library */
+enum nss_status {
+    NSS_STATUS_TRYAGAIN = -2,
+    NSS_STATUS_UNAVAIL,
+    NSS_STATUS_NOTFOUND,
+    NSS_STATUS_SUCCESS,
+    NSS_STATUS_RETURN
+};
+
+/* NSS backend operations implemented using either nss_sss.so.2 or libsss_nss_idmap API */
+struct nss_ops_ctx;
+
+int back_extdom_init_context(struct nss_ops_ctx **nss_context);
+void back_extdom_free_context(struct nss_ops_ctx **nss_context);
+void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
+                             unsigned int timeout);
+void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
+                            const char *name);
+void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
+                             const char *name);
+
+enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno);
+
+enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
+                                     uid_t uid, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno);
+
+enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno);
+
+enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
+                                     gid_t gid, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno);
+
+enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
+                                         const char *name, gid_t group,
+                                         gid_t *groups, int *ngroups,
+                                         int *lerrno);
+
+#endif /* BACK_EXTDOM_H */
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
new file mode 100644
index 0000000000000000000000000000000000000000..346c7d4301a607c7bc07ca5a9c53fe84618ac8ad
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_nss_sss.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2013-2017 Red Hat, Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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, write to the
+ *
+ *   Free Software Foundation, Inc.
+ *   59 Temple Place, Suite 330
+ *   Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/param.h>
+#include "back_extdom.h"
+
+struct nss_ops_ctx {
+    void *dl_handle;
+    long int initgroups_start;
+
+    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
+                                      long int *start, long int *size,
+                                      gid_t **groups, long int limit,
+                                      int *errnop);
+};
+
+void back_extdom_free_context(struct nss_ops_ctx **nss_context)
+{
+    if ((nss_context == NULL) || (*nss_context == NULL)) {
+        return;
+    }
+
+    if ((*nss_context)->dl_handle != NULL) {
+        dlclose((*nss_context)->dl_handle);
+    }
+
+    free((*nss_context));
+    *nss_context = NULL;
+}
+
+int back_extdom_init_context(struct nss_ops_ctx **nss_context)
+{
+    struct nss_ops_ctx *ctx = NULL;
+
+    if (nss_context == NULL) {
+        return EINVAL;
+    }
+
+    ctx = calloc(1, sizeof(struct nss_ops_ctx));
+    if (ctx == NULL) {
+        return ENOMEM;
+    }
+    *nss_context = ctx;
+
+    ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
+    if (ctx->dl_handle == NULL) {
+        goto fail;
+    }
+
+    ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r");
+    if (ctx->getpwnam_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r");
+    if (ctx->getpwuid_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r");
+    if (ctx->getgrnam_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r");
+    if (ctx->getgrgid_r == NULL) {
+        goto fail;
+    }
+
+    ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn");
+    if (ctx->initgroups_dyn == NULL) {
+        goto fail;
+    }
+
+    return 0;
+
+fail:
+    back_extdom_free_context(nss_context);
+
+    return EINVAL;
+}
+
+
+/* Following three functions cannot be implemented with nss_sss.so.2
+ * As result, we simply do nothing here */
+
+void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
+                             unsigned int timeout) {
+        /* no operation */
+}
+
+void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
+                            const char *name) {
+        /* no operation */
+}
+
+void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
+                             const char *name) {
+        /* no operation */
+}
+
+enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno) {
+    enum nss_status ret;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = nss_context->getpwnam_r(name, pwd,
+                                  buffer, buflen,
+                                  lerrno);
+
+    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
+        *result = pwd;
+        *lerrno = 0;
+    }
+
+    return ret;
+}
+
+enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
+                                     uid_t uid, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno) {
+    enum nss_status ret;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = nss_context->getpwuid_r(uid, pwd,
+                                  buffer, buflen,
+                                  lerrno);
+
+    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
+        *result = pwd;
+        *lerrno = 0;
+    }
+
+    return ret;
+}
+
+enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno) {
+    enum nss_status ret;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = nss_context->getgrnam_r(name, grp,
+                                  buffer, buflen,
+                                  lerrno);
+
+    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
+        *result = grp;
+        *lerrno = 0;
+    }
+
+    return ret;
+}
+
+enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
+                                     gid_t gid, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno) {
+
+    enum nss_status ret;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = nss_context->getgrgid_r(gid, grp,
+                                  buffer, buflen,
+                                  lerrno);
+
+    if ((ret == NSS_STATUS_SUCCESS) && (result != NULL)) {
+        *result = grp;
+        *lerrno = 0;
+    }
+
+    return ret;
+}
+
+enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
+                                         const char *name, gid_t group,
+                                         gid_t *groups, int *ngroups,
+                                         int *lerrno) {
+
+    enum nss_status ret = NSS_STATUS_UNAVAIL;
+    long int tsize = MAX (1, *ngroups);
+    gid_t *newgroups = NULL;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    newgroups = (gid_t *) calloc (tsize, sizeof (gid_t));
+    if (newgroups == NULL) {
+        *lerrno = ENOMEM;
+        return NSS_STATUS_TRYAGAIN;
+    }
+
+    newgroups[0] = group;
+    nss_context->initgroups_start = 1;
+
+    ret = nss_context->initgroups_dyn(name, group,
+                                      &nss_context->initgroups_start,
+                                      &tsize, &newgroups,
+                                      -1, lerrno);
+
+    (void) memcpy(groups, newgroups,
+                  MIN(*ngroups, nss_context->initgroups_start) * sizeof(gid_t));
+    free(newgroups);
+
+    if (*ngroups < nss_context->initgroups_start) {
+        ret = NSS_STATUS_TRYAGAIN;
+        *lerrno = ERANGE;
+    }
+
+    *ngroups = (int) nss_context->initgroups_start;
+
+    nss_context->initgroups_start = 0;
+
+    return ret;
+}
+
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
new file mode 100644
index 0000000000000000000000000000000000000000..89c58ca2de333b26954d916836b57aed5d7e18fb
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/back_extdom_sss_idmap.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2013-2017 Red Hat, Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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, write to the
+ *
+ *   Free Software Foundation, Inc.
+ *   59 Temple Place, Suite 330
+ *   Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include "back_extdom.h"
+
+/* SSSD only exposes *_timeout() variants if the following symbol is defined */
+#define IPA_389DS_PLUGIN_HELPER_CALLS
+#include <sss_nss_idmap.h>
+
+struct nss_ops_ctx {
+    unsigned int timeout;
+};
+
+static enum nss_status __convert_sss_nss2nss_status(int errcode) {
+    switch(errcode) {
+    case 0:
+        return NSS_STATUS_SUCCESS;
+    case ENOENT:
+        return NSS_STATUS_NOTFOUND;
+    case ETIME:
+        /* fall-through */
+    case ERANGE:
+        return NSS_STATUS_TRYAGAIN;
+    case ETIMEDOUT:
+        /* fall-through */
+    default:
+        return NSS_STATUS_UNAVAIL;
+    }
+    return NSS_STATUS_UNAVAIL;
+}
+
+int back_extdom_init_context(struct nss_ops_ctx **nss_context)
+{
+    struct nss_ops_ctx *ctx = NULL;
+
+    if (nss_context == NULL) {
+        return EINVAL;
+    }
+
+    ctx = calloc(1, sizeof(struct nss_ops_ctx));
+
+    if (ctx == NULL) {
+        return ENOMEM;
+    }
+    *nss_context = ctx;
+    return 0;
+}
+
+void back_extdom_free_context(struct nss_ops_ctx **nss_context)
+{
+    if ((nss_context == NULL) || (*nss_context == NULL)) {
+        return;
+    }
+
+    free((*nss_context));
+    *nss_context = NULL;
+}
+
+
+void back_extdom_set_timeout(struct nss_ops_ctx *nss_context,
+                             unsigned int timeout) {
+    if (nss_context == NULL) {
+        return;
+    }
+
+    nss_context->timeout = timeout;
+}
+
+void back_extdom_evict_user(struct nss_ops_ctx *nss_context,
+                            const char *name) {
+    if (nss_context == NULL) {
+        return;
+    }
+
+    (void) sss_nss_getpwnam_timeout(name, NULL,
+                                    NULL, 0,
+                                    NULL,
+                                    SSS_NSS_EX_FLAG_INVALIDATE_CACHE,
+                                    nss_context->timeout);
+}
+
+void back_extdom_evict_group(struct nss_ops_ctx *nss_context,
+                             const char *name) {
+    if (nss_context == NULL) {
+            return;
+    }
+
+    (void) sss_nss_getgrnam_timeout(name, NULL,
+                                    NULL, 0,
+                                    NULL,
+                                    SSS_NSS_EX_FLAG_INVALIDATE_CACHE,
+                                    nss_context->timeout);
+}
+
+enum nss_status back_extdom_getpwnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno) {
+    int ret = 0;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = sss_nss_getpwnam_timeout(name, pwd,
+                                   buffer, buflen,
+                                   result,
+                                   SSS_NSS_EX_FLAG_NO_FLAGS,
+                                   nss_context->timeout);
+
+    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
+     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
+     * but writes down errno into return code so we propagate it in case
+     * of error and translate the return code */
+    if (lerrno != NULL) {
+        *lerrno = ret;
+    }
+    return __convert_sss_nss2nss_status(ret);
+}
+
+enum nss_status back_extdom_getpwuid(struct nss_ops_ctx *nss_context,
+                                     uid_t uid, struct passwd *pwd,
+                                     char *buffer, size_t buflen,
+                                     struct passwd **result,
+                                     int *lerrno) {
+
+    int ret = 0;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = sss_nss_getpwuid_timeout(uid, pwd,
+                                   buffer, buflen,
+                                   result,
+                                   SSS_NSS_EX_FLAG_NO_FLAGS,
+                                   nss_context->timeout);
+
+    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
+     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
+     * but writes down errno into return code so we propagate it in case
+     * of error and translate the return code */
+    if (lerrno != NULL) {
+        *lerrno = ret;
+    }
+    return __convert_sss_nss2nss_status(ret);
+}
+
+enum nss_status back_extdom_getgrnam(struct nss_ops_ctx *nss_context,
+                                     const char *name, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno) {
+
+    int ret = 0;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = sss_nss_getgrnam_timeout(name, grp,
+                                   buffer, buflen,
+                                   result,
+                                   SSS_NSS_EX_FLAG_NO_FLAGS,
+                                   nss_context->timeout);
+
+    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
+     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
+     * but writes down errno into return code so we propagate it in case
+     * of error and translate the return code */
+    if (lerrno != NULL) {
+        *lerrno = ret;
+    }
+    return __convert_sss_nss2nss_status(ret);
+}
+
+enum nss_status back_extdom_getgrgid(struct nss_ops_ctx *nss_context,
+                                     gid_t gid, struct group *grp,
+                                     char *buffer, size_t buflen,
+                                     struct group **result,
+                                     int *lerrno) {
+
+    int ret = 0;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = sss_nss_getgrgid_timeout(gid, grp,
+                                   buffer, buflen,
+                                   result,
+                                   SSS_NSS_EX_FLAG_NO_FLAGS,
+                                   nss_context->timeout);
+
+    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
+     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
+     * but writes down errno into return code so we propagate it in case
+     * of error and translate the return code */
+    if (lerrno != NULL) {
+        *lerrno = ret;
+    }
+    return __convert_sss_nss2nss_status(ret);
+}
+
+enum nss_status back_extdom_getgrouplist(struct nss_ops_ctx *nss_context,
+                                         const char *name, gid_t group,
+                                         gid_t *groups, int *ngroups,
+                                         int *lerrno) {
+    int ret = 0;
+
+    if (nss_context == NULL) {
+        return NSS_STATUS_UNAVAIL;
+    }
+
+    ret = sss_nss_getgrouplist_timeout(name, group,
+                                       groups, ngroups,
+                                       SSS_NSS_EX_FLAG_NO_FLAGS,
+                                       nss_context->timeout);
+
+    /* SSSD uses the same infrastructure to handle sss_nss_get* calls
+     * as nss_sss.so.2 module where 'int *errno' is passed to the helper
+     * but writes down errno into return code so we propagate it in case
+     * of error and translate the return code */
+    if (lerrno != NULL) {
+        *lerrno = ret;
+    }
+    return __convert_sss_nss2nss_status(ret);
+}
+
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
index bc29f069816b0ce13578c9ae14c61edb832d44e4..bbc574747e8bbe045dfc9882198cb34b0bb8cab9 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
@@ -150,10 +150,13 @@ struct extdom_res {
     } data;
 };
+struct nss_ops_ctx;
+
 struct ipa_extdom_ctx {
     Slapi_ComponentId *plugin_id;
     char *base_dn;
     size_t max_nss_buf_size;
+    struct nss_ops_ctx *nss_ctx;
 };
 struct domain_info {
@@ -179,15 +182,15 @@ int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req,
                    struct berval **berval);
 int pack_response(struct extdom_res *res, struct berval **ret_val);
 int get_buffer(size_t *_buf_len, char **_buf);
-int getpwnam_r_wrapper(size_t buf_max, const char *name,
+int getpwnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
                        struct passwd *pwd, char **_buf, size_t *_buf_len);
-int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
+int getpwuid_r_wrapper(struct ipa_extdom_ctx *ctx, uid_t uid,
                        struct passwd *pwd, char **_buf, size_t *_buf_len);
-int getgrnam_r_wrapper(size_t buf_max, const char *name,
+int getgrnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
                        struct group *grp, char **_buf, size_t *_buf_len);
-int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
+int getgrgid_r_wrapper(struct ipa_extdom_ctx *ctx, gid_t gid,
                        struct group *grp, char **_buf, size_t *_buf_len);
-int get_user_grouplist(const char *name, gid_t gid,
+int get_user_grouplist(struct ipa_extdom_ctx *ctx, const char *name, gid_t gid,
                        size_t *_ngroups, gid_t **_groups);
 int pack_ber_sid(const char *sid, struct berval **berval);
 int pack_ber_name(const char *domain_name, const char *name,
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
index 526f903d2416e62ee5781909c234bd5ee2d89183..29699cfa390f5469d7c009388b90e68616cbf984 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
@@ -19,6 +19,7 @@
     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#define _GNU_SOURCE
 #include <errno.h>
 #include <stdarg.h>
@@ -31,24 +32,166 @@
 #include "ipa_extdom.h"
+#include "back_extdom.h"
+#include <stdio.h>
+#include <dlfcn.h>
 #define MAX_BUF (1024*1024*1024)
+struct test_data {
+    struct extdom_req *req;
+    struct ipa_extdom_ctx *ctx;
+};
+
+/*
+ * redefine logging for mocks
+ */
+#ifdef __GNUC__
+    __attribute__((format(printf, 3, 4)))
+#endif
+int slapi_log_error(int loglevel, char *subsystem, char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprint_error(fmt, ap);
+    va_end(ap);
+    return 0;
+}
+
+
+/*
+ * We cannot run cmocka tests against SSSD as that would require to set up SSSD
+ * and the rest of environment. Instead, we compile cmocka tests against
+ * back_extdom_nss_sss.c and re-define context initialization to use
+ * nsswrapper with our test data.
+ *
+ * This means we have to keep struct nss_ops_ctx definition in sync with tests!
+ */
+
+struct nss_ops_ctx {
+    void *dl_handle;
+    long int initgroups_start;
+
+    enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getgrnam_r)(const char *name, struct group *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
+                                  char *buffer, size_t buflen, int *errnop);
+    enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
+                                      long int *start, long int *size,
+                                      gid_t **groups, long int limit,
+                                      int *errnop);
+};
+
+int cmocka_extdom_init_context(struct nss_ops_ctx **nss_context)
+{
+    struct nss_ops_ctx *ctx = NULL;
+
+    if (nss_context == NULL) {
+        return -1;
+    }
+
+    ctx = calloc(1, sizeof(struct nss_ops_ctx));
+
+    if (ctx == NULL) {
+        return ENOMEM;
+    }
+    *nss_context = ctx;
+
+    ctx->dl_handle = dlopen("libnss_files.so.2", RTLD_NOW);
+    if (ctx->dl_handle == NULL) {
+        goto fail;
+    }
+
+    ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_files_getpwnam_r");
+    if (ctx->getpwnam_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_files_getpwuid_r");
+    if (ctx->getpwuid_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_files_getgrnam_r");
+    if (ctx->getgrnam_r == NULL) {
+        goto fail;
+    }
+
+    ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_files_getgrgid_r");
+    if (ctx->getgrgid_r == NULL) {
+        goto fail;
+    }
+
+    ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_files_initgroups_dyn");
+    if (ctx->initgroups_dyn == NULL) {
+        goto fail;
+    }
+
+    return 0;
+
+fail:
+    back_extdom_free_context(nss_context);
+
+    return -1;
+}
+
+struct {
+    const char *o, *n;
+} path_table[] = {
+    { .o = "/etc/passwd", .n = "./test_data/passwd"},
+    { .o = "/etc/group",  .n = "./test_data/group"},
+    { .o = NULL, .n = NULL}};
+
+FILE *(*original_fopen)(const char*, const char*) = NULL;
+
+FILE *fopen(const char *path, const char *mode) {
+    const char *_path = NULL;
+
+    /* Do not handle before-main() cases */
+    if (original_fopen == NULL) {
+        return NULL;
+    }
+    for(int i=0; path_table[i].o != NULL; i++) {
+        if (strcmp(path, path_table[i].o) == 0) {
+                _path = path_table[i].n;
+                break;
+        }
+    }
+    return (*original_fopen)(_path ? _path : path, mode);
+}
+
+/* Attempt to initialize original_fopen before main()
+ * There is no explicit order when all initializers are called,
+ * so we might still be late here compared to a code in a shared
+ * library initializer, like libselinux */
+void redefined_fopen_ctor (void) __attribute__ ((constructor));
+void redefined_fopen_ctor(void) {
+    original_fopen = dlsym(RTLD_NEXT, "fopen");
+}
 void test_getpwnam_r_wrapper(void **state)
 {
     int ret;
     struct passwd pwd;
     char *buf;
-    size_t buf_len;
+    size_t buf_len, max_big_buf_len;
+    struct test_data *test_data;
+
+    test_data = (struct test_data *) *state;
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwnam_r_wrapper(MAX_BUF, "non_exisiting_user", &pwd, &buf,
-                             &buf_len);
+    ret = getpwnam_r_wrapper(test_data->ctx,
+                             "non_exisiting_user", &pwd,
+                             &buf, &buf_len);
     assert_int_equal(ret, ENOENT);
-    ret = getpwnam_r_wrapper(MAX_BUF, "user", &pwd, &buf, &buf_len);
+    ret = getpwnam_r_wrapper(test_data->ctx,
+                             "user", &pwd, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(pwd.pw_name, "user");
     assert_string_equal(pwd.pw_passwd, "x");
@@ -62,7 +205,8 @@ void test_getpwnam_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwnam_r_wrapper(MAX_BUF, "user_big", &pwd, &buf, &buf_len);
+    ret = getpwnam_r_wrapper(test_data->ctx,
+                             "user_big", &pwd, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(pwd.pw_name, "user_big");
     assert_string_equal(pwd.pw_passwd, "x");
@@ -76,7 +220,11 @@ void test_getpwnam_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwnam_r_wrapper(1024, "user_big", &pwd, &buf, &buf_len);
+    max_big_buf_len = test_data->ctx->max_nss_buf_size;
+    test_data->ctx->max_nss_buf_size = 1024;
+    ret = getpwnam_r_wrapper(test_data->ctx,
+                             "user_big", &pwd, &buf, &buf_len);
+    test_data->ctx->max_nss_buf_size = max_big_buf_len;
     assert_int_equal(ret, ERANGE);
     free(buf);
 }
@@ -86,15 +234,18 @@ void test_getpwuid_r_wrapper(void **state)
     int ret;
     struct passwd pwd;
     char *buf;
-    size_t buf_len;
+    size_t buf_len, max_big_buf_len;
+    struct test_data *test_data;
+
+    test_data = (struct test_data *) *state;
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwuid_r_wrapper(MAX_BUF, 99999, &pwd, &buf, &buf_len);
+    ret = getpwuid_r_wrapper(test_data->ctx, 99999, &pwd, &buf, &buf_len);
     assert_int_equal(ret, ENOENT);
-    ret = getpwuid_r_wrapper(MAX_BUF, 12345, &pwd, &buf, &buf_len);
+    ret = getpwuid_r_wrapper(test_data->ctx, 12345, &pwd, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(pwd.pw_name, "user");
     assert_string_equal(pwd.pw_passwd, "x");
@@ -108,7 +259,7 @@ void test_getpwuid_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwuid_r_wrapper(MAX_BUF, 12346, &pwd, &buf, &buf_len);
+    ret = getpwuid_r_wrapper(test_data->ctx, 12346, &pwd, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(pwd.pw_name, "user_big");
     assert_string_equal(pwd.pw_passwd, "x");
@@ -122,7 +273,10 @@ void test_getpwuid_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getpwuid_r_wrapper(1024, 12346, &pwd, &buf, &buf_len);
+    max_big_buf_len = test_data->ctx->max_nss_buf_size;
+    test_data->ctx->max_nss_buf_size = 1024;
+    ret = getpwuid_r_wrapper(test_data->ctx, 12346, &pwd, &buf, &buf_len);
+    test_data->ctx->max_nss_buf_size = max_big_buf_len;
     assert_int_equal(ret, ERANGE);
     free(buf);
 }
@@ -132,15 +286,19 @@ void test_getgrnam_r_wrapper(void **state)
     int ret;
     struct group grp;
     char *buf;
-    size_t buf_len;
+    size_t buf_len, max_big_buf_len;
+    struct test_data *test_data;
+
+    test_data = (struct test_data *) *state;
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrnam_r_wrapper(MAX_BUF, "non_exisiting_group", &grp, &buf, &buf_len);
+    ret = getgrnam_r_wrapper(test_data->ctx,
+                             "non_exisiting_group", &grp, &buf, &buf_len);
     assert_int_equal(ret, ENOENT);
-    ret = getgrnam_r_wrapper(MAX_BUF, "group", &grp, &buf, &buf_len);
+    ret = getgrnam_r_wrapper(test_data->ctx, "group", &grp, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(grp.gr_name, "group");
     assert_string_equal(grp.gr_passwd, "x");
@@ -153,7 +311,7 @@ void test_getgrnam_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrnam_r_wrapper(MAX_BUF, "group_big", &grp, &buf, &buf_len);
+    ret = getgrnam_r_wrapper(test_data->ctx, "group_big", &grp, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(grp.gr_name, "group_big");
     assert_string_equal(grp.gr_passwd, "x");
@@ -165,7 +323,10 @@ void test_getgrnam_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrnam_r_wrapper(1024, "group_big", &grp, &buf, &buf_len);
+    max_big_buf_len = test_data->ctx->max_nss_buf_size;
+    test_data->ctx->max_nss_buf_size = 1024;
+    ret = getgrnam_r_wrapper(test_data->ctx, "group_big", &grp, &buf, &buf_len);
+    test_data->ctx->max_nss_buf_size = max_big_buf_len;
     assert_int_equal(ret, ERANGE);
     free(buf);
 }
@@ -175,15 +336,18 @@ void test_getgrgid_r_wrapper(void **state)
     int ret;
     struct group grp;
     char *buf;
-    size_t buf_len;
+    size_t buf_len, max_big_buf_len;
+    struct test_data *test_data;
+
+    test_data = (struct test_data *) *state;
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrgid_r_wrapper(MAX_BUF, 99999, &grp, &buf, &buf_len);
+    ret = getgrgid_r_wrapper(test_data->ctx, 99999, &grp, &buf, &buf_len);
     assert_int_equal(ret, ENOENT);
-    ret = getgrgid_r_wrapper(MAX_BUF, 11111, &grp, &buf, &buf_len);
+    ret = getgrgid_r_wrapper(test_data->ctx, 11111, &grp, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(grp.gr_name, "group");
     assert_string_equal(grp.gr_passwd, "x");
@@ -196,7 +360,7 @@ void test_getgrgid_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrgid_r_wrapper(MAX_BUF, 22222, &grp, &buf, &buf_len);
+    ret = getgrgid_r_wrapper(test_data->ctx, 22222, &grp, &buf, &buf_len);
     assert_int_equal(ret, 0);
     assert_string_equal(grp.gr_name, "group_big");
     assert_string_equal(grp.gr_passwd, "x");
@@ -208,7 +372,10 @@ void test_getgrgid_r_wrapper(void **state)
     ret = get_buffer(&buf_len, &buf);
     assert_int_equal(ret, 0);
-    ret = getgrgid_r_wrapper(1024, 22222, &grp, &buf, &buf_len);
+    max_big_buf_len = test_data->ctx->max_nss_buf_size;
+    test_data->ctx->max_nss_buf_size = 1024;
+    ret = getgrgid_r_wrapper(test_data->ctx, 22222, &grp, &buf, &buf_len);
+    test_data->ctx->max_nss_buf_size = max_big_buf_len;
     assert_int_equal(ret, ERANGE);
     free(buf);
 }
@@ -219,16 +386,21 @@ void test_get_user_grouplist(void **state)
     size_t ngroups;
     gid_t *groups;
     size_t c;
+    struct test_data *test_data;
+
+    test_data = (struct test_data *) *state;
     /* This is a bit odd behaviour of getgrouplist() it does not check if the
      * user exists, only if memberships of the user can be found. */
-    ret = get_user_grouplist("non_exisiting_user", 23456, &ngroups, &groups);
+    ret = get_user_grouplist(test_data->ctx,
+                             "non_exisiting_user", 23456, &ngroups, &groups);
     assert_int_equal(ret, LDAP_SUCCESS);
     assert_int_equal(ngroups, 1);
     assert_int_equal(groups[0], 23456);
     free(groups);
-    ret = get_user_grouplist("member0001", 23456, &ngroups, &groups);
+    ret = get_user_grouplist(test_data->ctx,
+                             "member0001", 23456, &ngroups, &groups);
     assert_int_equal(ret, LDAP_SUCCESS);
     assert_int_equal(ngroups, 3);
     assert_int_equal(groups[0], 23456);
@@ -236,14 +408,16 @@ void test_get_user_grouplist(void **state)
     assert_int_equal(groups[2], 22222);
     free(groups);
-    ret = get_user_grouplist("member0003", 23456, &ngroups, &groups);
+    ret = get_user_grouplist(test_data->ctx,
+                             "member0003", 23456, &ngroups, &groups);
     assert_int_equal(ret, LDAP_SUCCESS);
     assert_int_equal(ngroups, 2);
     assert_int_equal(groups[0], 23456);
     assert_int_equal(groups[1], 22222);
     free(groups);
-    ret = get_user_grouplist("user_big", 23456, &ngroups, &groups);
+    ret = get_user_grouplist(test_data->ctx,
+                             "user_big", 23456, &ngroups, &groups);
     assert_int_equal(ret, LDAP_SUCCESS);
     assert_int_equal(ngroups, 1001);
     assert_int_equal(groups[0], 23456);
@@ -253,11 +427,6 @@ void test_get_user_grouplist(void **state)
     free(groups);
 }
-struct test_data {
-    struct extdom_req *req;
-    struct ipa_extdom_ctx *ctx;
-};
-
 static int  extdom_req_setup(void **state)
 {
     struct test_data *test_data;
@@ -269,8 +438,14 @@ static int  extdom_req_setup(void **state)
     assert_non_null(test_data->req);
     test_data->ctx = calloc(sizeof(struct ipa_extdom_ctx), 1);
-    assert_non_null(test_data->req);
+    assert_non_null(test_data->ctx);
+
+    test_data->ctx->max_nss_buf_size = MAX_BUF;
+
+    assert_int_equal(cmocka_extdom_init_context(&test_data->ctx->nss_ctx), 0);
+    assert_non_null(test_data->ctx->nss_ctx);
+    back_extdom_set_timeout(test_data->ctx->nss_ctx, 10000);
     *state = test_data;
     return 0;
@@ -283,6 +458,7 @@ static int  extdom_req_teardown(void **state)
     test_data = (struct test_data *) *state;
     free_req_data(test_data->req);
+    back_extdom_free_context(&test_data->ctx->nss_ctx);
     free(test_data->ctx);
     free(test_data);
@@ -450,5 +626,6 @@ int main(int argc, const char *argv[])
         cmocka_unit_test(test_decode),
     };
-    return cmocka_run_group_tests(tests, NULL, NULL);
+    assert_non_null(original_fopen);
+    return cmocka_run_group_tests(tests, extdom_req_setup, extdom_req_teardown);
 }
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
index fe225fa86669a6728bec5014be41d80275f10717..86c6638ba73c2f59aff29191e3e68dc5c85d50fc 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
@@ -43,11 +43,12 @@
 #include <errno.h>
 #include <stdio.h>
+#include <sys/param.h>
 #include "ipa_extdom.h"
+#include "back_extdom.h"
 #include "util.h"
-#define MAX(a,b) (((a)>(b))?(a):(b))
 #define SSSD_DOMAIN_SEPARATOR '@'
 int get_buffer(size_t *_buf_len, char **_buf)
@@ -97,134 +98,137 @@ static int inc_buffer(size_t buf_max, size_t *_buf_len, char **_buf)
     return 0;
 }
-int getpwnam_r_wrapper(size_t buf_max, const char *name,
-                       struct passwd *pwd, char **_buf, size_t *_buf_len)
+int __nss_to_err(enum nss_status errcode)
 {
-    char *buf = NULL;
-    size_t buf_len = 0;
-    int ret;
-    struct passwd *result = NULL;
+    switch(errcode) {
+    case NSS_STATUS_SUCCESS:
+        return 0;
+    case NSS_STATUS_NOTFOUND:
+        return ENOENT;
+    case NSS_STATUS_TRYAGAIN:
+        return ERANGE;
+    case NSS_STATUS_UNAVAIL:
+        return ETIMEDOUT;
+    }
-    buf = *_buf;
-    buf_len = *_buf_len;
+    return -1;
+}
-    while (buf != NULL
-            && (ret = getpwnam_r(name, pwd, buf, buf_len, &result)) == ERANGE) {
-        ret = inc_buffer(buf_max, &buf_len, &buf);
-        if (ret != 0) {
-            if (ret == ERANGE) {
-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
-            }
-            goto done;
+int getpwnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
+                       struct passwd *pwd, char **buf, size_t *buf_len)
+{
+    int ret, lerrno = 0;
+    struct passwd *result = NULL;
+    enum nss_status rc;
+
+    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
+        rc = back_extdom_getpwnam(ctx->nss_ctx, name, pwd, *buf, *buf_len, &result, &lerrno);
+        ret = __nss_to_err(rc);
+        if (ret == ERANGE) {
+            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
+            if (ret != 0) goto done;
         }
     }
-    if (ret == 0 && result == NULL) {
-        ret = ENOENT;
-    }
-
 done:
-    *_buf = buf;
-    *_buf_len = buf_len;
-
+    switch(ret) {
+    case 0:
+        if (result == NULL) ret = ENOENT;
+        break;
+    case ERANGE:
+        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+    default:
+        break;
+    }
     return ret;
 }
-int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
-                       struct passwd *pwd, char **_buf, size_t *_buf_len)
+int getpwuid_r_wrapper(struct ipa_extdom_ctx *ctx, uid_t uid,
+                       struct passwd *pwd, char **buf, size_t *buf_len)
 {
-    char *buf = NULL;
-    size_t buf_len = 0;
-    int ret;
+    int ret, lerrno;
     struct passwd *result = NULL;
-
-    buf = *_buf;
-    buf_len = *_buf_len;
-
-    while (buf != NULL
-            && (ret = getpwuid_r(uid, pwd, buf, buf_len, &result)) == ERANGE) {
-        ret = inc_buffer(buf_max, &buf_len, &buf);
-        if (ret != 0) {
-            if (ret == ERANGE) {
-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
-            }
-            goto done;
+    enum nss_status rc;
+
+    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
+        rc = back_extdom_getpwuid(ctx->nss_ctx, uid, pwd, *buf, *buf_len, &result, &lerrno);
+        ret = __nss_to_err(rc);
+        if (ret == ERANGE) {
+            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
+            if (ret != 0) goto done;
         }
     }
-    if (ret == 0 && result == NULL) {
-        ret = ENOENT;
-    }
-
 done:
-    *_buf = buf;
-    *_buf_len = buf_len;
+    switch(ret) {
+    case 0:
+        if (result == NULL) ret = ENOENT;
+        break;
+    case ERANGE:
+        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+    default:
+        break;
+    }
     return ret;
 }
-int getgrnam_r_wrapper(size_t buf_max, const char *name,
-                       struct group *grp, char **_buf, size_t *_buf_len)
+int getgrnam_r_wrapper(struct ipa_extdom_ctx *ctx, const char *name,
+                       struct group *grp, char **buf, size_t *buf_len)
 {
-    char *buf = NULL;
-    size_t buf_len = 0;
-    int ret;
+    int ret, lerrno;
     struct group *result = NULL;
-
-    buf = *_buf;
-    buf_len = *_buf_len;
-
-    while (buf != NULL
-            && (ret = getgrnam_r(name, grp, buf, buf_len, &result)) == ERANGE) {
-        ret = inc_buffer(buf_max, &buf_len, &buf);
-        if (ret != 0) {
-            if (ret == ERANGE) {
-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
-            }
-            goto done;
+    enum nss_status rc;
+
+    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
+        rc = back_extdom_getgrnam(ctx->nss_ctx, name, grp, *buf, *buf_len, &result, &lerrno);
+        ret = __nss_to_err(rc);
+        if (ret == ERANGE) {
+            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
+            if (ret != 0) goto done;
         }
     }
-    if (ret == 0 && result == NULL) {
-        ret = ENOENT;
-    }
-
 done:
-    *_buf = buf;
-    *_buf_len = buf_len;
+    switch(ret) {
+    case 0:
+        if (result == NULL) ret = ENOENT;
+        break;
+    case ERANGE:
+        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+    default:
+        break;
+    }
     return ret;
 }
-int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
-                       struct group *grp, char **_buf, size_t *_buf_len)
+int getgrgid_r_wrapper(struct ipa_extdom_ctx *ctx, gid_t gid,
+                       struct group *grp, char **buf, size_t *buf_len)
 {
-    char *buf = NULL;
-    size_t buf_len = 0;
-    int ret;
+    int ret, lerrno;
     struct group *result = NULL;
-
-    buf = *_buf;
-    buf_len = *_buf_len;
-
-    while (buf != NULL
-            && (ret = getgrgid_r(gid, grp, buf, buf_len, &result)) == ERANGE) {
-        ret = inc_buffer(buf_max, &buf_len, &buf);
-        if (ret != 0) {
-            if (ret == ERANGE) {
-                LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
-            }
-            goto done;
+    enum nss_status rc;
+
+    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
+        rc = back_extdom_getgrgid(ctx->nss_ctx, gid, grp, *buf, *buf_len, &result, &lerrno);
+        ret = __nss_to_err(rc);
+        if (ret == ERANGE) {
+            ret = inc_buffer(ctx->max_nss_buf_size, buf_len, buf);
+            if (ret != 0) goto done;
         }
     }
-    if (ret == 0 && result == NULL) {
-        ret = ENOENT;
-    }
-
 done:
-    *_buf = buf;
-    *_buf_len = buf_len;
+    switch(ret) {
+    case 0:
+        if (result == NULL) ret = ENOENT;
+        break;
+    case ERANGE:
+        LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
+    default:
+        break;
+    }
     return ret;
 }
@@ -406,13 +410,14 @@ int check_request(struct extdom_req *req, enum extdom_version version)
     return LDAP_SUCCESS;
 }
-int get_user_grouplist(const char *name, gid_t gid,
+int get_user_grouplist(struct ipa_extdom_ctx *ctx, const char *name, gid_t gid,
                        size_t *_ngroups, gid_t **_groups)
 {
-    int ret;
+    int lerrno;
     int ngroups;
     gid_t *groups;
     gid_t *new_groups;
+    enum nss_status rc;
     ngroups = 128;
     groups = malloc(ngroups * sizeof(gid_t));
@@ -420,19 +425,18 @@ int get_user_grouplist(const char *name, gid_t gid,
         return LDAP_OPERATIONS_ERROR;
     }
-    ret = getgrouplist(name, gid, groups, &ngroups);
-    if (ret == -1) {
-        new_groups = realloc(groups, ngroups * sizeof(gid_t));
-        if (new_groups == NULL) {
-            free(groups);
-            return LDAP_OPERATIONS_ERROR;
-        }
-        groups = new_groups;
-
-        ret = getgrouplist(name, gid, groups, &ngroups);
-        if (ret == -1) {
-            free(groups);
-            return LDAP_OPERATIONS_ERROR;
+    for(rc = NSS_STATUS_TRYAGAIN; rc == NSS_STATUS_TRYAGAIN;) {
+        rc = back_extdom_getgrouplist(ctx->nss_ctx, name, gid, groups, &ngroups, &lerrno);
+        if (rc == NSS_STATUS_TRYAGAIN) {
+            new_groups = NULL;
+            if (lerrno == ERANGE) {
+                new_groups = realloc(groups, ngroups * sizeof(gid_t));
+            }
+            if ((new_groups == NULL) || (lerrno == ENOMEM)) {
+                free(groups);
+                return LDAP_OPERATIONS_ERROR;
+            }
+            groups = new_groups;
         }
     }
@@ -538,7 +542,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
     }
     if (response_type == RESP_USER_GROUPLIST) {
-        ret = get_user_grouplist(user_name, gid, &ngroups, &groups);
+        ret = get_user_grouplist(ctx, user_name, gid, &ngroups, &groups);
         if (ret != LDAP_SUCCESS) {
             goto done;
         }
@@ -561,7 +565,7 @@ int pack_ber_user(struct ipa_extdom_ctx *ctx,
         }
         for (c = 0; c < ngroups; c++) {
-            ret = getgrgid_r_wrapper(ctx->max_nss_buf_size,
+            ret = getgrgid_r_wrapper(ctx,
                                      groups[c], &grp, &buf, &buf_len);
             if (ret != 0) {
                 if (ret == ENOMEM || ret == ERANGE) {
@@ -841,8 +845,7 @@ static int handle_uid_request(struct ipa_extdom_ctx *ctx,
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getpwuid_r_wrapper(ctx->max_nss_buf_size, uid, &pwd, &buf,
-                                 &buf_len);
+        ret = getpwuid_r_wrapper(ctx, uid, &pwd, &buf, &buf_len);
         if (ret != 0) {
             if (ret == ENOMEM || ret == ERANGE) {
                 ret = LDAP_OPERATIONS_ERROR;
@@ -913,8 +916,7 @@ static int handle_gid_request(struct ipa_extdom_ctx *ctx,
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getgrgid_r_wrapper(ctx->max_nss_buf_size, gid, &grp, &buf,
-                                 &buf_len);
+        ret = getgrgid_r_wrapper(ctx, gid, &grp, &buf, &buf_len);
         if (ret != 0) {
             if (ret == ENOMEM || ret == ERANGE) {
                 ret = LDAP_OPERATIONS_ERROR;
@@ -1053,8 +1055,7 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
     switch(id_type) {
     case SSS_ID_TYPE_UID:
     case SSS_ID_TYPE_BOTH:
-        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
-                                 &buf_len);
+        ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len);
         if (ret != 0) {
             if (ret == ENOMEM || ret == ERANGE) {
                 ret = LDAP_OPERATIONS_ERROR;
@@ -1086,8 +1087,7 @@ static int handle_sid_request(struct ipa_extdom_ctx *ctx,
                             pwd.pw_shell, kv_list, berval);
         break;
     case SSS_ID_TYPE_GID:
-        ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
-                                 &buf_len);
+        ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
         if (ret != 0) {
             if (ret == ENOMEM || ret == ERANGE) {
                 ret = LDAP_OPERATIONS_ERROR;
@@ -1181,8 +1181,7 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
             goto done;
         }
-        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
-                                 &buf_len);
+        ret = getpwnam_r_wrapper(ctx, fq_name, &pwd, &buf, &buf_len);
         if (ret == 0) {
             if (request_type == REQ_FULL_WITH_GROUPS) {
                 ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
@@ -1211,8 +1210,7 @@ static int handle_name_request(struct ipa_extdom_ctx *ctx,
              * error codes which can indicate that the user was not found. To
              * be on the safe side we fail back to the group lookup on all
              * errors. */
-            ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
-                                     &buf_len);
+            ret = getgrnam_r_wrapper(ctx, fq_name, &grp, &buf, &buf_len);
             if (ret != 0) {
                 if (ret == ENOMEM || ret == ERANGE) {
                     ret = LDAP_OPERATIONS_ERROR;
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
index 5bc8c2f571e311c5ae4cc56e2e1ae7d4e2f77ee6..83c30e7e6aad72af603c0b4ed1c49b80fa57560f 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
@@ -38,9 +38,11 @@
  * END COPYRIGHT BLOCK **/
 #include "ipa_extdom.h"
+#include "back_extdom.h"
 #include "util.h"
 #define DEFAULT_MAX_NSS_BUFFER (128*1024*1024)
+#define DEFAULT_MAX_NSS_TIMEOUT (10*1000)
 Slapi_PluginDesc ipa_extdom_plugin_desc = {
     IPA_EXTDOM_FEATURE_DESC,
@@ -166,6 +168,7 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
     struct ipa_extdom_ctx *ctx;
     Slapi_Entry *e;
     int ret;
+    unsigned int timeout;
     ctx = calloc(1, sizeof(struct ipa_extdom_ctx));
     if (!ctx) {
@@ -202,6 +205,20 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
     }
     LOG("Maximal nss buffer size set to [%zu]!\n", ctx->max_nss_buf_size);
+
+    ret = back_extdom_init_context(&ctx->nss_ctx);
+    if (ret != 0) {
+        LOG("Unable to initialize nss interface: returned [%d]!\n", ret);
+        goto done;
+    }
+
+    timeout = slapi_entry_attr_get_uint(e, "ipaExtdomMaxNssTimeout");
+    if (timeout == 0) {
+        timeout = DEFAULT_MAX_NSS_TIMEOUT;
+    }
+    back_extdom_set_timeout(ctx->nss_ctx, timeout);
+    LOG("Maximal nss timeout (in ms) set to [%u]!\n", timeout);
+
     ret = 0;
 done:
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
deleted file mode 100644
index ad839f340efe989a91cd6902f59c9a41483f68e0..0000000000000000000000000000000000000000
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-export LD_PRELOAD=$(pkg-config --libs nss_wrapper)
-export NSS_WRAPPER_PASSWD=./test_data/passwd
-export NSS_WRAPPER_GROUP=./test_data/group
diff --git a/freeipa.spec.in b/freeipa.spec.in
index a8b5ce81fcf9bdb61cd3707e6b68b6f2196e0776..80ae98c5515f64a8df8d981ad5e91b05c84e31c1 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -246,7 +246,6 @@ BuildRequires:  python3-augeas
 #
 %if ! %{ONLY_CLIENT}
 BuildRequires:  libcmocka-devel
-BuildRequires:  nss_wrapper
 # Required by ipa_kdb_tests
 BuildRequires:  %{_libdir}/krb5/plugins/kdb/db2.so
 %endif # ONLY_CLIENT
diff --git a/server.m4 b/server.m4
index a9670c87372bb7b92d08dad634c0bda123a02597..f0a8bbcc778596dade89d9332abb2939b8a44143 100644
--- a/server.m4
+++ b/server.m4
@@ -35,6 +35,16 @@ AC_CHECK_LIB([sss_nss_idmap],
              [AC_MSG_ERROR([Required sss_nss_getlistbycert symbol in sss_nss_idmap not found])],
              [])
+dnl --- if sss_nss_idmap provides _timeout() API, use it
+bck_cflags="$CFLAGS"
+CFLAGS="$CFLAGS -DIPA_389DS_PLUGIN_HELPER_CALLS"
+AC_CHECK_DECLS([sss_nss_getpwnam_timeout], [], [], [[#include <sss_nss_idmap.h>]])
+CFLAGS="$bck_cflags"
+
+if test "x$ac_cv_have_decl_sss_nss_getpwnam_timeout" = xyes ; then
+    AC_DEFINE(USE_SSS_NSS_TIMEOUT,1,[Use extended NSS API provided by SSSD])
+fi
+
 dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
 PKG_CHECK_EXISTS([sss_certmap],
                  [PKG_CHECK_MODULES([SSSCERTMAP], [sss_certmap])],
--
2.14.3
SOURCES/0007-man-ipa-cacert-manage-install-needs-clarification.patch
File was deleted
SOURCES/0008-Add-the-sub-operation-for-fqdn-index-config.patch
New file
@@ -0,0 +1,46 @@
From 8a1e04abede4c0bd5730781ef8c42c8a2e1bbcf9 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slaznick@redhat.com>
Date: Fri, 3 Nov 2017 09:23:10 +0100
Subject: [PATCH] Add the sub operation for fqdn index config
This should improve performance of the host-find command.
https://pagure.io/freeipa/issue/6371
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/share/indices.ldif        | 1 +
 install/updates/20-indices.update | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/install/share/indices.ldif b/install/share/indices.ldif
index d853266025ae350dd7de83e11e463c6bb1ab9429..adb041d374d8fc48fff9d4b40208e7eda82857b3 100644
--- a/install/share/indices.ldif
+++ b/install/share/indices.ldif
@@ -108,6 +108,7 @@ cn: fqdn
 nsSystemIndex: false
 nsIndexType: eq
 nsIndexType: pres
+nsIndexType: sub
 dn: cn=macAddress,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
 changetype: add
diff --git a/install/updates/20-indices.update b/install/updates/20-indices.update
index 74961d77875515d680f34af739c984a6533eb252..fb588b9ba8a2a89c9e7eab87ab5f224ca438645a 100644
--- a/install/updates/20-indices.update
+++ b/install/updates/20-indices.update
@@ -70,8 +70,9 @@ default:cn: fqdn
 default:ObjectClass: top
 default:ObjectClass: nsIndex
 default:nsSystemIndex: false
-default:nsIndexType: eq
-default:nsIndexType: pres
+only:nsIndexType: eq
+only:nsIndexType: pres
+only:nsIndexType: sub
 dn: cn=macAddress,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config
 default:cn: macAddress
--
2.14.3
SOURCES/0008-certs-do-not-implicitly-create-DS-pin.txt.patch
File was deleted
SOURCES/0009-Add-indexing-to-improve-host-find-performance.patch
New file
@@ -0,0 +1,121 @@
From ff597260ef2f5e953b55ae1a8511191853becca8 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slaznick@redhat.com>
Date: Fri, 27 Oct 2017 09:34:38 +0200
Subject: [PATCH] Add indexing to improve host-find performance
host-find <host_name> command performance gets deteriorated when
there's way too many hosts in the LDAP tree. We're adding indices
to try and mitigate this behavior.
https://pagure.io/freeipa/issue/6371
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 install/share/indices.ldif        | 45 +++++++++++++++++++++++++++++++++++++++
 install/updates/20-indices.update | 40 ++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+)
diff --git a/install/share/indices.ldif b/install/share/indices.ldif
index adb041d374d8fc48fff9d4b40208e7eda82857b3..7bd59d2774df9bdf56f6b8034236aa2c5658b366 100644
--- a/install/share/indices.ldif
+++ b/install/share/indices.ldif
@@ -279,3 +279,48 @@ objectClass: nsIndex
 nsSystemIndex: false
 nsIndexType: eq
 nsIndexType: sub
+
+dn: cn=description,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+changetype: add
+cn: description
+objectClass: top
+objectClass: nsindex
+nssystemindex: false
+nsindextype: eq
+nsindextype: sub
+
+dn: cn=l,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+changetype: add
+cn: l
+objectClass: top
+objectClass: nsindex
+nssystemindex: false
+nsindextype: eq
+nsindextype: sub
+
+dn: cn=nsOsVersion,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+changetype: add
+cn: nsOsVersion
+objectClass: top
+objectClass: nsindex
+nssystemindex: false
+nsindextype: eq
+nsindextype: sub
+
+dn: cn=nsHardwarePlatform,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+changetype: add
+cn: nsHardwarePlatform
+objectClass: top
+objectClass: nsindex
+nssystemindex: false
+nsindextype: eq
+nsindextype: sub
+
+dn: cn=nsHostLocation,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+changetype: add
+cn: nsHostLocation
+objectClass: top
+objectClass: nsindex
+nssystemindex: false
+nsindextype: eq
+nsindextype: sub
diff --git a/install/updates/20-indices.update b/install/updates/20-indices.update
index fb588b9ba8a2a89c9e7eab87ab5f224ca438645a..016fbb6bedb6af69fba0a8a84f8c1c6622d4368c 100644
--- a/install/updates/20-indices.update
+++ b/install/updates/20-indices.update
@@ -260,3 +260,43 @@ default: objectClass: nsIndex
 only: nsSystemIndex: false
 only: nsIndexType: eq
 only: nsIndexType: sub
+
+dn: cn=description,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+default: cn: description
+default: objectclass: top
+default: objectclass: nsindex
+default: nssystemindex: false
+default: nsindextype: eq
+default: nsindextype: sub
+
+dn: cn=l,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+default: cn: l
+default: objectclass: top
+default: objectclass: nsindex
+default: nssystemindex: false
+default: nsindextype: eq
+default: nsindextype: sub
+
+dn: cn=nsOsVersion,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+default: cn: nsOsVersion
+default: objectclass: top
+default: objectclass: nsindex
+default: nssystemindex: false
+default: nsindextype: eq
+default: nsindextype: sub
+
+dn: cn=nsHardwarePlatform,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+default: cn: nsHardwarePlatform
+default: objectclass: top
+default: objectclass: nsindex
+default: nssystemindex: false
+default: nsindextype: eq
+default: nsindextype: sub
+
+dn: cn=nsHostLocation,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
+default: cn: nsHostLocation
+default: objectclass: top
+default: objectclass: nsindex
+default: nssystemindex: false
+default: nsindextype: eq
+default: nsindextype: sub
--
2.14.3
SOURCES/0009-httpinstance-clean-up-etc-httpd-alias-on-uninstall.patch
File was deleted
SOURCES/0010-Fixing-replica-install-fix-ldap-connection-in-domlvl.patch
File was deleted
SOURCES/0010-ipa-getkeytab-man-page-add-more-details-about-the-r-.patch
New file
@@ -0,0 +1,87 @@
From 30e55883bd4822d4d3af061d646e7b1044880d52 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Tue, 7 Nov 2017 09:31:19 +0100
Subject: [PATCH] ipa-getkeytab man page: add more details about the -r option
The man page does not provide enough information about replicated
environments and the use of the -r option.
This fix adds an example how to use the same keytab on 2 different
hosts, and points to ipa {service/host}-allow-retrieve-keytab.
Fixes:
https://pagure.io/freeipa/issue/7237
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 client/man/ipa-getkeytab.1 | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/client/man/ipa-getkeytab.1 b/client/man/ipa-getkeytab.1
index 08f6ec40d362b88a974e6ec735ed37c271e01882..39ff0d5da85b5a641328a512feeb06bc9c1ab9d7 100644
--- a/client/man/ipa-getkeytab.1
+++ b/client/man/ipa-getkeytab.1
@@ -44,10 +44,15 @@ provided, so the principal name is just the service
 name and hostname (ldap/foo.example.com from the
 example above).
+ipa-getkeytab is used during IPA client enrollment to retrieve a host service principal and store it in /etc/krb5.keytab. It is possible to retrieve the keytab without Kerberos credentials if the host was pre\-created with a one\-time password. The keytab can be retrieved by binding as the host and authenticating with this one\-time password. The \fB\-D|\-\-binddn\fR and \fB\-w|\-\-bindpw\fR options are used for this authentication.
+
 \fBWARNING:\fR retrieving the keytab resets the secret for the Kerberos principal.
 This renders all other keytabs for that principal invalid.
+When multiple hosts or services need to share the same key (for instance in high availability or load balancing clusters), the \fB\-r\fR option must be used to retrieve the existing key instead of generating a new one (please refer to the EXAMPLES section).
+
+Note that the user or host calling \fBipa-getkeytab\fR needs to be allowed to generate the key with \fBipa host\-allow\-create\-keytab\fR or \fBipa service\-allow\-create\-keytab\fR,
+and the user or host calling \fBipa-getkeytab \-r\fR needs to be allowed to retrieve the keytab for the host or service with \fBipa host\-allow\-retrieve\-keytab\fR or \fBipa service\-allow\-retrieve\-keytab\fR.
-This is used during IPA client enrollment to retrieve a host service principal and store it in /etc/krb5.keytab. It is possible to retrieve the keytab without Kerberos credentials if the host was pre\-created with a one\-time password. The keytab can be retrieved by binding as the host and authenticating with this one\-time password. The \fB\-D|\-\-binddn\fR and \fB\-w|\-\-bindpw\fR options are used for this authentication.
 .SH "OPTIONS"
 .TP
 \fB\-p principal\-name\fR
@@ -118,16 +123,44 @@ keytab must have access to the keys for this operation to succeed.
 Add and retrieve a keytab for the NFS service principal on
 the host foo.example.com and save it in the file /tmp/nfs.keytab and retrieve just the des\-cbc\-crc key.
+.nf
    # ipa\-getkeytab \-p nfs/foo.example.com \-k /tmp/nfs.keytab \-e des\-cbc\-crc
+.fi
 Add and retrieve a keytab for the ldap service principal on
 the host foo.example.com and save it in the file /tmp/ldap.keytab.
+.nf
    # ipa\-getkeytab \-s ipaserver.example.com \-p ldap/foo.example.com \-k /tmp/ldap.keytab
+.fi
 Retrieve a keytab using LDAP credentials (this will typically be done by \fBipa\-join(1)\fR when enrolling a client using the \fBipa\-client\-install(1)\fR command:
+.nf
    # ipa\-getkeytab \-s ipaserver.example.com \-p host/foo.example.com \-k /etc/krb5.keytab \-D fqdn=foo.example.com,cn=computers,cn=accounts,dc=example,dc=com \-w password
+.fi
+
+Add and retrieve a keytab for a clustered HTTP service deployed on client1.example.com and client2.example.com (already enrolled), using the client-frontend.example.com host name:
+
+.nf
+   # ipa host-add client-frontend.example.com --ip-address 10.1.2.3
+   # ipa service-add HTTP/client-frontend.example.com
+   # ipa service-allow-retrieve-keytab HTTP/client-frontend.example.com --hosts={client1.example.com,client2.example.com}
+   # ipa server-allow-create-keytab HTTP/client-frontend.example.com --hosts=client1.example.com
+.fi
+
+   On client1, generate and retrieve a new keytab for client-frontend.example.com:
+.nf
+   # kinit -k
+   # ipa-getkeytab -p HTTP/client-frontend.example.com -k /tmp/http.keytab
+
+.fi
+   On client2, retrieve the existing keytab for client-frontend.example.com:
+.nf
+   # kinit -k
+   # ipa-getkeytab -r -p HTTP/client-frontend.example.com -k /tmp/http.keytab
+.fi
+
 .SH "EXIT STATUS"
 The exit status is 0 on success, nonzero on error.
--
2.13.6
SOURCES/0011-Don-t-allow-OTP-or-RADIUS-in-FIPS-mode.patch
New file
@@ -0,0 +1,83 @@
From be18d6c15a2557e8f45e41efc81f1c005958c690 Mon Sep 17 00:00:00 2001
From: Stanislav Laznicka <slaznick@redhat.com>
Date: Tue, 7 Nov 2017 14:42:12 +0100
Subject: [PATCH] Don't allow OTP or RADIUS in FIPS mode
RADIUS, which is also internally used in the process of OTP
authentication by ipa-otpd, requires MD5 checksums which
makes it impossible to be used in FIPS mode. Don't allow users
setting OTP or RADIUS authentication if in FIPS mode.
https://pagure.io/freeipa/issue/7168
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
 ipaserver/plugins/baseuser.py |  3 +++
 ipaserver/plugins/config.py   | 16 ++++++++++++++++
 2 files changed, 19 insertions(+)
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index bf24dbf542d3b481671dfe4e8cee14a2edcc26e0..bb8a73ded0fed135d5829ec0b0829a936f2196fb 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -32,6 +32,7 @@ from .baseldap import (
     add_missing_object_class)
 from ipaserver.plugins.service import (
    validate_certificate, validate_realm, normalize_principal)
+from ipaserver.plugins.config import check_fips_auth_opts
 from ipalib.request import context
 from ipalib import _
 from ipalib.constants import PATTERN_GROUPUSER_NAME
@@ -477,6 +478,7 @@ class baseuser_add(LDAPCreate):
                             **options):
         assert isinstance(dn, DN)
         set_krbcanonicalname(entry_attrs)
+        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
         self.obj.convert_usercertificate_pre(entry_attrs)
     def post_common_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -600,6 +602,7 @@ class baseuser_mod(LDAPUpdate):
         assert isinstance(dn, DN)
         add_sshpubkey_to_attrs_pre(self.context, attrs_list)
+        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
         self.check_namelength(ldap, **options)
         self.check_mail(entry_attrs)
diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
index ce15e6096f5b84dc45ee21d5aecc73ecf86eba07..c9033fa8e7a2a0bfe77464fa4f9c62278bd814f6 100644
--- a/ipaserver/plugins/config.py
+++ b/ipaserver/plugins/config.py
@@ -85,6 +85,20 @@ EXAMPLES:
 register = Registry()
+
+def check_fips_auth_opts(fips_mode, **options):
+    """
+    OTP and RADIUS are not allowed in FIPS mode since they use MD5
+    checksums (OTP uses our RADIUS responder daemon ipa-otpd).
+    """
+    if 'ipauserauthtype' in options and fips_mode:
+        if ('otp' in options['ipauserauthtype'] or
+                'radius' in options['ipauserauthtype']):
+            raise errors.InvocationError(
+                'OTP and RADIUS authentication in FIPS is '
+                'not yet supported')
+
+
 @register()
 class config(LDAPObject):
     """
@@ -398,6 +412,8 @@ class config_mod(LDAPUpdate):
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
         assert isinstance(dn, DN)
+        check_fips_auth_opts(fips_mode=self.api.env.fips_mode, **options)
+
         if 'ipadefaultprimarygroup' in entry_attrs:
             group=entry_attrs['ipadefaultprimarygroup']
             try:
--
2.13.6
SOURCES/0011-replica-prepare-fix-wrong-IPA-CA-nickname-in-replica.patch
File was deleted
SOURCES/0012-Fix-cert-find-for-CA-less-installations.patch
New file
@@ -0,0 +1,88 @@
From 6049b791567dad33be050b05bb08ef2040f473ee Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 24 Oct 2017 15:43:08 -0400
Subject: [PATCH] Fix cert-find for CA-less installations
Change 49f9d799c171c7ae2ac546a33a353c2c40b4719c deferred the
detailed lookup until all certs were collected but introduced
a bug where the ra backend was always retrieved. This generated a
backtrace in a CA-less install because there is no ra backend in
the CA-less case.
The deferral also removes the certificate value from the LDAP
search output resulting in only the serial number being displayed
unless --all is provided. Add a new class variable,
self.ca_enabled, to add an exception for the CA-less case.
Fixes https://pagure.io/freeipa/issue/7202
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
---
 ipaserver/plugins/cert.py | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index bb11713317abad55577b1c280253ab5d6d68c508..c1d389217265f44e646ac27d9adc8d5524c74ce7 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1453,6 +1453,7 @@ class cert_find(Search, CertMethod):
             truncated = bool(truncated)
+        ca_enabled = getattr(context, 'ca_enabled')
         for entry in entries:
             for attr in ('usercertificate', 'usercertificate;binary'):
                 for cert in entry.get(attr, []):
@@ -1466,7 +1467,12 @@ class cert_find(Search, CertMethod):
                         obj = result[issuer, serial_number]
                     except KeyError:
                         obj = {'serial_number': serial_number}
-                        if not pkey_only and all:
+                        if not pkey_only and (all or not ca_enabled):
+                            # Retrieving certificate details is now deferred
+                            # until after all certificates are collected.
+                            # For the case of CA-less we need to keep
+                            # the certificate because getting it again later
+                            # would require unnecessary LDAP searches.
                             obj['certificate'] = (
                                 base64.b64encode(cert).decode('ascii'))
                         result[issuer, serial_number] = obj
@@ -1480,6 +1486,11 @@ class cert_find(Search, CertMethod):
     def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
                 no_members=True, timelimit=None, sizelimit=None, **options):
+        # Store ca_enabled status in the context to save making the API
+        # call multiple times.
+        ca_enabled = self.api.Command.ca_is_enabled()['result']
+        setattr(context, 'ca_enabled', ca_enabled)
+
         if 'cacn' in options:
             ca_obj = api.Command.ca_show(options['cacn'])['result']
             ca_sdn = unicode(ca_obj['ipacasubjectdn'][0])
@@ -1534,7 +1545,8 @@ class cert_find(Search, CertMethod):
         if not pkey_only:
             ca_objs = {}
-            ra = self.api.Backend.ra
+            if ca_enabled:
+                ra = self.api.Backend.ra
             for key, obj in six.iteritems(result):
                 if all and 'cacn' in obj:
@@ -1561,6 +1573,12 @@ class cert_find(Search, CertMethod):
                 if not raw:
                     self.obj._parse(obj, all)
+                    if not ca_enabled and not all:
+                        # For the case of CA-less don't display the full
+                        # certificate unless requested. It is kept in the
+                        # entry from _ldap_search() so its attributes can
+                        # be retrieved.
+                        obj.pop('certificate', None)
                     self.obj._fill_owners(obj)
         result = list(six.itervalues(result))
--
2.13.6
SOURCES/0012-ldap2-use-LDAP-whoami-operation-to-retrieve-bind-DN-.patch
File was deleted
SOURCES/0013-Backup-ipa-specific-httpd-unit-file.patch
File was deleted
SOURCES/0013-Fix-ipa-restore-python2.patch
New file
@@ -0,0 +1,39 @@
From 276a0dfa90be417a0ce37b15027f716baa97a453 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 2 Nov 2017 09:34:43 +0100
Subject: [PATCH] Fix ipa-restore (python2)
In order to stop tracking LDAP server cert, ipa-restore is using
dse.ldif to find the certificate name. But when ipa-server-install
--uninstall has been called, the file does not exist, leading to a
IOError exception (regression introduced by 87540fe).
The ipa-restore code properly catches the exception in python3 because
IOError is a subclass of OSError, but in python2 this is not the case.
The fix catches IOError and OSError to work properly with both version.
Fixes:
https://pagure.io/freeipa/issue/7231
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Tomas Krizek <tkrizek@redhat.com>
---
 ipaserver/install/ipa_restore.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/ipa_restore.py b/ipaserver/install/ipa_restore.py
index 96fc493c774f5de4c8149bf477cb66ec4960de4f..923b1d6696d33c0bb07ca018b53dd3dabcc191aa 100644
--- a/ipaserver/install/ipa_restore.py
+++ b/ipaserver/install/ipa_restore.py
@@ -815,7 +815,7 @@ class Restore(admintool.AdminTool):
         try:
             dsinstance.DsInstance().stop_tracking_certificates(
                 installutils.realm_to_serverid(api.env.realm))
-        except OSError:
+        except (OSError, IOError):
             # When IPA is not installed, DS NSS DB does not exist
             pass
--
2.13.6
SOURCES/0014-Backup-ipa-custodia-conf-and-keys.patch
New file
@@ -0,0 +1,154 @@
From 0e1b5a65ed06b2213deebb0ea1e5fb8422223426 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Wed, 8 Nov 2017 15:15:30 +0100
Subject: [PATCH] Backup ipa-custodia conf and keys
https://pagure.io/freeipa/issue/7247
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Simo Sorce <ssorce@redhat.com>
---
 install/share/custodia.conf.template    |  2 +-
 ipaplatform/base/paths.py               |  1 +
 ipapython/ipautil.py                    | 19 +++++++++++++++++++
 ipaserver/install/custodiainstance.py   | 24 +++++++++++++-----------
 ipaserver/install/ipa_backup.py         |  2 ++
 ipatests/test_ipapython/test_ipautil.py |  7 +++++++
 6 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/install/share/custodia.conf.template b/install/share/custodia.conf.template
index 855a1b3ba206e4ded8de80758b02473040096c7f..ee3c43ca7ec265aa09d250426bf4138bcfdf62b6 100644
--- a/install/share/custodia.conf.template
+++ b/install/share/custodia.conf.template
@@ -16,7 +16,7 @@ header = GSS_NAME
 handler = ipaserver.secrets.kem.IPAKEMKeys
 paths = /keys
 store = ipa
-server_keys = $IPA_CUSTODIA_CONF_DIR/server.keys
+server_keys = $IPA_CUSTODIA_KEYS
 [store:ipa]
 handler = ipaserver.secrets.store.IPASecStore
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 804fddee60f787e161947bbe4b1914995257ceb4..42240a71066599ca8b36d10a9e5b23625f868977 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -349,6 +349,7 @@ class BasePathNamespace(object):
     NETWORK_MANAGER_CONFIG_DIR = '/etc/NetworkManager/conf.d'
     IPA_CUSTODIA_CONF_DIR = '/etc/ipa/custodia'
     IPA_CUSTODIA_CONF = '/etc/ipa/custodia/custodia.conf'
+    IPA_CUSTODIA_KEYS = '/etc/ipa/custodia/server.keys'
     IPA_CUSTODIA_SOCKET = '/run/httpd/ipa-custodia.sock'
     IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
     IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index cc52af6d9235cfbd597679231f63667b81a200b4..426b32ef05ab00dcbf37b1e58b6390accee33cb1 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -307,6 +307,25 @@ def write_tmp_file(txt):
     return fd
+
+def flush_sync(f):
+    """Flush and fsync file to disk
+
+    :param f: a file object with fileno and name
+    """
+    # flush file buffer to file descriptor
+    f.flush()
+    # flush Kernel buffer to disk
+    os.fsync(f.fileno())
+    # sync metadata in directory
+    dirname = os.path.dirname(os.path.abspath(f.name))
+    dirfd = os.open(dirname, os.O_RDONLY | os.O_DIRECTORY)
+    try:
+        os.fsync(dirfd)
+    finally:
+        os.close(dirfd)
+
+
 def shell_quote(string):
     if isinstance(string, str):
         return "'" + string.replace("'", "'\\''") + "'"
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index bc3cea7063dff183c85b4f6e8ced7567f691001d..0a90bb3954486b9773e3553e9981d2a8d0d4e44a 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -25,8 +25,7 @@ class CustodiaInstance(SimpleServiceInstance):
     def __init__(self, host_name=None, realm=None):
         super(CustodiaInstance, self).__init__("ipa-custodia")
         self.config_file = paths.IPA_CUSTODIA_CONF
-        self.server_keys = os.path.join(paths.IPA_CUSTODIA_CONF_DIR,
-                                        'server.keys')
+        self.server_keys = paths.IPA_CUSTODIA_KEYS
         self.ldap_uri = None
         self.fqdn = host_name
         self.realm = realm
@@ -35,16 +34,19 @@ class CustodiaInstance(SimpleServiceInstance):
         template_file = os.path.basename(self.config_file) + '.template'
         template = os.path.join(paths.USR_SHARE_IPA_DIR, template_file)
         httpd_info = pwd.getpwnam(constants.HTTPD_USER)
-        sub_dict = dict(IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR,
-                        IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET,
-                        IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG,
-                        LDAP_URI=installutils.realm_to_ldapi_uri(self.realm),
-                        UID=httpd_info.pw_uid, GID=httpd_info.pw_gid)
+        sub_dict = dict(
+            IPA_CUSTODIA_CONF_DIR=paths.IPA_CUSTODIA_CONF_DIR,
+            IPA_CUSTODIA_KEYS=paths.IPA_CUSTODIA_KEYS,
+            IPA_CUSTODIA_SOCKET=paths.IPA_CUSTODIA_SOCKET,
+            IPA_CUSTODIA_AUDIT_LOG=paths.IPA_CUSTODIA_AUDIT_LOG,
+            LDAP_URI=installutils.realm_to_ldapi_uri(self.realm),
+            UID=httpd_info.pw_uid,
+            GID=httpd_info.pw_gid
+        )
         conf = ipautil.template_file(template, sub_dict)
-        fd = open(self.config_file, "w+")
-        fd.write(conf)
-        fd.flush()
-        fd.close()
+        with open(self.config_file, "w") as f:
+            f.write(conf)
+            ipautil.flush_sync(f)
     def create_instance(self):
         suffix = ipautil.realm_to_suffix(self.realm)
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
index f8cdd56d26636678279ba5afb423c5eef10c33d0..93b154330d3e6c8700c98860eb0c08f6841774bb 100644
--- a/ipaserver/install/ipa_backup.py
+++ b/ipaserver/install/ipa_backup.py
@@ -181,6 +181,8 @@ class Backup(admintool.AdminTool):
         paths.DNSSEC_SOFTHSM_PIN_SO,
         paths.IPA_ODS_EXPORTER_KEYTAB,
         paths.IPA_DNSKEYSYNCD_KEYTAB,
+        paths.IPA_CUSTODIA_KEYS,
+        paths.IPA_CUSTODIA_CONF,
         paths.HOSTS,
     ) + tuple(
         os.path.join(paths.IPA_NSSDB_DIR, file)
diff --git a/ipatests/test_ipapython/test_ipautil.py b/ipatests/test_ipapython/test_ipautil.py
index 9c351bd0ed9cd96488ac74deadf97996668a75d2..5e1f58003e9f3cae2f0819ecc348ade2c367548b 100644
--- a/ipatests/test_ipapython/test_ipautil.py
+++ b/ipatests/test_ipapython/test_ipautil.py
@@ -25,6 +25,7 @@ Test the `ipapython/ipautil.py` module.
 import nose
 import pytest
 import six
+import tempfile
 from ipapython import ipautil
@@ -478,3 +479,9 @@ def test_backcompat():
     assert rc is result.returncode
     assert out is result.output
     assert err is result.error_output
+
+
+def test_flush_sync():
+    with tempfile.NamedTemporaryFile('wb+') as f:
+        f.write(b'data')
+        ipautil.flush_sync(f)
--
2.13.6
SOURCES/0014-WebUI-check-principals-in-lowercase.patch
File was deleted
SOURCES/0015-WebUI-add-method-for-disabling-item-in-user-dropdown.patch
File was deleted
SOURCES/0015-adtrust-filter-out-subdomains-when-defining-our-topo.patch
New file
@@ -0,0 +1,66 @@
From efdbea05f716700d8ed659430a6b501b41de0e54 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Thu, 19 Oct 2017 13:21:05 +0300
Subject: [PATCH] adtrust: filter out subdomains when defining our topology to
 AD
When definining a topology of a forest to be visible over a cross-forest
trust, we set *.<forest name> as all-catch top level name already.
This means that all DNS subdomains of the forest will already be matched
by this top level name (TLN). If we add more TLNs for subdomains, Active
Directory will respond with NT_STATUS_INVALID_PARAMETER.
Filter out all subdomains of the forest root domain. All other realm
domains will be added with explicit TLN records.
Also filter out single label domains. These aren't possible to add as
TLNs to Windows Server 2016 as it considers them incorrect. Given that
we do not allow single lable domains as part of freeIPA installs, this
is another layer of protection here.
Fixes https://pagure.io/freeipa/issue/6666
Reviewed-By: Christian Heimes <cheimes@redhat.com>
---
 ipaserver/dcerpc.py | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index d684a17cabe43bbbd43d29f75f534b6e50fccd12..aa63cd9db0a1d47b5309cc6bed2ff7584760a39d 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -50,6 +50,7 @@ import samba
 import ldap as _ldap
 from ipapython import ipaldap
+from ipapython.dnsutil import DNSName
 from dns import resolver, rdatatype
 from dns.exception import DNSException
 import pysss_nss_idmap
@@ -1589,7 +1590,22 @@ class TrustDomainJoins(object):
                      entry.single_value.get('modifytimestamp').timetuple()
                 )*1e7+116444736000000000)
+        forest = DNSName(self.local_domain.info['dns_forest'])
+        # tforest is IPA forest. keep the line below for future checks
+        # tforest = DNSName(self.remote_domain.info['dns_forest'])
         for dom in realm_domains['associateddomain']:
+            d = DNSName(dom)
+
+            # We should skip all DNS subdomains of our forest
+            # because we are going to add *.<forest> TLN anyway
+            if forest.is_superdomain(d) and forest != d:
+                continue
+
+            # We also should skip single label TLDs as they
+            # cannot be added as TLNs
+            if len(d.labels) == 1:
+                continue
+
             ftinfo = dict()
             ftinfo['rec_name'] = dom
             ftinfo['rec_time'] = trust_timestamp
--
2.13.6
SOURCES/0016-Fix-ca-less-IPA-install-on-fips-mode.patch
New file
@@ -0,0 +1,45 @@
From 8f35c1c705a7584cdcc9ad5c6fb15ba940ec3f4a Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 23 Nov 2017 18:06:56 +0100
Subject: [PATCH] Fix ca less IPA install on fips mode
When ipa-server-install is run in fips mode and ca-less, the installer
fails when the keys are provided with --{http|dirsrv|pkinit}-cert-file
in a separate key file.
The installer transforms the key into PKCS#8 format using
openssl pkcs8 -topk8
but this command fails on a fips-enabled server, unless the options
-v2 aes256 -v2prf hmacWithSHA256
are also provided.
Fixes:
https://pagure.io/freeipa/issue/7280
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
---
 ipapython/certdb.py | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 114c58340253141706afa461ecaf87797562ca1d..f198811e0fd02c8925f0dcfa8764535b35ed29ed 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -499,9 +499,13 @@ class NSSDatabase(object):
                                 "Can't load private key from both %s and %s" %
                                 (key_file, filename))
+                        # the args -v2 aes256 -v2prf hmacWithSHA256 are needed
+                        # on OpenSSL 1.0.2 (fips mode). As soon as FreeIPA
+                        # requires OpenSSL 1.1.0 we'll be able to drop them
                         args = [
                             OPENSSL, 'pkcs8',
                             '-topk8',
+                            '-v2', 'aes256', '-v2prf', 'hmacWithSHA256',
                             '-passout', 'file:' + self.pwd_file,
                         ]
                         if ((label != 'PRIVATE KEY' and key_password) or
--
2.13.6
SOURCES/0016-WebUI-Add-support-for-login-for-AD-users.patch
File was deleted
SOURCES/0017-cert-do-not-limit-internal-searches-in-cert-find.patch
File was deleted
SOURCES/0017-trust-detect-and-error-out-when-non-AD-trust-with-IP.patch
New file
@@ -0,0 +1,281 @@
From a4e9e8f368c8a61d539e9da26e4a16a6234c138f Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Fri, 17 Nov 2017 17:19:25 +0200
Subject: [PATCH] trust: detect and error out when non-AD trust with IPA domain
 name exists
Quite often users choose wrong type of trust on Active Directory side
when setting up a trust to freeIPA. The trust type supported by freeIPA
is just a normal forest trust to another Active Directory. However,
some people follow old internet recipes that force using a trust to MIT
Kerberos realm.
This is a wrong type of trust. Unfortunately, when someone used MIT
Kerberos realm trust, there is no way to programmatically remote the
trust from freeIPA side. As result, we have to detect such situation and
report an error.
To do proper reporting, we need reuse some constants and trust type
names we use in IPA CLI/Web UI. These common components were moved to
a separate ipaserver/dcerpc_common.py module that is imported by both
ipaserver/plugins/trust.py and ipaserver/dcerpc.py.
Fixes https://pagure.io/freeipa/issue/7264
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
 ipaserver/dcerpc.py        | 37 +++++++++++++++--------
 ipaserver/dcerpc_common.py | 73 ++++++++++++++++++++++++++++++++++++++++++++++
 ipaserver/plugins/trust.py | 65 ++++++++++-------------------------------
 3 files changed, 113 insertions(+), 62 deletions(-)
 create mode 100644 ipaserver/dcerpc_common.py
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index aa63cd9db0a1d47b5309cc6bed2ff7584760a39d..ac1b2a34784df491a3851aa21bbadbec2297241c 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -31,6 +31,10 @@ from ipapython import ipautil
 from ipapython.ipa_log_manager import root_logger
 from ipapython.dn import DN
 from ipaserver.install import installutils
+from ipaserver.dcerpc_common import (TRUST_BIDIRECTIONAL,
+                                     TRUST_JOIN_EXTERNAL,
+                                     trust_type_string)
+
 from ipalib.util import normalize_name
 import os
@@ -77,15 +81,6 @@ The code in this module relies heavily on samba4-python package
 and Samba4 python bindings.
 """)
-# Both constants can be used as masks against trust direction
-# because bi-directional has two lower bits set.
-TRUST_ONEWAY = 1
-TRUST_BIDIRECTIONAL = 3
-
-# Trust join behavior
-# External trust -- allow creating trust to a non-root domain in the forest
-TRUST_JOIN_EXTERNAL = 1
-
 def is_sid_valid(sid):
     try:
@@ -151,6 +146,7 @@ pysss_type_key_translation_dict = {
     pysss_nss_idmap.ID_BOTH: 'both',
 }
+
 class TrustTopologyConflictSolved(Exception):
     """
     Internal trust error: raised when previously detected
@@ -1254,9 +1250,26 @@ class TrustDomainInstance(object):
             dname = lsa.String()
             dname.string = another_domain.info['dns_domain']
             res = self._pipe.QueryTrustedDomainInfoByName(
-                                self._policy_handle,
-                                dname,
-                                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
+                self._policy_handle,
+                dname,
+                lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO
+            )
+            if res.info_ex.trust_type != lsa.LSA_TRUST_TYPE_UPLEVEL:
+                msg = _('There is already a trust to {ipa_domain} with '
+                        'unsupported type {trust_type}. Please remove '
+                        'it manually on AD DC side.')
+                ttype = trust_type_string(
+                    res.info_ex.trust_type, res.info_ex.trust_attributes
+                )
+                err = unicode(msg).format(
+                    ipa_domain=another_domain.info['dns_domain'],
+                    trust_type=ttype)
+
+                raise errors.ValidationError(
+                    name=_('AD domain controller'),
+                    error=err
+                )
+
             self._pipe.DeleteTrustedDomain(self._policy_handle,
                                            res.info_ex.sid)
         except RuntimeError as e:
diff --git a/ipaserver/dcerpc_common.py b/ipaserver/dcerpc_common.py
new file mode 100644
index 0000000000000000000000000000000000000000..526b025e3282c8a556088eb2ed1ba467b889b86c
--- /dev/null
+++ b/ipaserver/dcerpc_common.py
@@ -0,0 +1,73 @@
+import six
+from ipalib import _
+if six.PY3:
+    unicode = six.text_type
+
+# Both constants can be used as masks against trust direction
+# because bi-directional has two lower bits set.
+TRUST_ONEWAY = 1
+TRUST_BIDIRECTIONAL = 3
+
+# Trust join behavior
+# External trust -- allow creating trust to a non-root domain in the forest
+TRUST_JOIN_EXTERNAL = 1
+
+# We don't want to import any of Samba Python code here just for constants
+# Since these constants set in MS-ADTS, we can rely on their stability
+LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE = 0x00000001
+
+_trust_direction_dict = {
+        1: _('Trusting forest'),
+        2: _('Trusted forest'),
+        3: _('Two-way trust')
+}
+
+_trust_status_dict = {
+        True: _('Established and verified'),
+        False: _('Waiting for confirmation by remote side')
+}
+
+_trust_type_dict_unknown = _('Unknown')
+
+# Trust type is a combination of ipanttrusttype and ipanttrustattributes
+# We shift trust attributes by 3 bits to left so bit 0 becomes bit 3 and
+# 2+(1 << 3) becomes 10.
+_trust_type_dict = {
+        1: _('Non-Active Directory domain'),
+        2: _('Active Directory domain'),
+        3: _('RFC4120-compliant Kerberos realm'),
+        10: _('Non-transitive external trust to a domain in '
+              'another Active Directory forest'),
+        11: _('Non-transitive external trust to an RFC4120-'
+              'compliant Kerberos realm')
+}
+
+
+def trust_type_string(level, attrs):
+    """
+    Returns a string representing a type of the trust.
+    The original field is an enum:
+      LSA_TRUST_TYPE_DOWNLEVEL  = 0x00000001,
+      LSA_TRUST_TYPE_UPLEVEL    = 0x00000002,
+      LSA_TRUST_TYPE_MIT        = 0x00000003
+    """
+    transitive = int(attrs) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
+    string = _trust_type_dict.get(int(level) | (transitive << 3),
+                                  _trust_type_dict_unknown)
+    return unicode(string)
+
+
+def trust_direction_string(level):
+    """
+    Returns a string representing a direction of the trust.
+    The original field is a bitmask taking two bits in use
+      LSA_TRUST_DIRECTION_INBOUND  = 0x00000001,
+      LSA_TRUST_DIRECTION_OUTBOUND = 0x00000002
+    """
+    string = _trust_direction_dict.get(int(level), _trust_type_dict_unknown)
+    return unicode(string)
+
+
+def trust_status_string(level):
+    string = _trust_status_dict.get(level, _trust_type_dict_unknown)
+    return unicode(string)
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index d0bbfbc47ca65c9c5229685fc9d202c293fe41cd..ecc5fa0b22f94de05cc5282758be093f0cfca13f 100644
--- a/ipaserver/plugins/trust.py
+++ b/ipaserver/plugins/trust.py
@@ -44,6 +44,13 @@ from ipalib import errors
 from ipalib import output
 from ldap import SCOPE_SUBTREE
 from time import sleep
+from ipaserver.dcerpc_common import (TRUST_ONEWAY,
+                                     TRUST_BIDIRECTIONAL,
+                                     TRUST_JOIN_EXTERNAL,
+                                     LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE,
+                                     trust_type_string,
+                                     trust_direction_string,
+                                     trust_status_string)
 if six.PY3:
     unicode = str
@@ -63,9 +70,6 @@ except Exception as e:
 if api.env.in_server and api.env.context in ['lite', 'server']:
     try:
         import ipaserver.dcerpc
-        from ipaserver.dcerpc import (TRUST_ONEWAY,
-                                      TRUST_BIDIRECTIONAL,
-                                      TRUST_JOIN_EXTERNAL)
         import dbus
         import dbus.mainloop.glib
         _bindings_installed = True
@@ -157,28 +161,14 @@ particular type.
 register = Registry()
-# Trust type is a combination of ipanttrusttype and ipanttrustattributes
-# We shift trust attributes by 3 bits to left so bit 0 becomes bit 3 and
-# 2+(1 << 3) becomes 10.
-_trust_type_dict = {1 : _('Non-Active Directory domain'),
-                    2 : _('Active Directory domain'),
-                    3 : _('RFC4120-compliant Kerberos realm'),
-                    10: _('Non-transitive external trust to a domain in another Active Directory forest')}
-
-_trust_direction_dict = {1 : _('Trusting forest'),
-                         2 : _('Trusted forest'),
-                         3 : _('Two-way trust')}
-_trust_status_dict = {True : _('Established and verified'),
-                 False : _('Waiting for confirmation by remote side')}
-_trust_type_dict_unknown = _('Unknown')
-
-_trust_type_option = StrEnum('trust_type',
-                        cli_name='type',
-                        label=_('Trust type (ad for Active Directory, default)'),
-                        values=(u'ad',),
-                        default=u'ad',
-                        autofill=True,
-                    )
+_trust_type_option = StrEnum(
+         'trust_type',
+         cli_name='type',
+         label=_('Trust type (ad for Active Directory, default)'),
+         values=(u'ad',),
+         default=u'ad',
+         autofill=True,
+        )
 DEFAULT_RANGE_SIZE = 200000
@@ -187,31 +177,6 @@ DBUS_IFACE_TRUST = 'com.redhat.idm.trust'
 CRED_STYLE_SAMBA = 1
 CRED_STYLE_KERBEROS = 2
-LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE = 0x00000001
-
-def trust_type_string(level, attrs):
-    """
-    Returns a string representing a type of the trust. The original field is an enum:
-      LSA_TRUST_TYPE_DOWNLEVEL  = 0x00000001,
-      LSA_TRUST_TYPE_UPLEVEL    = 0x00000002,
-      LSA_TRUST_TYPE_MIT        = 0x00000003
-    """
-    transitive = int(attrs) & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE
-    string = _trust_type_dict.get(int(level) | (transitive << 3), _trust_type_dict_unknown)
-    return unicode(string)
-
-def trust_direction_string(level):
-    """
-    Returns a string representing a direction of the trust. The original field is a bitmask taking two bits in use
-      LSA_TRUST_DIRECTION_INBOUND  = 0x00000001,
-      LSA_TRUST_DIRECTION_OUTBOUND = 0x00000002
-    """
-    string = _trust_direction_dict.get(int(level), _trust_type_dict_unknown)
-    return unicode(string)
-
-def trust_status_string(level):
-    string = _trust_status_dict.get(level, _trust_type_dict_unknown)
-    return unicode(string)
 def make_trust_dn(env, trust_type, dn):
     assert isinstance(dn, DN)
--
2.13.6
SOURCES/0018-ipa-kdb-add-ipadb_fetch_principals_with_extra_filter.patch
File was deleted
SOURCES/0018-ipaserver-plugins-trust.py-fix-some-indenting-issues.patch
New file
@@ -0,0 +1,71 @@
From e553b66e54af3bf981501bca57fb22caaa8e8305 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Thu, 9 Nov 2017 09:57:47 +0200
Subject: [PATCH] ipaserver/plugins/trust.py; fix some indenting issues
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
 ipaserver/plugins/trust.py | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index ecc5fa0b2