diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/.github/workflows/ci.yml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/.github/workflows/ci.yml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/.github/workflows/ci.yml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/.github/workflows/ci.yml 2024-10-01 18:30:01.000000000 +0000 @@ -30,5 +30,5 @@ run: | source ../contrib/fedora/bashrc_sssd - make CFLAGS+="$SSS_WARNINGS -Werror -Wno-error=deprecated-declarations" + make CFLAGS+="$SSS_WARNINGS -Werror" - name: make check @@ -37,5 +37,5 @@ run: | source ../contrib/fedora/bashrc_sssd - make CFLAGS+="$SSS_WARNINGS -Werror -Wno-error=deprecated-declarations" check + make CFLAGS+="$SSS_WARNINGS -Werror" check - name: make distcheck @@ -123,4 +123,5 @@ ./sssd/var/log/sssd/*.log ./sssd/ci-build-debug/ci-*.log + ./sssd/ci-build-debug/config.log ./sssd/ci-build-debug/test-suite.log ./sssd/ci-build-debug/ci-mock-result/*.log @@ -136,122 +137,4 @@ ./sssd/ci-build-debug/*.valgrind.log - multihost: - needs: [prepare, build] - strategy: - fail-fast: false - matrix: - tag: ${{ fromJson(needs.prepare.outputs.matrix).multihost }} - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - name: Checkout sssd repository - uses: actions/checkout@v4 - with: - path: sssd - - - name: Setup containers - uses: SSSD/sssd-ci-containers/actions/setup@master - with: - path: sssd-ci-containers - tag: ${{ matrix.tag }} - limit: dns client - override: | - services: - client: - image: ${REGISTRY}/ci-client-devel:${TAG} - shm_size: 4G - tmpfs: - - /dev/shm - volumes: - - ../sssd:/sssd:rw - - - name: Build SSSD on the client - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - log-file: multihost-build.log - working-directory: /sssd - script: | - #!/bin/bash - set -ex - - ./contrib/ci/run --deps-only - autoreconf -if - - mkdir -p /dev/shm/sssd - pushd /dev/shm/sssd - /sssd/configure --enable-silent-rules - make rpms - - - name: Install SSSD on the client - uses: SSSD/sssd-ci-containers/actions/exec@master - with: - log-file: multihost-install.log - user: root - script: | - #!/bin/bash - set -ex - - dnf remove -y --noautoremove sssd\* - dnf install -y /dev/shm/sssd/rpmbuild/RPMS/*/*.rpm - rm -fr /dev/shm/sssd - test -x /usr/bin/sss_ssh_knownhosts && \ - sed -e 's/GlobalKnownHostsFile/#GlobalKnownHostsFile/' \ - -e 's/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p %p %h/KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts %H/' \ - -i /etc/ssh/ssh_config.d/04-ipa.conf - - - name: Install multihost tests dependencies - shell: bash - run: | - set -ex - - sudo apt-get update - - # Install certutil and dependencies for python-ldap - sudo apt-get install -y libnss3-tools libsasl2-dev python3-dev libldap2-dev libssl-dev - - # Virtualenv - pip3 install virtualenv - python3 -m venv .venv - source .venv/bin/activate - - # Install multihost tests requirements - pip3 install -r ./sssd/src/tests/multihost/requirements.txt - - - name: Create multihost configuration - uses: DamianReeves/write-file-action@6929a9a6d1807689191dcc8bbe62b54d70a32b42 - with: - path: mhc.yml - write-mode: overwrite - contents: | - root_password: 'Secret123' - domains: - - name: tier0.tests - type: sssd - hosts: - - name: client - external_hostname: client.test - role: master - - - name: Run basic multihost tests - run: | - set -ex -o pipefail - - source .venv/bin/activate - export PYTHONPATH="${PYTHONPATH}:$(realpath ./sssd/src/tests/multihost)" - pytest -s --multihost-config=./mhc.yml ./sssd/src/tests/multihost/basic |& tee multihost-pytest.log - - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - if-no-files-found: ignore - name: ${{ matrix.tag }}-multihost - path: | - sssd/ci-install-deps.log - multihost-build.log - multihost-install.log - multihost-pytest.log - system: needs: [prepare, build] @@ -437,5 +320,5 @@ if: ${{ always() }} runs-on: ubuntu-latest - needs: [build, intgcheck, multihost, system] + needs: [build, intgcheck, system] steps: - name: Fail on failure @@ -443,5 +326,4 @@ needs.build.result != 'success' || needs.intgcheck.result != 'success' - || needs.multihost.result != 'success' || needs.system.result != 'success' run: exit 1 diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/Makefile.am /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/Makefile.am --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/Makefile.am 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/Makefile.am 2024-10-01 18:30:01.000000000 +0000 @@ -190,7 +190,5 @@ sssdlibexec_PROGRAMS += sssd_ssh endif -if BUILD_IFP sssdlibexec_PROGRAMS += sssd_ifp -endif if BUILD_SAMBA sssdlibexec_PROGRAMS += gpo_child @@ -320,10 +318,8 @@ endif # HAVE_LIBRESOLV -if BUILD_IFP non_interactive_cmocka_based_tests += ifp_tests if BUILD_LIBSIFP non_interactive_cmocka_based_tests += sss_sifp-tests endif # BUILD_LIBSIFP -endif # BUILD_IFP if HAVE_INOTIFY @@ -705,8 +701,8 @@ src/sss_iface/sss_iface.h \ src/util/crypto/sss_crypto.h \ - src/util/crypto/libcrypto/sss_openssl.h \ src/util/cert.h \ src/util/dlinklist.h \ src/util/debug.h \ + src/util/memory_erase.h \ src/util/util.h \ src/util/util_errors.h \ @@ -947,9 +943,7 @@ nss_idmap_doc -if BUILD_IFP if BUILD_LIBSIFP SSSD_DOCS += sss_simpleifp_doc endif # BUILD_LIBSIFP -endif # BUILD_IFP CLIENT_LIBS = $(LTLIBINTL) @@ -993,4 +987,5 @@ src/util/atomic_io.c \ src/util/memory.c \ + src/util/memory_erase.c \ $(NULL) SSS_CRYPT_CFLAGS = $(CRYPTO_CFLAGS) @@ -1272,4 +1267,5 @@ src/util/util_preauth.c \ src/util/memory.c \ + src/util/memory_erase.c \ src/util/safe-format-string.c \ src/util/server.c \ @@ -1444,5 +1440,4 @@ $(NULL) -if BUILD_IFP if BUILD_LIBSIFP lib_LTLIBRARIES += libsss_simpleifp.la @@ -1473,5 +1468,4 @@ src/lib/sifp/sss_sifp_dbus.h endif # BUILD_LIBSIFP -endif # BUILD_IFP ######################### @@ -1674,5 +1668,4 @@ $(NULL) -if BUILD_IFP pkglib_LTLIBRARIES += libifp_iface.la libifp_iface_la_SOURCES = \ @@ -1782,6 +1775,4 @@ -endif - if BUILD_KCM sssd_kcm_SOURCES = \ @@ -3202,5 +3193,4 @@ $(NULL) -if BUILD_IFP ifp_tests_SOURCES = \ $(TEST_MOCK_RESP_OBJ) \ @@ -3245,5 +3235,4 @@ $(SSSD_INTERNAL_LTLIBS) endif # BUILD_LIBSIFP -endif # BUILD_IFP test_sysdb_views_SOURCES = \ @@ -4183,4 +4172,5 @@ src/util/atomic_io.c \ src/util/authtok-utils.c \ + src/util/memory_erase.c \ src/sss_client/sss_pam_macros.h \ src/sss_client/sss_pam_compat.h @@ -4707,4 +4697,5 @@ src/util/atomic_io.c \ src/util/memory.c \ + src/util/memory_erase.c \ src/util/authtok.c \ src/util/authtok-utils.c \ @@ -4751,4 +4742,5 @@ src/util/atomic_io.c \ src/util/memory.c \ + src/util/memory_erase.c \ src/util/authtok.c \ src/util/authtok-utils.c \ @@ -4900,4 +4892,5 @@ src/util/atomic_io.c \ src/util/memory.c \ + src/util/memory_erase.c \ src/util/strtonum.c \ $(NULL) @@ -5239,9 +5232,7 @@ $(NULL) endif -if BUILD_IFP systemdunit_DATA += \ src/sysv/systemd/sssd-ifp.service \ $(NULL) -endif if BUILD_PAC_RESPONDER systemdunit_DATA += \ @@ -5311,5 +5302,8 @@ -e 's|@nss_socket_user_group[@]|$(nss_socket_user_group)|g' \ -e 's|@supplementary_groups[@]|$(supplementary_groups)|g' \ - -e 's|@sssdconfdir[@]|$(sssdconfdir)|g' + -e 's|@sssdconfdir[@]|$(sssdconfdir)|g' \ + -e 's|@secdbpath[@]|$(secdbpath)|g' \ + -e 's|@dbpath[@]|$(dbpath)|g' \ + -e 's|@gpocachepath[@]|$(gpocachepath)|g' replace_script = \ @@ -5369,9 +5363,7 @@ endif -if BUILD_IFP src/sysv/systemd/sssd-ifp.service: src/sysv/systemd/sssd-ifp.service.in Makefile @$(MKDIR_P) src/sysv/systemd/ $(ifp_replace_script) -endif if BUILD_PAC_RESPONDER @@ -5492,9 +5484,7 @@ $(DOXYGEN) src/sss_client/idmap/sss_nss_idmap.doxy $(DOXYGEN) src/lib/certmap/sss_certmap.doxy -if BUILD_IFP if BUILD_LIBSIFP $(DOXYGEN) src/lib/sifp/sss_simpleifp.doxy endif # BUILD_LIBSIFP -endif # BUILD_IFP else !HAVE_DOXYGEN docs: @@ -5707,4 +5697,5 @@ rm -f $(builddir)/src/sysv/systemd/sssd-kcm.service rm -f $(builddir)/src/tools/wrappers/sss_debuglevel + rm -Rf $(builddir)/src/examples rm -Rf $(builddir)/contrib diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/configure.ac /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/configure.ac --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/configure.ac 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/configure.ac 2024-10-01 18:30:01.000000000 +0000 @@ -564,4 +564,5 @@ contrib/sssd-pcsc.rules contrib/90-sssd-token-access.rules contrib/sssd-tmpfiles.conf + src/examples/logrotate src/sysv/sssd src/sysv/gentoo/sssd src/sysv/gentoo/sssd-kcm po/Makefile.in src/man/Makefile src/tests/cwrap/Makefile diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/contrib/ci/sssd.supp /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/contrib/ci/sssd.supp --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/contrib/ci/sssd.supp 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/contrib/ci/sssd.supp 2024-10-01 18:30:01.000000000 +0000 @@ -25,29 +25,4 @@ } -# nss3-involved leaks -{ - sssd-leak-nss3 - Memcheck:Leak - ... - obj:*/libnss3.so - ... -} - -# nspr4-involved leaks -{ - sssd-leak-nspr4 - Memcheck:Leak - ... - obj:*/libnspr4.so - ... -} -{ - sssd-leak-nspr4-arena-allocate - Memcheck:Leak - fun:malloc - fun:PL_ArenaAllocate - ... -} - # dbus-involved leaks { @@ -109,19 +84,4 @@ } -# False positive leak involving RHEL6 glib memory slices -{ - sssd-leak-glib-slices - Memcheck:Leak - fun:memalign - fun:posix_memalign - obj:/lib*/libglib-2.0.so* - fun:g_slice_alloc - fun:g_string_sized_new - ... - fun:g_utf8_casefold - fun:sss_utf8_case_eq - ... -} - # uninitialised value in libselinux (fixed in fedora >= 21) { @@ -158,13 +118,4 @@ } -# popt was not good with read access either. Applies for popt <= 1.13 -{ - popt-suppress-invalid-read - Memcheck:Addr4 - ... - fun:poptGetNextOpt - fun:main -} - # Some tests initialize c-ares context, then fork a child that just exits # without a proper teardown, which means the ares destructor is not called. @@ -222,48 +173,4 @@ } -# Leak found on debian -{ - set-default-locale-error-debian - Memcheck:Leak - ... - fun:malloc - fun:xmalloc - fun:set_default_locale - fun:main -} - -# glibc nsswitch (getpwuid) leak -# Seems to be affecting Fedora < F28 -{ - glibc-nss-getpwuid - Memcheck:Leak - fun:malloc - ... - fun:getpwuid_r@@GLIBC_2.2.5 - fun:getpwuid - ... - fun:main -} - -# Suppress https://bugzilla.redhat.com/show_bug.cgi?id=2065675 -{ - dlopen-tests - Memcheck:Leak - match-leak-kinds: definite - fun:malloc - fun:UnknownInlinedFun - fun:_dl_find_object_update - fun:dl_open_worker_begin - fun:_dl_catch_exception - fun:dl_open_worker - fun:_dl_catch_exception - fun:_dl_open - fun:dlopen_doit - fun:_dl_catch_exception - fun:_dl_catch_error - fun:_dlerror_run - fun:dlopen@@GLIBC_2.34 -} - # sssd debug initialization leak { @@ -278,2 +185,13 @@ fun:main } + +{ + dl-invalid-read + Memcheck:Addr32 + fun:bcmp + ... + fun:openaux + ... + fun:_dl_catch_exception + fun:_dl_open +} diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/contrib/sssd.spec.in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/contrib/sssd.spec.in --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/contrib/sssd.spec.in 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/contrib/sssd.spec.in 2024-10-01 18:30:01.000000000 +0000 @@ -176,4 +176,7 @@ BuildRequires: systemd-devel BuildRequires: systemtap-sdt-devel +%if 0%{?fedora} >= 41 +BuildRequires: systemtap-sdt-dtrace +%endif BuildRequires: uid_wrapper BuildRequires: po4a @@ -208,4 +211,9 @@ Obsoletes: libsss_simpleifp-debuginfo < 2.9.0 %endif +%if 0%{?rhel} != 9 +%if %{use_sssd_user} +Obsoletes: sssd-polkit-rules < 2.10.0 +%endif +%endif # Requires # due to ABI changes in 1.1.30/1.2.0 @@ -468,4 +476,5 @@ the information from the SSSD to be transmitted over the system bus. +%if 0%{?rhel} == 9 %if %{use_sssd_user} %package polkit-rules @@ -478,8 +487,7 @@ %description polkit-rules Provides rules for polkit integration with SSSD. This is required -for smartcard support. +for smartcard support if SSSD service is running as user 'sssd'. %endif -%if 0%{?rhel} == 9 %package -n libsss_simpleifp Summary: The SSSD D-Bus responder helper library @@ -607,4 +615,7 @@ --with-libsifp \ --with-conf-service-user-support \ + --with-files-provider \ + --with-extended-enumeration-support \ + --with-ssh-known-hosts-proxy \ %endif %if %{build_subid} @@ -808,4 +819,7 @@ %dir %{_libdir}/%{name} +%if 0%{?rhel} == 9 +%{_libdir}/%{name}/libsss_files.so +%endif %{_libdir}/%{name}/libsss_simple.so @@ -865,4 +879,7 @@ %endif %{_mandir}/man5/sssd.conf.5* +%if 0%{?rhel} == 9 +%{_mandir}/man5/sssd-files.5* +%endif %{_mandir}/man5/sssd-simple.5* %{_mandir}/man5/sssd-sudo.5* @@ -883,11 +900,12 @@ %{_sysusersdir}/sssd.conf %endif - - %if %{use_sssd_user} +%if 0%{?rhel} == 9 %files polkit-rules +%endif %{_datadir}/polkit-1/rules.d/* %endif + %files ldap -f sssd_ldap.lang %license COPYING @@ -1098,9 +1116,10 @@ %if %{use_sssd_user} %pre common +! getent passwd sssd >/dev/null || usermod sssd -d /run/sssd >/dev/null || true %if %{use_sysusers} %sysusers_create_compat %{SOURCE1} %else getent group sssd >/dev/null || groupadd -r sssd -getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd +getent passwd sssd >/dev/null || useradd -r -g sssd -d /run/sssd -s /sbin/nologin -c "User for sssd" sssd %endif %endif @@ -1123,4 +1142,5 @@ %__chown -f %{sssd_user}:%{sssd_user} %{_var}/log/%{name}/*.log || true %__chown -f %{sssd_user}:%{sssd_user} %{secdbpath}/*.ldb || true +%__chown -f %{sssd_user}:%{sssd_user} %{gpocachepath}/* || true %preun common @@ -1177,5 +1197,5 @@ %preun client if [ $1 -eq 0 ] ; then - /usr/sbin/alternatives --remove cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so + /usr/sbin/alternatives --remove cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so || true fi diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/conf_macros.m4 /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/conf_macros.m4 --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/conf_macros.m4 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/conf_macros.m4 2024-10-01 18:30:01.000000000 +0000 @@ -735,20 +735,4 @@ ]) -AC_DEFUN([WITH_IFP], - [ AC_ARG_WITH([infopipe], - [AC_HELP_STRING([--with-infopipe], - [Whether to build with InfoPipe support [yes]] - ) - ], - [with_infopipe=$withval], - with_infopipe=yes - ) - - if test x"$with_infopipe" = xyes; then - AC_DEFINE(BUILD_IFP, 1, [whether to build with InfoPipe support]) - fi - AM_CONDITIONAL([BUILD_IFP], [test x"$with_infopipe" = xyes]) - ]) - AC_DEFUN([WITH_LIBSIFP], [ AC_ARG_WITH([libsifp], diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/confdb/confdb.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/confdb/confdb.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/confdb/confdb.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/confdb/confdb.c 2024-10-01 18:30:01.000000000 +0000 @@ -651,4 +651,9 @@ mode_t old_umask; + if (cdb_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Bad argument\n"); + return EFAULT; + } + cdb = talloc_zero(mem_ctx, struct confdb_ctx); if (!cdb) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/SSSDConfig/sssdoptions.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/SSSDConfig/sssdoptions.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/SSSDConfig/sssdoptions.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/SSSDConfig/sssdoptions.py 2024-10-01 18:30:01.000000000 +0000 @@ -399,4 +399,5 @@ 'ldap_disable_range_retrieval': _('Disable Active Directory range retrieval'), 'ldap_use_ppolicy': _('Use the ppolicy extension'), + 'ldap_ppolicy_pwd_change_threshold': _('Force a password change when remaining grace logins reach or go below this threshold'), # [provider/ldap/id] diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/cfg_rules.ini /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/cfg_rules.ini --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/cfg_rules.ini 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/cfg_rules.ini 2024-10-01 18:30:01.000000000 +0000 @@ -748,4 +748,5 @@ option = ldap_uri option = ldap_use_ppolicy +option = ldap_ppolicy_pwd_change_threshold option = ldap_user_ad_account_expires option = ldap_user_ad_user_account_control @@ -772,4 +773,5 @@ option = ldap_user_object_class option = ldap_user_objectsid +option = ldap_user_passkey option = ldap_user_primary_group option = ldap_user_principal diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/etc/sssd.api.d/sssd-ldap.conf /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/etc/sssd.api.d/sssd-ldap.conf --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/config/etc/sssd.api.d/sssd-ldap.conf 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/config/etc/sssd.api.d/sssd-ldap.conf 2024-10-01 18:30:01.000000000 +0000 @@ -45,4 +45,5 @@ wildcard_limit = int, None, false ldap_use_ppolicy = bool, None, false +ldap_ppolicy_pwd_change_threshold = int, None, false [provider/ldap/id] diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb.h 2024-10-01 18:30:01.000000000 +0000 @@ -31,5 +31,4 @@ #define CACHE_SYSDB_FILE "cache_%s.ldb" #define CACHE_TIMESTAMPS_FILE "timestamps_%s.ldb" -#define LOCAL_SYSDB_FILE "sssd.ldb" #define SYSDB_INDEXES "@INDEXLIST" @@ -135,4 +134,5 @@ #define SYSDB_CCACHE_FILE "ccacheFile" #define SYSDB_DN_FOR_MEMBER_HASH_TABLE "dnForMemberHashTable" +#define SYSDB_AD_SAMACCOUNTNAME "adSAMAccountName" #define SYSDB_ORIG_DN "originalDN" @@ -804,4 +804,5 @@ int sysdb_init_ext(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, + bool create_missing_cache, struct sysdb_upgrade_ctx *upgrade_ctx); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_init.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_init.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_init.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_init.c 2024-10-01 18:30:01.000000000 +0000 @@ -349,55 +349,4 @@ } -static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_context *ldb, - struct sss_domain_info *domain, - const char *cur_version, - const char **_new_version) -{ - errno_t ret; - TALLOC_CTX *tmp_ctx; - const char *version; - struct ldb_context *save_ldb; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - /* The upgrade process depends on having ldb around, yet the upgrade - * function shouldn't set the ldb pointer, only the connect function - * should after it's successful. To avoid hard refactoring, save the - * ldb pointer here and restore in the 'done' handler - */ - save_ldb = sysdb->ldb; - sysdb->ldb = ldb; - - version = talloc_strdup(tmp_ctx, cur_version); - if (version == NULL) { - ret = ENOMEM; - goto done; - } - - DEBUG(SSSDBG_CONF_SETTINGS, - "Upgrading timstamp cache of DB [%s] from version: %s\n", - domain->name, version); - - if (strcmp(version, SYSDB_TS_VERSION_0_1) == 0) { - ret = sysdb_ts_upgrade_01(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - ret = EOK; - -done: - sysdb->ldb = save_ldb; - *_new_version = version; - talloc_free(tmp_ctx); - return ret; -} - static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, @@ -413,4 +362,24 @@ struct ldb_context *save_ldb; + if ((strcmp(cur_version, SYSDB_VERSION_0_1) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_2) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_3) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_4) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_5) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_6) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_7) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_8) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_9) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_10) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_11) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_12) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_13) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_14) == 0) || + (strcmp(cur_version, SYSDB_VERSION_0_15) == 0)) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Cache version is way too old and must be deleted manually\n"); + return EIO; + } + tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -436,95 +405,4 @@ domain->name, version); - if (strcmp(version, SYSDB_VERSION_0_3) == 0) { - ret = sysdb_upgrade_03(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_4) == 0) { - ret = sysdb_upgrade_04(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_5) == 0) { - ret = sysdb_upgrade_05(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_6) == 0) { - ret = sysdb_upgrade_06(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_7) == 0) { - ret = sysdb_upgrade_07(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_8) == 0) { - ret = sysdb_upgrade_08(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_9) == 0) { - ret = sysdb_upgrade_09(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_10) == 0) { - ret = sysdb_upgrade_10(sysdb, domain, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_11) == 0) { - ret = sysdb_upgrade_11(sysdb, domain, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_12) == 0) { - ret = sysdb_upgrade_12(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_13) == 0) { - ret = sysdb_upgrade_13(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_14) == 0) { - ret = sysdb_upgrade_14(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - - if (strcmp(version, SYSDB_VERSION_0_15) == 0) { - ret = sysdb_upgrade_15(sysdb, &version); - if (ret != EOK) { - goto done; - } - } - if (strcmp(version, SYSDB_VERSION_0_16) == 0) { ret = sysdb_upgrade_16(sysdb, &version); @@ -583,4 +461,11 @@ } + if (strcmp(version, SYSDB_VERSION_0_24) == 0) { + ret = sysdb_upgrade_24(sysdb, &version); + if (ret != EOK) { + goto done; + } + } + ret = EOK; done: @@ -789,4 +674,5 @@ ldb, domain, version, &version); if (ret != EOK) { + DEBUG(SSSDBG_TRACE_FUNC, "sysdb_domain_cache_upgrade() failed\n"); goto done; } @@ -857,54 +743,4 @@ ret = sysdb_ts_cache_connect(tmp_ctx, sysdb, domain, &ldb, &version); - switch (ret) { - case ERR_SYSDB_VERSION_TOO_OLD: - if (upgrade_ctx == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, - "DB version too old [%s], expected [%s] for domain %s!\n", - version, SYSDB_VERSION, domain->name); - break; - } - - ret = sysdb_ts_cache_upgrade(tmp_ctx, sysdb, ldb, domain, version, - &version); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Could not upgrade the timestamp ldb file (%d) (%s)\n", - ret, sss_strerror(ret)); - break; - } - - /* The version should now match SYSDB_VERSION. - * If not, it means we didn't match any of the - * known older versions. The DB might be - * corrupt or generated by a newer version of - * SSSD. - */ - ret = sysdb_version_check(SYSDB_TS_VERSION, version); - if (ret == EOK) { - /* The cache has been upgraded. - * We need to reopen the LDB to ensure that - * any changes made above take effect. - */ - ret = sysdb_ldb_reconnect(tmp_ctx, - sysdb->ldb_ts_file, - LDB_FLG_NOSYNC, - &ldb); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, - "Could not reopen the timestamp ldb file (%d) (%s)\n", - ret, sss_strerror(ret)); - } - } - break; - case ERR_SYSDB_VERSION_TOO_NEW: - DEBUG(SSSDBG_MINOR_FAILURE, - "DB version too new [%s], expected [%s] for domain %s!\n", - version, SYSDB_TS_VERSION, domain->name); - break; - default: - break; - } - if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, @@ -926,5 +762,5 @@ if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, - "Could not delete the timestamp ldb file (%d) (%s)\n", + "sysdb_ts_cache_connect() failed after cache deletion [%d]: %s\n", ret, sss_strerror(ret)); } @@ -941,8 +777,10 @@ struct sss_domain_info *domain, const char *db_path, + bool create_missing_cache, struct sysdb_dom_upgrade_ctx *upgrade_ctx, struct sysdb_ctx **_ctx) { TALLOC_CTX *tmp_ctx = NULL; + bool ldb_file_missing; struct sysdb_ctx *sysdb; int ret; @@ -964,4 +802,9 @@ goto done; } + ldb_file_missing = (access(sysdb->ldb_file, F_OK) == -1 && errno == ENOENT); + if (ldb_file_missing && !create_missing_cache) { + ret = ENOENT; + goto done; + } DEBUG(SSSDBG_FUNC_DATA, "DB File for %s: %s\n", domain->name, sysdb->ldb_file); @@ -998,9 +841,10 @@ struct sss_domain_info *domains) { - return sysdb_init_ext(mem_ctx, domains, NULL); + return sysdb_init_ext(mem_ctx, domains, false, NULL); } int sysdb_init_ext(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, + bool create_missing_cache, struct sysdb_upgrade_ctx *upgrade_ctx) { @@ -1011,12 +855,4 @@ struct sysdb_dom_upgrade_ctx *dom_upgrade_ctx; - if (upgrade_ctx != NULL) { - /* check if we have an old sssd.ldb to upgrade */ - ret = sysdb_check_upgrade_02(domains, DB_PATH); - if (ret != EOK) { - return ret; - } - } - tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { @@ -1041,5 +877,5 @@ } - ret = sysdb_domain_init_internal(tmp_ctx, dom, DB_PATH, + ret = sysdb_domain_init_internal(tmp_ctx, dom, DB_PATH, create_missing_cache, dom_upgrade_ctx, &sysdb); if (ret != EOK) { @@ -1065,4 +901,4 @@ { return sysdb_domain_init_internal(mem_ctx, domain, - db_path, false, _ctx); + db_path, false, NULL, _ctx); } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_private.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_private.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_private.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_private.h 2024-10-01 18:30:01.000000000 +0000 @@ -24,4 +24,5 @@ #define __INT_SYS_DB_H__ +#define SYSDB_VERSION_0_25 "0.25" #define SYSDB_VERSION_0_24 "0.24" #define SYSDB_VERSION_0_23 "0.23" @@ -49,5 +50,5 @@ #define SYSDB_VERSION_0_1 "0.1" -#define SYSDB_VERSION SYSDB_VERSION_0_24 +#define SYSDB_VERSION SYSDB_VERSION_0_25 #define SYSDB_BASE_LDIF \ @@ -74,5 +75,4 @@ "@IDXATTR: gidNumber\n" \ "@IDXATTR: lastUpdate\n" \ - "@IDXATTR: dataExpireTimestamp\n" \ "@IDXATTR: originalDN\n" \ "@IDXATTR: nameAlias\n" \ @@ -107,8 +107,9 @@ /* The timestamp cache has its own versioning */ +#define SYSDB_TS_VERSION_0_3 "0.3" #define SYSDB_TS_VERSION_0_2 "0.2" #define SYSDB_TS_VERSION_0_1 "0.1" -#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_2 +#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_3 #define SYSDB_TS_BASE_LDIF \ @@ -118,5 +119,4 @@ "dn: @INDEXLIST\n" \ "@IDXATTR: lastUpdate\n" \ - "@IDXATTR: dataExpireTimestamp\n" \ "\n" \ "dn: cn=sysdb\n" \ @@ -165,26 +165,9 @@ struct sss_domain_info *domain, const char *db_path, + bool create_missing_cache, struct sysdb_dom_upgrade_ctx *upgrade_ctx, struct sysdb_ctx **_ctx); /* Upgrade routines */ -int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver); -int sysdb_check_upgrade_02(struct sss_domain_info *domains, - const char *db_path); -int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char **ver); -int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char **ver); -int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver); -int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_17(struct sysdb_ctx *sysdb, @@ -197,4 +180,5 @@ int sysdb_upgrade_22(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver); +int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver); int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_upgrade.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_upgrade.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/db/sysdb_upgrade.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/db/sysdb_upgrade.c 2024-10-01 18:30:01.000000000 +0000 @@ -137,1472 +137,4 @@ } -/* serach all groups that have a memberUid attribute. - * change it into a member attribute for a user of same domain. - * remove the memberUid attribute - * add the new member attribute - * finally stop indexing memberUid - * upgrade version to 0.2 - */ -int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver) -{ - struct ldb_message_element *el; - struct ldb_result *res; - struct ldb_dn *basedn; - struct ldb_dn *mem_dn; - struct ldb_message *msg; - const struct ldb_val *val; - /* No change needed because this version has objectclass group */ - const char *filter = "(&(memberUid=*)(objectclass=group))"; - const char *attrs[] = { "memberUid", NULL }; - const char *mdn; - char *domain; - int ret, i, j; - TALLOC_CTX *tmp_ctx; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(tmp_ctx, ldb, SYSDB_VERSION_0_2, &ctx); - if (ret) { - talloc_free(tmp_ctx); - return ret; - } - - basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); - if (!basedn) { - ret = EIO; - goto done; - } - - ret = ldb_search(ldb, tmp_ctx, &res, - basedn, LDB_SCOPE_SUBTREE, - attrs, "%s", filter); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - for (i = 0; i < res->count; i++) { - el = ldb_msg_find_element(res->msgs[i], "memberUid"); - if (!el) { - DEBUG(SSSDBG_CRIT_FAILURE, - "memberUid is missing from message [%s], skipping\n", - ldb_dn_get_linearized(res->msgs[i]->dn)); - continue; - } - - /* create modification message */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = res->msgs[i]->dn; - - ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* get domain name component value */ - val = ldb_dn_get_component_val(res->msgs[i]->dn, 2); - domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length); - if (!domain) { - ret = ENOMEM; - goto done; - } - - for (j = 0; j < el->num_values; j++) { - mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER, - (const char *)el->values[j].data, domain); - if (!mem_dn) { - ret = ENOMEM; - goto done; - } - - mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn)); - if (!mdn) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - talloc_zfree(mem_dn); - } - - /* ok now we are ready to modify the entry */ - ret = ldb_modify(ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - talloc_zfree(msg); - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_check_upgrade_02(struct sss_domain_info *domains, - const char *db_path) -{ - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_context *ldb; - char *ldb_file; - struct sysdb_ctx *sysdb; - struct sss_domain_info *dom; - struct ldb_message_element *el; - struct ldb_message *msg; - struct ldb_result *res; - struct ldb_dn *verdn; - const char *version = NULL; - bool do_02_upgrade = false; - bool ctx_trans = false; - int ret; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ldb_file = talloc_asprintf(tmp_ctx, "%s/"LOCAL_SYSDB_FILE, - db_path); - if (ldb_file == NULL) { - ret = ENOMEM; - goto exit; - } - - ret = sysdb_ldb_connect(tmp_ctx, ldb_file, 0, &ldb); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); - return ret; - } - - verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); - if (!verdn) { - ret = EIO; - goto exit; - } - - ret = ldb_search(ldb, tmp_ctx, &res, - verdn, LDB_SCOPE_BASE, - NULL, NULL); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto exit; - } - if (res->count > 1) { - ret = EIO; - goto exit; - } - - if (res->count == 1) { - el = ldb_msg_find_element(res->msgs[0], "version"); - if (el) { - if (el->num_values != 1) { - ret = EINVAL; - goto exit; - } - version = talloc_strndup(tmp_ctx, - (char *)(el->values[0].data), - el->values[0].length); - if (!version) { - ret = ENOMEM; - goto exit; - } - - if (strcmp(version, SYSDB_VERSION) == 0) { - /* all fine, return */ - ret = EOK; - goto exit; - } - - DEBUG(SSSDBG_CONF_SETTINGS, - "Upgrading DB from version: %s\n", version); - - if (strcmp(version, SYSDB_VERSION_0_1) == 0) { - /* convert database */ - ret = sysdb_upgrade_01(ldb, &version); - if (ret != EOK) goto exit; - } - - if (strcmp(version, SYSDB_VERSION_0_2) == 0) { - /* need to convert database to split files */ - do_02_upgrade = true; - } - - } - } - - if (!do_02_upgrade) { - /* not a v2 upgrade, return and let the normal code take over any - * further upgrade */ - ret = EOK; - goto exit; - } - - /* == V2->V3 UPGRADE == */ - - DEBUG(SSSDBG_IMPORTANT_INFO, - "UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3); - - /* ldb uses posix locks, - * posix is stupid and kills all locks when you close *any* file - * descriptor associated to the same file. - * Therefore we must close and reopen the ldb file here */ - - /* == Backup and reopen ldb == */ - - /* close */ - talloc_zfree(ldb); - - /* backup*/ - ret = backup_file(ldb_file, SSSDBG_FATAL_FAILURE); - if (ret != EOK) { - goto exit; - } - - /* reopen */ - ret = sysdb_ldb_connect(tmp_ctx, ldb_file, 0, &ldb); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); - return ret; - } - - /* open a transaction */ - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to start ldb transaction! (%d)\n", ret); - ret = EIO; - goto exit; - } - - /* == Upgrade contents == */ - - for (dom = domains; dom; dom = dom->next) { - struct ldb_dn *domain_dn; - struct ldb_dn *users_dn; - struct ldb_dn *groups_dn; - int i; - - /* create new dom db */ - ret = sysdb_domain_init_internal(tmp_ctx, dom, - db_path, false, &sysdb); - if (ret != EOK) { - goto done; - } - - ret = ldb_transaction_start(sysdb->ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to start ldb transaction! (%d)\n", ret); - ret = EIO; - goto done; - } - ctx_trans = true; - - /* search all entries for this domain in local, - * copy them all in the new database, - * then remove them from local */ - - domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_DOM_BASE, dom->name); - if (!domain_dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_search(ldb, tmp_ctx, &res, - domain_dn, LDB_SCOPE_SUBTREE, - NULL, NULL); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - /* - * dom->sysdb->ldb is not initialized, - * so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn() - */ - users_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_TMPL_USER_BASE, dom->name); - if (!users_dn) { - ret = ENOMEM; - goto done; - } - - /* - * dom->sysdb->ldb is not initialized, - * so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn() - */ - groups_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_TMPL_GROUP_BASE, dom->name); - if (!groups_dn) { - ret = ENOMEM; - goto done; - } - - for (i = 0; i < res->count; i++) { - - struct ldb_dn *orig_dn; - - msg = res->msgs[i]; - - /* skip pre-created congtainers */ - if ((ldb_dn_compare(msg->dn, domain_dn) == 0) || - (ldb_dn_compare(msg->dn, users_dn) == 0) || - (ldb_dn_compare(msg->dn, groups_dn) == 0)) { - continue; - } - - /* regenerate the DN against the new ldb as it may have different - * casefolding rules (example: name changing from case insensitive - * to case sensitive) */ - orig_dn = msg->dn; - msg->dn = ldb_dn_new(msg, sysdb->ldb, - ldb_dn_get_linearized(orig_dn)); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_add(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_FATAL_FAILURE, "WARNING: Could not add entry %s," - " to new ldb file! (%d [%s])\n", - ldb_dn_get_linearized(msg->dn), - ret, ldb_errstring(sysdb->ldb)); - } - - ret = ldb_delete(ldb, orig_dn); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_FATAL_FAILURE, - "WARNING: Could not remove entry %s," - " from old ldb file! (%d [%s])\n", - ldb_dn_get_linearized(orig_dn), - ret, ldb_errstring(ldb)); - } - } - - /* now remove the basic containers from local */ - /* these were optional so debug at level 9 in case - * of failure just for tracing */ - ret = ldb_delete(ldb, groups_dn); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," - " from old ldb file! (%d [%s])\n", - ldb_dn_get_linearized(groups_dn), - ret, ldb_errstring(ldb)); - } - ret = ldb_delete(ldb, users_dn); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," - " from old ldb file! (%d [%s])\n", - ldb_dn_get_linearized(users_dn), - ret, ldb_errstring(ldb)); - } - ret = ldb_delete(ldb, domain_dn); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," - " from old ldb file! (%d [%s])\n", - ldb_dn_get_linearized(domain_dn), - ret, ldb_errstring(ldb)); - } - - ret = ldb_transaction_commit(sysdb->ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to commit ldb transaction! (%d)\n", ret); - ret = EIO; - goto done; - } - ctx_trans = false; - - talloc_zfree(domain_dn); - talloc_zfree(groups_dn); - talloc_zfree(users_dn); - talloc_zfree(res); - } - - /* conversion done, upgrade version number */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - ret = ldb_transaction_commit(ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to commit ldb transaction! (%d)\n", ret); - ret = EIO; - goto exit; - } - - ret = EOK; - -done: - if (ret != EOK) { - if (ctx_trans) { - ret = ldb_transaction_cancel(sysdb->ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to cancel ldb transaction! (%d)\n", ret); - } - } - ret = ldb_transaction_cancel(ldb); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to cancel ldb transaction! (%d)\n", ret); - } - } - -exit: - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_4, &ctx); - if (ret) { - return ret; - } - - /* Make this database case-sensitive */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_5, &ctx); - if (ret) { - return ret; - } - - /* Add new index */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* Rebuild memberuid and memberoif attributes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - ret = ldb_add(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_6, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Add Index for dataExpireTimestamp */ - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* Add index to speed up ONELEVEL searches */ - ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "@IDXONE", "1"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_7, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Case insensitive search for originalDN */ - ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_8, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Add Index for nameAlias */ - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "@IDXATTR", "nameAlias"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_9, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Add Index for servicePort and serviceProtocol */ - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "@IDXATTR", "servicePort"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_string(msg, "@IDXATTR", "serviceProtocol"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_10, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Add Index for ipHostNumber and ipNetworkNumber */ - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_string(msg, "@IDXATTR", "sudoUser"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char **ver) -{ - - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_result *res; - struct ldb_message *msg; - struct ldb_message *user; - struct ldb_message_element *memberof_el; - const char *name; - struct ldb_dn *basedn; - /* No change needed because version 10 has objectclass user */ - const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))"; - const char *attrs[] = { "name", "memberof", NULL }; - struct upgrade_ctx *ctx; - int i, j; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_11, &ctx); - if (ret) { - return ret; - } - - /* - * dom->sysdb->ldb is not initialized, - * so ldb_dn_new_fmt() shouldn't be changed to sysdb_*_base_dn() - */ - basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_TMPL_USER_BASE, domain->name); - if (basedn == NULL) { - ret = EIO; - goto done; - } - - ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, - attrs, "%s", filter); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - for (i = 0; i < res->count; i++) { - user = res->msgs[i]; - memberof_el = ldb_msg_find_element(user, "memberof"); - if (memberof_el == NULL) { - ret = EINVAL; - goto done; - } - - name = ldb_msg_find_attr_as_string(user, "name", NULL); - if (name == NULL) { - ret = EIO; - goto done; - } - - DEBUG(SSSDBG_TRACE_LIBS, "User [%s] is a member of %d groups\n", - name, memberof_el->num_values); - - for (j = 0; j < memberof_el->num_values; j++) { - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = ENOMEM; - goto done; - } - - msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]); - if (msg->dn == NULL) { - ret = ENOMEM; - goto done; - } - - if (!ldb_dn_validate(msg->dn)) { - DEBUG(SSSDBG_MINOR_FAILURE, "DN validation failed during " - "upgrade: [%s]\n", - memberof_el->values[j].data); - talloc_zfree(msg); - continue; - } - - ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "ghost", name); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - DEBUG(SSSDBG_TRACE_FUNC, "Adding ghost [%s] to entry [%s]\n", - name, ldb_dn_get_linearized(msg->dn)); - - ret = sss_ldb_modify_permissive(sysdb->ldb, msg); - talloc_zfree(msg); - if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { - /* If we failed adding the ghost user(s) because the values already - * exist, they were probably propagated from a parent that was - * upgraded before us. Mark the group as expired so that it is - * refreshed on next request. - */ - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = ENOMEM; - goto done; - } - - msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]); - if (msg->dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, - LDB_FLAG_MOD_REPLACE, NULL); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = sss_ldb_modify_permissive(sysdb->ldb, msg); - talloc_zfree(msg); - if (ret != LDB_SUCCESS) { - goto done; - } - } else if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - } - - DEBUG(SSSDBG_TRACE_FUNC, "Removing fake user [%s]\n", - ldb_dn_get_linearized(user->dn)); - - ret = ldb_delete(sysdb->ldb, user->dn); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char **ver) -{ - TALLOC_CTX *tmp_ctx; - errno_t ret; - struct ldb_result *res; - struct ldb_message *entry; - const char *key; - const char *value; - struct ldb_message_element *memberof_el; - struct ldb_dn *memberof_dn; - struct ldb_dn *basedn; - const struct ldb_val *val; - const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY, - SYSDB_AUTOFS_ENTRY_VALUE, - SYSDB_MEMBEROF, - NULL }; - struct upgrade_ctx *ctx; - size_t i, j; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_12, &ctx); - if (ret) { - return ret; - } - - basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, - AUTOFS_ENTRY_SUBDIR, domain->name); - if (basedn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, - attrs, "(objectClass=%s)", SYSDB_AUTOFS_ENTRY_OC); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - DEBUG(SSSDBG_TRACE_LIBS, "Found %d autofs entries\n", res->count); - - for (i = 0; i < res->count; i++) { - entry = res->msgs[i]; - key = ldb_msg_find_attr_as_string(entry, - SYSDB_AUTOFS_ENTRY_KEY, NULL); - value = ldb_msg_find_attr_as_string(entry, - SYSDB_AUTOFS_ENTRY_VALUE, NULL); - memberof_el = ldb_msg_find_element(entry, SYSDB_MEMBEROF); - - if (key && value && memberof_el) { - for (j = 0; j < memberof_el->num_values; j++) { - memberof_dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, - &(memberof_el->values[j])); - if (!memberof_dn) { - DEBUG(SSSDBG_OP_FAILURE, "Cannot convert memberof into DN, skipping\n"); - continue; - } - - val = ldb_dn_get_rdn_val(memberof_dn); - if (!val) { - DEBUG(SSSDBG_OP_FAILURE, "Cannot get map name from map DN\n"); - continue; - } - - ret = sysdb_save_autofsentry(domain, - (const char *) val->data, - key, value, NULL, 0, 0); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Cannot save autofs entry [%s]-[%s] into map %s\n", - key, value, val->data); - continue; - } - } - - } - - /* Delete the old entry if it was either processed or incomplete */ - DEBUG(SSSDBG_TRACE_LIBS, "Deleting [%s]\n", - ldb_dn_get_linearized(entry->dn)); - - ret = ldb_delete(sysdb->ldb, entry->dn); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Cannot delete old autofs entry %s\n", - ldb_dn_get_linearized(entry->dn)); - continue; - } - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_13, &ctx); - if (ret) { - return ret; - } - - /* add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* add index for sshKnownHostsExpire */ - ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_string(msg, "@IDXATTR", "sshKnownHostsExpire"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver) -{ - struct upgrade_ctx *ctx; - struct ldb_result *dom_res; - struct ldb_result *res; - struct ldb_dn *basedn; - const char *attrs[] = { "cn", "name", NULL }; - const char *tmp_str; - errno_t ret; - int i, j, l, n; - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx); - if (ret) { - return ret; - } - - basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE); - if (!basedn) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); - ret = EIO; - goto done; - } - - ret = ldb_search(sysdb->ldb, ctx, &dom_res, - basedn, LDB_SCOPE_ONELEVEL, - attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to search subdomains\n"); - ret = EIO; - goto done; - } - - for (i = 0; i < dom_res->count; i++) { - - tmp_str = ldb_msg_find_attr_as_string(dom_res->msgs[i], "cn", NULL); - if (tmp_str == NULL) { - DEBUG(SSSDBG_MINOR_FAILURE, - "The object [%s] doesn't have a name\n", - ldb_dn_get_linearized(dom_res->msgs[i]->dn)); - continue; - } - - basedn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_DOM_BASE, tmp_str); - if (!basedn) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to build base dn for subdomain %s\n", tmp_str); - continue; - } - - ret = ldb_search(sysdb->ldb, ctx, &res, - basedn, LDB_SCOPE_SUBTREE, attrs, NULL); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to search subdomain %s\n", tmp_str); - talloc_free(basedn); - continue; - } - - l = ldb_dn_get_comp_num(basedn); - for (j = 0; j < res->count; j++) { - n = ldb_dn_get_comp_num(res->msgs[j]->dn); - if (n <= l + 1) { - /* Do not remove subdomain containers, only their contents */ - continue; - } - ret = ldb_delete(sysdb->ldb, res->msgs[j]->dn); - if (ret) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to delete %s\n", - ldb_dn_get_linearized(res->msgs[j]->dn)); - continue; - } - } - - talloc_free(basedn); - talloc_free(res); - } - - talloc_free(dom_res); - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - return ret; -} - -int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver) -{ - struct upgrade_ctx *ctx; - struct ldb_message *msg; - struct ldb_result *res; - struct ldb_dn *basedn; - struct ldb_dn *newdn; - const char *attrs[] = { SYSDB_NAME, NULL }; - const char *tmp_str; - errno_t ret; - int i; - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_15, &ctx); - if (ret) { - return ret; - } - - basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE); - if (!basedn) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); - ret = EIO; - goto done; - } - - /* create base ranges container */ - msg = ldb_msg_new(ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_RANGE_BASE); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, "cn", "ranges"); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - /* do a synchronous add */ - ret = ldb_add(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to upgrade DB (%d, [%s])!\n", - ret, ldb_errstring(sysdb->ldb)); - ret = EIO; - goto done; - } - talloc_zfree(msg); - - ret = ldb_search(sysdb->ldb, ctx, &res, - basedn, LDB_SCOPE_SUBTREE, attrs, - "objectclass=%s", SYSDB_ID_RANGE_CLASS); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to search range objects\n"); - ret = EIO; - goto done; - } - - /* Failure to convert any range is not fatal. As long as there are no - * left-over objects we can fail to move them around, as they will be - * recreated on the next online access */ - for (i = 0; i < res->count; i++) { - tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); - if (tmp_str == NULL) { - DEBUG(SSSDBG_OP_FAILURE, - "The object [%s] doesn't have a name\n", - ldb_dn_get_linearized(res->msgs[i]->dn)); - ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); - if (ret) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to delete %s\n", - ldb_dn_get_linearized(res->msgs[i]->dn)); - ret = EIO; - goto done; - } - continue; - } - - newdn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_TMPL_RANGE, tmp_str); - if (!newdn) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to create new DN to move [%s]\n", - ldb_dn_get_linearized(res->msgs[i]->dn)); - ret = ENOMEM; - goto done; - } - ret = ldb_rename(sysdb->ldb, res->msgs[i]->dn, newdn); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to move [%s] to [%s]\n", - ldb_dn_get_linearized(res->msgs[i]->dn), - ldb_dn_get_linearized(newdn)); - ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); - if (ret) { - DEBUG(SSSDBG_OP_FAILURE, - "Failed to delete %s\n", - ldb_dn_get_linearized(res->msgs[i]->dn)); - ret = EIO; - goto done; - } - } - talloc_zfree(newdn); - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - return ret; -} - -int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_message *msg; - struct upgrade_ctx *ctx; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_16, &ctx); - if (ret) { - return ret; - } - - /* Add new indexes */ - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); - if (!msg->dn) { - ret = ENOMEM; - goto done; - } - - /* Case insensitive search for canonicalUserPrincipalName */ - ret = ldb_msg_add_empty(msg, SYSDB_CANONICAL_UPN, LDB_FLAG_MOD_ADD, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - ret = ldb_msg_add_string(msg, SYSDB_CANONICAL_UPN, "CASE_INSENSITIVE"); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto done; - } - - /* conversion done, update version number */ - ret = update_version(ctx); - -done: - ret = finish_upgrade(ret, &ctx, ver); - talloc_free(tmp_ctx); - return ret; -} - int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver) { @@ -2350,5 +882,5 @@ if (objects == NULL || objects->count == 0) { - DEBUG(SSSDBG_TRACE_LIBS, "No objects found, nothing to do."); + DEBUG(SSSDBG_TRACE_LIBS, "No objects found, nothing to do.\n"); ret = EOK; goto done; @@ -2821,42 +1353,24 @@ } -int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver) +int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver) { struct upgrade_ctx *ctx; errno_t ret; - struct ldb_message *msg = NULL; - ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_TS_VERSION_0_2, &ctx); + ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_25, &ctx); if (ret) { return ret; } - /* Remove @IDXONE from index */ - talloc_free(msg); - msg = ldb_msg_new(ctx); - if (msg == NULL) { - ret = ENOMEM; - goto done; - } - - msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); - if (msg->dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL); - if (ret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; + ret = sysdb_ldb_mod_index(sysdb, SYSDB_IDX_DELETE, sysdb->ldb, "dataExpireTimestamp"); + if (ret == ENOENT) { /*nothing to delete */ + ret = EOK; } - - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); + if (ret != EOK) { + DEBUG(SSSDBG_TRACE_FUNC, "sysdb_ldb_mod_index() failed [%d]: %s\n", + ret, sss_strerror(ret)); goto done; } - /* conversion done, update version number */ ret = update_version(ctx); Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/examples: logrotate Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/examples: logrotate.in diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/external/crypto.m4 /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/external/crypto.m4 --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/external/crypto.m4 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/external/crypto.m4 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,5 @@ AC_DEFUN([AM_CHECK_LIBCRYPTO], - [PKG_CHECK_MODULES([CRYPTO],[libcrypto]) + [PKG_CHECK_MODULES([CRYPTO], [libcrypto >= 1.0.1], [], + [AC_MSG_ERROR([Please install libcrypto version 1.0.1 or greater])]) PKG_CHECK_MODULES([SSL],[libssl]) ]) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/external/libcurl.m4 /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/external/libcurl.m4 --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/external/libcurl.m4 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/external/libcurl.m4 2024-10-01 18:30:01.000000000 +0000 @@ -3,2 +3,14 @@ PKG_CHECK_MODULES([CURL], [libcurl], [found_libcurl=yes], [found_libcurl=no]) + +AC_MSG_CHECKING([whether libcurl knows CURLOPT_PROTOCOLS_STR]) + +AC_LINK_IFELSE( + [AC_LANG_SOURCE([ +#include +int main () { + return CURLOPT_PROTOCOLS_STR; +}])], + [AC_MSG_RESULT([yes]); AC_DEFINE_UNQUOTED([HAVE_CURLOPT_PROTOCOLS_STR], [1], [CURLOPT_PROTOCOLS_STR available]) ], + [AC_MSG_RESULT([no])] +) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/lib/certmap/sss_cert_content_crypto.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/lib/certmap/sss_cert_content_crypto.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/lib/certmap/sss_cert_content_crypto.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/lib/certmap/sss_cert_content_crypto.c 2024-10-01 18:30:01.000000000 +0000 @@ -35,11 +35,4 @@ #include "lib/certmap/sss_certmap_int.h" -/* backward compatible macros for OpenSSL < 1.1 */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#define ASN1_STRING_get0_data(o) ASN1_STRING_data(o) -#define X509_get_extension_flags(o) ((o)->ex_flags) -#define X509_get_key_usage(o) ((o)->ex_kusage) -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ - #define OID_NTDS_CA_SECURITY_EXT "1.3.6.1.4.1.311.25.2" #define OID_NTDS_OBJECTSID "1.3.6.1.4.1.311.25.2.1" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/Makefile.am /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/Makefile.am --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/Makefile.am 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/Makefile.am 2024-10-01 18:30:01.000000000 +0000 @@ -25,7 +25,4 @@ PAC_RESPONDER_CONDS = ;with_pac_responder endif -if BUILD_IFP -IFP_CONDS = ;with_ifp -endif if BUILD_KCM KCM_CONDS = ;with_kcm @@ -77,5 +74,5 @@ -CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(SSH_KNOWN_HOSTS_PROXY_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SYSTEMD_CONDS)$(KCM_CONDS)$(STAP_CONDS)$(KCM_RENEWAL_CONDS)$(LOCKFREE_CLIENT_CONDS)$(HAVE_INOTIFY_CONDS)$(PASSKEY_CONDS)$(FILES_PROVIDER_CONDS)$(SSSD_NON_ROOT_USER_CONDS)$(SSSD_CONF_SERVICE_USER_CONDS)$(ENUM_CONDS)$(LIBNL_CONDS) +CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(SSH_KNOWN_HOSTS_PROXY_CONDS)$(PAC_RESPONDER_CONDS)$(GPO_CONDS)$(SYSTEMD_CONDS)$(KCM_CONDS)$(STAP_CONDS)$(KCM_RENEWAL_CONDS)$(LOCKFREE_CLIENT_CONDS)$(HAVE_INOTIFY_CONDS)$(PASSKEY_CONDS)$(FILES_PROVIDER_CONDS)$(SSSD_NON_ROOT_USER_CONDS)$(SSSD_CONF_SERVICE_USER_CONDS)$(ENUM_CONDS)$(LIBNL_CONDS) @@ -94,5 +91,5 @@ man_MANS = \ sssd.8 sssd.conf.5 sssd-ldap.5 sssd-ldap-attributes.5 \ - sssd-krb5.5 sssd-simple.5 sss-certmap.5 \ + sssd-krb5.5 sssd-simple.5 sss-certmap.5 sssd-ifp.5 \ sssd_krb5_locator_plugin.8 sssd_krb5_localauth_plugin.8 \ pam_sss.8 pam_sss_gss.8 sss_obfuscate.8 sss_cache.8 sss_debuglevel.8 \ @@ -116,8 +113,4 @@ endif -if BUILD_IFP -man_MANS += sssd-ifp.5 -endif - if BUILD_KCM man_MANS += sssd-kcm.8 diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/include/seealso.xml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/include/seealso.xml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/include/seealso.xml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/include/seealso.xml 2024-10-01 18:30:01.000000000 +0000 @@ -66,10 +66,8 @@ , - - - sssd-ifp - 5 - , - + + sssd-ifp + 5 + , pam_sss8 diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sss_ssh_knownhosts.1.xml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sss_ssh_knownhosts.1.xml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sss_ssh_knownhosts.1.xml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sss_ssh_knownhosts.1.xml 2024-10-01 18:30:01.000000000 +0000 @@ -45,5 +45,5 @@ option: - KnownHostsCommand /usr/bin/sss_ssh_knownhosts %H + KnownHostsCommand /usr/bin/sss_ssh_knownhosts %H Please refer to the @@ -68,8 +68,46 @@ + + + , + + + + When the keys retrieved from the backend do not include + the hostname, this tool will add the unmodified hostname + as provided by the caller. If this flag is set, only the + hostname (no port number) will be added to the keys. + + + + + KEY RETRIEVAL + + The key lines retrieved from the backend are expected to respect the + key format as decribed in the SSH_KNOWN_HOSTS FILE FORMAT + section of sshd + 8. However, returning only + the keytype and the key itself is tolerated, in which case, the + hostname received as parameter will be added before the keytype to + output a correctly formatted line. The hostname will be added + unmodified or just the hostname (no port number), depending on + whether the , + option was provided. + + + When the SSH server is listening on a non-default port, the + backend MUST provide the hostname including the port number in the + correct format and position as part of the key line. For example, + the minimal key line would be: + + [canonical.host.name]:2222 <keytype> <base64-encoded key> + + + + EXIT STATUS diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd-ad.5.xml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd-ad.5.xml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd-ad.5.xml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd-ad.5.xml 2024-10-01 18:30:01.000000000 +0000 @@ -259,10 +259,11 @@ - This option specifies LDAP access control - filter that the user must match in order - to be allowed access. Please note that the - access_provider option must be - explicitly set to ad in order - for this option to have an effect. + Specifies an LDAP access control filter that a user + must match to gain access. The access_provider + option must be explicitly set to ad + for this option to take effect. If you want to use the + ad_access_filter as the only access control + scheme, you must disable GPO based access control + (see option ad_gpo_access_control for details). diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd-ldap.5.xml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd-ldap.5.xml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd-ldap.5.xml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd-ldap.5.xml 2024-10-01 18:30:01.000000000 +0000 @@ -857,6 +857,7 @@ individual files. Typically the file names need to be the hash of the certificate followed by '.0'. - If available, cacertdir_rehash - can be used to create the correct names. + If available, openssl rehash + or c_rehash can be used to + create the correct names. @@ -1489,5 +1490,6 @@ Please note that 'access_provider = ldap' must be set for this feature to work. Also 'ldap_pwd_policy' - must be set to an appropriate password policy. + must be set to shadow or mit_kerberos, these options + do not work with server-side password policies. @@ -1653,4 +1655,23 @@ + + + + ldap_ppolicy_pwd_change_threshold (integer) + + + Forces a password change when server side password + policy controls are enabled and remaining grace + logins returned by the server after the + authentication reach or go below the threshold. + Note that the minimum useful value is 2, as changing + the password consumes 2 additional grace logins, one + to verify the current password and a second one to + perform the password change. + + + Default: 0 + + diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd.conf.5.xml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd.conf.5.xml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/man/sssd.conf.5.xml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/man/sssd.conf.5.xml 2024-10-01 18:30:01.000000000 +0000 @@ -233,10 +233,9 @@ - Supported services: nss, pam + Supported services: nss, pam, ifp , sudo , autofs , ssh , pac - , ifp @@ -4572,4 +4571,15 @@ two-step prompting has to be used. + + Some clients, such as SSH with + 'PasswordAuthentication yes', generate their own prompts + and do not use prompts provided by SSSD or other PAM + modules. Additionally, for SSH with + PasswordAuthentication, if two-factor authentication is + available, SSSD expects that the + credentials entered by the user at the SSH password prompt + will always be the two factors in a single string, even if + two-factor authentication is optional. + diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/monitor/monitor.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/monitor/monitor.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/monitor/monitor.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/monitor/monitor.c 2024-10-01 18:30:01.000000000 +0000 @@ -1557,5 +1557,5 @@ db_up_ctx.cdb = ctx->cdb; - ret = sysdb_init_ext(tmp_ctx, ctx->domains, &db_up_ctx); + ret = sysdb_init_ext(tmp_ctx, ctx->domains, true, &db_up_ctx); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/oidc_child/oidc_child_curl.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/oidc_child/oidc_child_curl.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/oidc_child/oidc_child_curl.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/oidc_child/oidc_child_curl.c 2024-10-01 18:30:01.000000000 +0000 @@ -123,5 +123,9 @@ /* Only allow https */ +#ifdef HAVE_CURLOPT_PROTOCOLS_STR + res = curl_easy_setopt(curl_ctx, CURLOPT_PROTOCOLS_STR, "https"); +#else res = curl_easy_setopt(curl_ctx, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS); +#endif if (res != CURLE_OK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to enforce HTTPS.\n"); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/p11_child/p11_child_openssl.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/p11_child/p11_child_openssl.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/p11_child/p11_child_openssl.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/p11_child/p11_child_openssl.c 2024-10-01 18:30:01.000000000 +0000 @@ -133,13 +133,4 @@ } -#if OPENSSL_VERSION_NUMBER < 0x10100000L -#define TLS_client_method SSLv23_client_method -#define X509_STORE_get0_objects(store) (store->objs) -#define X509_OBJECT_get_type(object) (object->type) -#define X509_OBJECT_get0_X509(object) (object->data.x509) -#define EVP_MD_CTX_free EVP_MD_CTX_destroy -#define X509_CRL_get0_nextUpdate(object) (object->crl->nextUpdate) -#endif - OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, const char *path, @@ -594,9 +585,5 @@ /* See https://wiki.openssl.org/index.php/Library_Initialization for * details. */ -#if OPENSSL_VERSION_NUMBER >= 0x10100000L ret = OPENSSL_init_ssl(0, NULL); -#else - ret = SSL_library_init(); -#endif if (ret != 1) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize OpenSSL.\n"); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_access.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_access.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_access.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_access.h 2024-10-01 18:30:01.000000000 +0000 @@ -50,4 +50,5 @@ hash_table_t *gpo_map_options_table; enum gpo_map_type gpo_default_right; + struct sdap_attr_map *host_attr_map; }; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_gpo.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_gpo.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_gpo.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_gpo.c 2024-10-01 18:30:01.000000000 +0000 @@ -46,4 +46,5 @@ #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_gpo.h" +#include "providers/ad/ad_opts.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_async.h" @@ -2242,4 +2243,14 @@ } + if (state->access_ctx->host_attr_map == NULL) { + ret = sdap_copy_map(state->access_ctx, + ad_2008r2_user_map, SDAP_OPTS_USER, + &state->access_ctx->host_attr_map); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to copy user map.\n"); + goto done; + } + } + subreq = groups_by_user_send(state, state->ev, state->access_ctx->ad_id_ctx->sdap_id_ctx, @@ -2249,4 +2260,6 @@ BE_FILTER_NAME, NULL, + state->access_ctx->host_attr_map, + SDAP_OPTS_USER, true, true); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_opts.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_opts.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ad/ad_opts.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ad/ad_opts.c 2024-10-01 18:30:01.000000000 +0000 @@ -169,4 +169,5 @@ { "ldap_library_debug_level", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_use_ppolicy", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + { "ldap_ppolicy_pwd_change_threshold", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, DP_OPTION_TERMINATOR }; @@ -245,4 +246,5 @@ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, { "ldap_user_email", "mail", SYSDB_USER_EMAIL, NULL }, + { SDAP_ATTR_MAP_NO_OPT, "sAMAccountName", SYSDB_AD_SAMACCOUNTNAME, NULL }, { "ldap_user_passkey", "altSecurityIdentities", SYSDB_USER_PASSKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ipa/ipa_opts.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ipa/ipa_opts.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ipa/ipa_opts.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ipa/ipa_opts.c 2024-10-01 18:30:01.000000000 +0000 @@ -179,4 +179,5 @@ { "ldap_library_debug_level", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_use_ppolicy", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + { "ldap_ppolicy_pwd_change_threshold", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, DP_OPTION_TERMINATOR }; @@ -228,4 +229,5 @@ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, { "ldap_user_email", "mail", SYSDB_USER_EMAIL, NULL }, + { SDAP_ATTR_MAP_NO_OPT, "sAMAccountName", SYSDB_AD_SAMACCOUNTNAME, NULL }, { "ldap_user_passkey", "ipaPassKey", SYSDB_USER_PASSKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/krb5/krb5_child.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/krb5/krb5_child.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/krb5/krb5_child.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/krb5/krb5_child.c 2024-10-01 18:30:01.000000000 +0000 @@ -542,13 +542,4 @@ switch (sss_authtok_get_type(auth_tok)) { - case SSS_AUTHTOK_TYPE_PASSWORD: - ret = sss_authtok_get_password(auth_tok, &pwd, &len); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_password failed.\n"); - return ret; - } - - return tokeninfo_matches_pwd(mem_ctx, ti, pwd, len, out_token, out_pin); - break; case SSS_AUTHTOK_TYPE_2FA_SINGLE: ret = sss_authtok_get_2fa_single(auth_tok, &pwd, &len); @@ -575,5 +566,5 @@ } - return EINVAL; + return EAGAIN; } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.c 2024-10-01 18:30:01.000000000 +0000 @@ -195,5 +195,6 @@ static errno_t check_pwexpire_ldap(struct pam_data *pd, struct sdap_ppolicy_data *ppolicy, - int pwd_exp_warning) + int pwd_exp_warning, + struct sdap_options *opts) { int ret = EOK; @@ -202,4 +203,5 @@ uint32_t *data; uint32_t *ptr; + int pwd_change_thold; if (pwd_exp_warning < 0) { @@ -233,5 +235,17 @@ (uint8_t*)data); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); + DEBUG(SSSDBG_CRIT_FAILURE, + "pam_add_response failed: %s\n", + sss_strerror(ret)); + return ret; + } + + /* + * Either password is expired or this is a grace login. + * Check the grace loging password change threshold. + */ + pwd_change_thold = dp_opt_get_int(opts->basic, SDAP_PPOLICY_PWD_CHANGE_THRESHOLD); + if (pwd_change_thold > 0 && ppolicy->grace > 0 && ppolicy->grace <= pwd_change_thold) { + ret = ERR_PASSWORD_EXPIRED; } } @@ -244,5 +258,6 @@ void *pw_expire_data, struct pam_data *pd, - int pwd_expiration_warning) + int pwd_expiration_warning, + struct sdap_options *opts) { errno_t ret; @@ -258,5 +273,6 @@ case PWEXPIRE_LDAP_PASSWORD_POLICY: ret = check_pwexpire_ldap(pd, pw_expire_data, - pwd_expiration_warning); + pwd_expiration_warning, + opts); break; case PWEXPIRE_NONE: @@ -972,4 +988,5 @@ struct pam_data *pd; struct be_ctx *be_ctx; + struct sdap_auth_ctx *auth_ctx; }; @@ -995,4 +1012,5 @@ state->pd = pd; state->be_ctx = params->be_ctx; + state->auth_ctx = auth_ctx; pd->pam_status = PAM_SYSTEM_ERR; @@ -1061,5 +1079,6 @@ if (ret == EOK) { ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, state->pd, - state->be_ctx->domain->pwd_expiration_warning); + state->be_ctx->domain->pwd_expiration_warning, + state->auth_ctx->opts); if (ret == EINVAL) { /* Unknown password expiration type. */ @@ -1190,5 +1209,5 @@ switch (opts->pwmodify_mode) { case SDAP_PWMODIFY_EXOP: - use_ppolicy = dp_opt_get_int(opts->basic, SDAP_USE_PPOLICY); + use_ppolicy = dp_opt_get_bool(opts->basic, SDAP_USE_PPOLICY); subreq = sdap_exop_modify_passwd_send(state, ev, sh, user_dn, password, new_password, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_auth.h 2024-10-01 18:30:01.000000000 +0000 @@ -44,5 +44,6 @@ void *pw_expire_data, struct pam_data *pd, - errno_t checkb); + int pwd_expiration_warning, + struct sdap_options *opts); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_common.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_common.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_common.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_common.h 2024-10-01 18:30:01.000000000 +0000 @@ -314,4 +314,6 @@ int filter_type, const char *extra_value, + struct sdap_attr_map *user_map, + size_t user_map_cnt, bool noexist_delete, bool set_non_posix); @@ -389,4 +391,9 @@ const char *extra_filter); +char *principal_string_to_samaccountname(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *princ, + const char *realm); + char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, const char *attr_name, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_id.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_id.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_id.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_id.c 2024-10-01 18:30:01.000000000 +0000 @@ -180,4 +180,5 @@ char *user_filter = NULL; char *ep_filter; + char *sam_filter = NULL; req = tevent_req_create(memctx, &state, struct users_get_state); @@ -231,11 +232,15 @@ ctx->opts->user_map[SDAP_AT_USER_PRINC].name, clean_value, ctx->opts->basic); + sam_filter = principal_string_to_samaccountname(state, + ctx->opts->user_map[SDAP_AT_USER_SAMACCOUNTNAME].name, + clean_value, state->domain->realm); /* TODO: Do we have to check the attribute names more carefully? */ - user_filter = talloc_asprintf(state, "(|(%s=%s)(%s=%s)%s)", + user_filter = talloc_asprintf(state, "(|(%s=%s)(%s=%s)%s%s)", ctx->opts->user_map[SDAP_AT_USER_PRINC].name, clean_value, ctx->opts->user_map[SDAP_AT_USER_EMAIL].name, clean_value, - ep_filter == NULL ? "" : ep_filter); + ep_filter == NULL ? "" : ep_filter, + sam_filter == NULL ? "" : sam_filter); talloc_zfree(clean_value); if (user_filter == NULL) { @@ -1145,4 +1150,6 @@ int filter_type; const char *extra_value; + struct sdap_attr_map *user_map; + size_t user_map_cnt; const char **attrs; bool non_posix; @@ -1166,4 +1173,6 @@ int filter_type, const char *extra_value, + struct sdap_attr_map *user_map, + size_t user_map_cnt, bool noexist_delete, bool set_non_posix) @@ -1193,4 +1202,6 @@ state->filter_type = filter_type; state->extra_value = extra_value; + state->user_map = user_map; + state->user_map_cnt = user_map_cnt; state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; @@ -1257,4 +1268,6 @@ sdap_id_op_handle(state->op), state->ctx, + state->user_map, + state->user_map_cnt, state->conn, state->search_bases, @@ -1458,4 +1471,5 @@ ar->filter_type, ar->extra_value, + NULL, 0, noexist_delete, false); break; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_opts.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_opts.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/ldap_opts.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/ldap_opts.c 2024-10-01 18:30:01.000000000 +0000 @@ -136,4 +136,5 @@ { "ldap_library_debug_level", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_use_ppolicy", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + { "ldap_ppolicy_pwd_change_threshold", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, DP_OPTION_TERMINATOR }; @@ -197,4 +198,5 @@ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, { "ldap_user_email", "mail", SYSDB_USER_EMAIL, NULL }, + { SDAP_ATTR_MAP_NO_OPT, NULL, SYSDB_AD_SAMACCOUNTNAME, NULL }, { "ldap_user_passkey", "passkey", SYSDB_USER_PASSKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR @@ -257,4 +259,5 @@ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, { "ldap_user_email", "mail", SYSDB_USER_EMAIL, NULL }, + { SDAP_ATTR_MAP_NO_OPT, NULL, SYSDB_AD_SAMACCOUNTNAME, NULL }, { "ldap_user_passkey", "passkey", SYSDB_USER_PASSKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR @@ -317,4 +320,5 @@ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, { "ldap_user_email", "mail", SYSDB_USER_EMAIL, NULL }, + { SDAP_ATTR_MAP_NO_OPT, "sAMAccountName", SYSDB_AD_SAMACCOUNTNAME, NULL }, { "ldap_user_passkey", "passkey", SYSDB_USER_PASSKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap.h 2024-10-01 18:30:01.000000000 +0000 @@ -239,4 +239,5 @@ SDAP_LIBRARY_DEBUG_LEVEL, SDAP_USE_PPOLICY, + SDAP_PPOLICY_PWD_CHANGE_THRESHOLD, SDAP_OPTS_BASIC /* opts counter */ @@ -292,4 +293,5 @@ SDAP_AT_USER_CERT, SDAP_AT_USER_EMAIL, + SDAP_AT_USER_SAMACCOUNTNAME, SDAP_AT_USER_PASSKEY, @@ -421,4 +423,5 @@ }; #define SDAP_ATTR_MAP_TERMINATOR { NULL, NULL, NULL, NULL } +#define SDAP_ATTR_MAP_NO_OPT "==NO OPTION==" struct sdap_search_base { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_access.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_access.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_access.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_access.c 2024-10-01 18:30:01.000000000 +0000 @@ -808,5 +808,5 @@ ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd, - domain->pwd_expiration_warning); + domain->pwd_expiration_warning, opts); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async.h 2024-10-01 18:30:01.000000000 +0000 @@ -159,4 +159,6 @@ struct sdap_handle *sh, struct sdap_id_ctx *id_ctx, + struct sdap_attr_map *user_map, + size_t user_map_cnt, struct sdap_id_conn_ctx *conn, struct sdap_search_base **search_bases, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_initgroups.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_initgroups.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_initgroups.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_initgroups.c 2024-10-01 18:30:01.000000000 +0000 @@ -786,4 +786,6 @@ struct sysdb_ctx *sysdb; struct sdap_options *opts; + struct sdap_attr_map *user_map; + size_t user_map_cnt; struct sss_domain_info *dom; struct sdap_handle *sh; @@ -813,4 +815,6 @@ struct tevent_context *ev, struct sdap_options *opts, + struct sdap_attr_map *user_map, + size_t user_map_cnt, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, @@ -829,4 +833,6 @@ state->ev = ev; state->opts = opts; + state->user_map = user_map; + state->user_map_cnt = user_map_cnt; state->sysdb = sysdb; state->dom = dom; @@ -969,5 +975,5 @@ subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh, state->orig_dn, - state->opts->user_map[SDAP_AT_USER_MEMBEROF].name, + state->user_map[SDAP_AT_USER_MEMBEROF].name, sdap_attrs, num_maps, maps, timeout); if (!subreq) { @@ -2698,4 +2704,6 @@ struct sysdb_ctx *sysdb; struct sdap_options *opts; + struct sdap_attr_map *user_map; + size_t user_map_cnt; struct sss_domain_info *dom; struct sdap_domain *sdom; @@ -2732,4 +2740,6 @@ struct sdap_handle *sh, struct sdap_id_ctx *id_ctx, + struct sdap_attr_map *user_map, + size_t user_map_cnt, struct sdap_id_conn_ctx *conn, struct sdap_search_base **search_bases, @@ -2755,4 +2765,10 @@ state->ev = ev; state->opts = id_ctx->opts; + state->user_map = user_map; + state->user_map_cnt = user_map_cnt; + if (state->user_map == NULL) { + state->user_map = id_ctx->opts->user_map; + state->user_map_cnt = id_ctx->opts->user_map_cnt; + } state->dom = sdom->dom; state->sysdb = sdom->dom->sysdb; @@ -2786,5 +2802,5 @@ switch (filter_type) { case BE_FILTER_SECID: - search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; + search_attr = state->user_map[SDAP_AT_USER_OBJECTSID].name; ret = sss_filter_sanitize(state, state->filter_value, &clean_name); @@ -2795,5 +2811,5 @@ break; case BE_FILTER_UUID: - search_attr = state->opts->user_map[SDAP_AT_USER_UUID].name; + search_attr = state->user_map[SDAP_AT_USER_UUID].name; ret = sss_filter_sanitize(state, state->filter_value, &clean_name); @@ -2813,15 +2829,15 @@ ep_filter = get_enterprise_principal_string_filter(state, - state->opts->user_map[SDAP_AT_USER_PRINC].name, + state->user_map[SDAP_AT_USER_PRINC].name, clean_name, state->opts->basic); state->user_base_filter = talloc_asprintf(state, "(&(|(%s=%s)(%s=%s)%s)(objectclass=%s)", - state->opts->user_map[SDAP_AT_USER_PRINC].name, + state->user_map[SDAP_AT_USER_PRINC].name, clean_name, - state->opts->user_map[SDAP_AT_USER_EMAIL].name, + state->user_map[SDAP_AT_USER_EMAIL].name, clean_name, ep_filter == NULL ? "" : ep_filter, - state->opts->user_map[SDAP_OC_USER].name); + state->user_map[SDAP_OC_USER].name); if (state->user_base_filter == NULL) { talloc_zfree(req); @@ -2829,5 +2845,5 @@ } } else { - search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; + search_attr = state->user_map[SDAP_AT_USER_NAME].name; ret = sss_parse_internal_fqname(state, filter_value, @@ -2861,5 +2877,5 @@ talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)", search_attr, clean_name, - state->opts->user_map[SDAP_OC_USER].name); + state->user_map[SDAP_OC_USER].name); if (!state->user_base_filter) { talloc_zfree(req); @@ -2878,5 +2894,5 @@ state->user_base_filter = talloc_asprintf_append(state->user_base_filter, "(%s=*))", - id_ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); + state->user_map[SDAP_AT_USER_OBJECTSID].name); } else { /* When not ID-mapping or looking up app users, make sure there @@ -2884,6 +2900,6 @@ state->user_base_filter = talloc_asprintf_append(state->user_base_filter, "(&(%s=*)(!(%s=0))))", - id_ctx->opts->user_map[SDAP_AT_USER_UID].name, - id_ctx->opts->user_map[SDAP_AT_USER_UID].name); + state->user_map[SDAP_AT_USER_UID].name, + state->user_map[SDAP_AT_USER_UID].name); } if (!state->user_base_filter) { @@ -2893,6 +2909,6 @@ ret = build_attrs_from_map(state, - state->opts->user_map, - state->opts->user_map_cnt, + state->user_map, + state->user_map_cnt, NULL, &state->user_attrs, NULL); if (ret) { @@ -2991,5 +3007,5 @@ state->user_search_bases[state->user_base_iter]->scope, state->filter, state->user_attrs, - state->opts->user_map, state->opts->user_map_cnt, + state->user_map, state->user_map_cnt, state->timeout, false); @@ -3180,4 +3196,5 @@ case SDAP_SCHEMA_IPA_V1: subreq = sdap_initgr_nested_send(state, state->ev, state->opts, + state->user_map, state->user_map_cnt, state->sysdb, state->dom, state->sh, state->orig_user, state->grp_attrs); @@ -3378,5 +3395,5 @@ ret = sdap_attrs_get_sid_str( tmp_ctx, opts->idmap_ctx, state->orig_user, - opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name, + state->user_map[SDAP_AT_USER_OBJECTSID].sys_name, &sid_str); if (ret != EOK) goto done; @@ -3393,5 +3410,5 @@ ret = sysdb_attrs_get_uint32_t( state->orig_user, - opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, + state->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, &primary_gid); if (ret != EOK) { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_nested_groups.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_nested_groups.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_nested_groups.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_nested_groups.c 2024-10-01 18:30:01.000000000 +0000 @@ -1634,4 +1634,6 @@ DEBUG(SSSDBG_OP_FAILURE, "Unknown entry type [%s]!\n", state->current_member->dn); + DEBUG(SSSDBG_OP_FAILURE, "Consider enabling sssd-ldap option " + "ldap_ignore_unreadable_references\n"); ret = EINVAL; goto done; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_users.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_users.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_users.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_async_users.c 2024-10-01 18:30:01.000000000 +0000 @@ -183,4 +183,5 @@ const char *user_name = NULL; const char *fullname = NULL; + const char *samaccountname = NULL; const char *pwd; const char *gecos; @@ -204,4 +205,5 @@ char *p1; char *p2; + char *new_upn; bool is_posix = true; @@ -270,5 +272,26 @@ if (opts->schema_type == SDAP_SCHEMA_AD) { + /* construct canonical UPN from sAMAccountName to help Samba and also + * to allow us to lookup user via UPN */ ret = sysdb_attrs_get_string(attrs, + opts->user_map[SDAP_AT_USER_SAMACCOUNTNAME].sys_name, + &samaccountname); + if (ret == EOK) { + ret = ENOENT; + new_upn = talloc_asprintf(memctx, "%s@%s", samaccountname, + dom->realm); + if (new_upn != NULL){ + ret = sysdb_attrs_add_string(user_attrs, + SYSDB_CANONICAL_UPN, new_upn); + DEBUG(SSSDBG_TRACE_FUNC, + "Storing Canonical UPN %s for user %s\n", new_upn, + user_name); + } + } + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Unable to obtain Canonical UPN for %s\n", user_name); + } + ret = sysdb_attrs_get_string(attrs, opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname); if (ret == EOK) { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_utils.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_utils.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/providers/ldap/sdap_utils.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/providers/ldap/sdap_utils.c 2024-10-01 18:30:01.000000000 +0000 @@ -207,4 +207,37 @@ } +/* we check the principal and if it contains our realm, then we drop it + * for the comparison with sAMAccountName */ + +char *principal_string_to_samaccountname(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *princ, + const char *realm) +{ + char *p; + + if (attr_name == NULL || princ == NULL || realm == NULL) { + return NULL; + } + + p = strchr(princ, '@'); + if (p == NULL) { + return NULL; + } + + if (strcasecmp(p + 1,realm) == 0) { + return talloc_asprintf(mem_ctx, "(%s=%.*s)", attr_name, + (int) (p - princ), + princ); + } + return NULL; +} + +/* enterprise principals are expected that their realm is from the local domain + * and the request is send to the local KDC which then will look at the part + * before the realm with the \@ and will try to figure out from which trusted + * realm the principal might be coming from and if it found wound it will tell + * the client to forward the request to this realm */ + char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, const char *attr_name, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/resolv/async_resolv.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/resolv/async_resolv.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/resolv/async_resolv.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/resolv/async_resolv.c 2024-10-01 18:30:01.000000000 +0000 @@ -28,5 +28,4 @@ #include -#include #include #include @@ -795,5 +794,5 @@ static int resolv_gethostbyname_dns_parse(struct gethostbyname_dns_state *state, - int status, unsigned char *abuf, int alen); + unsigned char *abuf, int alen); static struct tevent_req * @@ -936,5 +935,5 @@ } - ret = resolv_gethostbyname_dns_parse(state, status, abuf, alen); + ret = resolv_gethostbyname_dns_parse(state, abuf, alen); if (ret != EOK) { tevent_req_error(req, ret); @@ -947,9 +946,10 @@ static int resolv_gethostbyname_dns_parse(struct gethostbyname_dns_state *state, - int status, unsigned char *abuf, int alen) + unsigned char *abuf, int alen) { struct hostent *hostent = NULL; int naddrttls; errno_t ret; + int status; void *addr = NULL; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/resolv/async_resolv.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/resolv/async_resolv.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/resolv/async_resolv.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/resolv/async_resolv.h 2024-10-01 18:30:01.000000000 +0000 @@ -28,4 +28,5 @@ #include +#define CARES_NO_DEPRECATED #include diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/responder/nss/nss_protocol_pwent.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/responder/nss/nss_protocol_pwent.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/responder/nss/nss_protocol_pwent.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/responder/nss/nss_protocol_pwent.c 2024-10-01 18:30:01.000000000 +0000 @@ -124,4 +124,5 @@ hd_ctx.domain = domain->name; hd_ctx.upn = upn; + hd_ctx.flatname = domain->flat_name; homedir = sss_nss_get_homedir_override(mem_ctx, msg, nss_ctx, domain, &hd_ctx); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/responder/pam/pamsrv_cmd.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/responder/pam/pamsrv_cmd.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/responder/pam/pamsrv_cmd.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/responder/pam/pamsrv_cmd.c 2024-10-01 18:30:01.000000000 +0000 @@ -555,7 +555,20 @@ } - ret = sysdb_attrs_add_bool(attrs, SYSDB_LOCAL_SMARTCARD_AUTH, sc_allow); - if (ret != EOK) { - goto fail; + if (sc_allow) { + /* Only set SYSDB_LOCAL_SMARTCARD_AUTH to 'true' but never to + * 'false'. The krb5 backend will only returns that Smartcard + * authentication is available if a Smartcard is present. That means + * if the user authenticates with a different method and a Smartcard + * is not present at this time 'sc_allow' will be 'false' and might + * overwrite a 'true' value written during a previous authentication + * attempt where a Smartcard was present. To avoid this we only write + * 'true' values. Since the default if SYSDB_LOCAL_SMARTCARD_AUTH is + * missing is 'false' local Smartcard authentication (offline) will + * still only be enabled if online Smartcard authentication was + * detected. */ + ret = sysdb_attrs_add_bool(attrs, SYSDB_LOCAL_SMARTCARD_AUTH, sc_allow); + if (ret != EOK) { + goto fail; + } } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/autofs/autofs_test_client.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/autofs/autofs_test_client.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/autofs/autofs_test_client.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/autofs/autofs_test_client.c 2024-10-01 18:30:01.000000000 +0000 @@ -72,6 +72,4 @@ } - poptFreeContext(pc); - requested_protocol = pc_protocol; protocol = _sss_auto_protocol_version(requested_protocol); @@ -79,4 +77,5 @@ fprintf(stderr, "Unsupported protocol version: %u -> %u\n", requested_protocol, protocol); + poptFreeContext(pc); exit(EXIT_FAILURE); } @@ -86,4 +85,5 @@ fprintf(stderr, "setautomntent failed [%d]: %s\n", ret, strerror(ret)); + poptFreeContext(pc); exit(EXIT_FAILURE); } @@ -142,7 +142,9 @@ fprintf(stderr, "endautomntent failed [%d]: %s\n", ret, strerror(ret)); + poptFreeContext(pc); exit(EXIT_FAILURE); } printf("endautomntent done for %s\n", mapname); + poptFreeContext(pc); return 0; } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/pam_sss.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/pam_sss.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/pam_sss.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/pam_sss.c 2024-10-01 18:30:01.000000000 +0000 @@ -50,4 +50,5 @@ #include "util/authtok-utils.h" #include "util/dlinklist.h" +#include "util/memory_erase.h" #include @@ -172,5 +173,5 @@ { if (pi->pam_authtok != NULL) { - _pam_overwrite_n((void *)pi->pam_authtok, pi->pam_authtok_size); + sss_erase_mem_securely((void *)pi->pam_authtok, pi->pam_authtok_size); free((void *)pi->pam_authtok); pi->pam_authtok = NULL; @@ -178,5 +179,5 @@ if (pi->pam_newauthtok != NULL) { - _pam_overwrite_n((void *)pi->pam_newauthtok, pi->pam_newauthtok_size); + sss_erase_mem_securely((void *)pi->pam_newauthtok, pi->pam_newauthtok_size); free((void *)pi->pam_newauthtok); pi->pam_newauthtok = NULL; @@ -184,5 +185,5 @@ if (pi->first_factor != NULL) { - _pam_overwrite_n((void *)pi->first_factor, strlen(pi->first_factor)); + sss_erase_mem_securely((void *)pi->first_factor, strlen(pi->first_factor)); free((void *)pi->first_factor); pi->first_factor = NULL; @@ -305,8 +306,8 @@ if (null_strcmp(answer, resp[0].resp) != 0) { logger(pamh, LOG_NOTICE, "Passwords do not match."); - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); if (answer != NULL) { - _pam_overwrite((void *) answer); + sss_erase_mem_securely((void *) answer, strlen(answer)); free(answer); answer = NULL; @@ -323,5 +324,5 @@ goto failed; } - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); } else { @@ -331,5 +332,5 @@ } else { answer = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); if(answer == NULL) { @@ -1617,5 +1618,5 @@ done: if (buf != NULL ) { - _pam_overwrite_n((void *)buf, rd.len); + sss_erase_mem_securely((void *)buf, rd.len); free(buf); } @@ -1643,5 +1644,5 @@ } else { pi->pam_authtok = strdup(answer); - _pam_overwrite((void *)answer); + sss_erase_mem_securely((void *)answer, strlen(answer)); free(answer); answer=NULL; @@ -1657,4 +1658,5 @@ static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi, + bool second_factor_optional, const char *prompt_fa1, const char *prompt_fa2) { @@ -1707,11 +1709,28 @@ } - if (resp[1].resp == NULL || *(resp[1].resp) == '\0' - || (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0 - && strcmp(resp[0].resp, resp[1].resp) == 0)) { + if (resp[1].resp == NULL || *(resp[1].resp) == '\0') { /* Missing second factor, assume first factor contains combined 2FA - * credentials. - * Special handling for SSH with password authentication. Combined - * 2FA credentials are used but SSH puts them in both responses. */ + * credentials if the second factor is not optional. If it is optional + * then it is assumed that the first factor contain the password. */ + pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); + if (pi->pam_authtok == NULL) { + D(("strndup failed.")); + ret = PAM_BUF_ERR; + goto done; + } + pi->pam_authtok_size = strlen(pi->pam_authtok) + 1; + pi->pam_authtok_type = second_factor_optional + ? SSS_AUTHTOK_TYPE_PASSWORD + : SSS_AUTHTOK_TYPE_2FA_SINGLE; + } else if (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0 + && strcmp(resp[0].resp, resp[1].resp) == 0) { + /* Special handling for SSH with password authentication (ssh's + * 'PasswordAuthentication' option. In this mode the ssh client + * directly prompts the user for a password and the prompts we are + * sending are ignored. Since we send two prompts ssh * will create two + * response as well with the same content. We assume that the combined + * 2FA credentials are used even if the second factor is optional + * because there is no indication about the intention of the user. As a + * result we prefer the more secure variant. */ pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); @@ -1722,5 +1741,5 @@ } pi->pam_authtok_size = strlen(pi->pam_authtok) + 1; - pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; + pi->pam_authtok_type = SSS_AUTHTOK_TYPE_2FA_SINGLE; } else { @@ -1764,9 +1783,9 @@ if (resp != NULL) { if (resp[0].resp != NULL) { - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); } if (resp[1].resp != NULL) { - _pam_overwrite((void *)resp[1].resp); + sss_erase_mem_securely((void *)resp[1].resp, strlen(resp[1].resp)); free(resp[1].resp); } @@ -1797,5 +1816,5 @@ } else { pi->pam_authtok = strdup(answer); - _pam_overwrite((void *)answer); + sss_erase_mem_securely((void *)answer, strlen(answer)); free(answer); answer=NULL; @@ -1978,5 +1997,6 @@ if (resp != NULL) { if (resp[pin_idx].resp != NULL) { - _pam_overwrite((void *)resp[pin_idx].resp); + sss_erase_mem_securely((void *)resp[pin_idx].resp, + strlen(resp[pin_idx].resp)); free(resp[pin_idx].resp); } @@ -2261,5 +2281,5 @@ answer = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); resp[0].resp = NULL; @@ -2351,15 +2371,17 @@ done: - _pam_overwrite((void *)answer); - free(answer); - answer=NULL; + if (answer != NULL) { + sss_erase_mem_securely((void *)answer, strlen(answer)); + free(answer); + answer=NULL; + } if (resp != NULL) { if (resp[0].resp != NULL) { - _pam_overwrite((void *)resp[0].resp); + sss_erase_mem_securely((void *)resp[0].resp, strlen(resp[0].resp)); free(resp[0].resp); } if (resp[1].resp != NULL) { - _pam_overwrite((void *)resp[1].resp); + sss_erase_mem_securely((void *)resp[1].resp, strlen(resp[1].resp)); free(resp[1].resp); } @@ -2391,5 +2413,5 @@ } else { pi->pam_newauthtok = strdup(answer); - _pam_overwrite((void *)answer); + sss_erase_mem_securely((void *)answer, strlen(answer)); free(answer); answer=NULL; @@ -2488,6 +2510,11 @@ break; case PC_TYPE_2FA: - ret = prompt_2fa(pamh, pi, pc_get_2fa_1st_prompt(pi->pc[c]), - pc_get_2fa_2nd_prompt(pi->pc[c])); + if (pi->password_prompting) { + ret = prompt_2fa(pamh, pi, true, pc_get_2fa_1st_prompt(pi->pc[c]), + pc_get_2fa_2nd_prompt(pi->pc[c])); + } else { + ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]), + pc_get_2fa_2nd_prompt(pi->pc[c])); + } break; case PC_TYPE_2FA_SINGLE: @@ -2565,8 +2592,8 @@ && pi->otp_challenge != NULL)) { if (pi->password_prompting) { - ret = prompt_2fa(pamh, pi, _("First Factor: "), + ret = prompt_2fa(pamh, pi, true, _("First Factor: "), _("Second Factor (optional): ")); } else { - ret = prompt_2fa(pamh, pi, _("First Factor: "), + ret = prompt_2fa(pamh, pi, false, _("First Factor: "), _("Second Factor: ")); } @@ -2737,8 +2764,10 @@ && pi->otp_challenge != NULL)) { if (pi->password_prompting) { - ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), + ret = prompt_2fa(pamh, pi, true, + _("First Factor (Current Password): "), _("Second Factor (optional): ")); } else { - ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "), + ret = prompt_2fa(pamh, pi, false, + _("First Factor (Current Password): "), _("Second Factor: ")); } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_authorizedkeys.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_authorizedkeys.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_authorizedkeys.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_authorizedkeys.c 2024-10-01 18:30:01.000000000 +0000 @@ -108,5 +108,5 @@ /* print results */ for (i = 0; i < ent->num_pubkeys; i++) { - ret = sss_ssh_print_pubkey(&ent->pubkeys[i], NULL); + ret = sss_ssh_print_pubkey(&ent->pubkeys[i], NULL, NULL); if (ret != EOK && ret != EINVAL) { DEBUG(SSSDBG_CRIT_FAILURE, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhosts.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhosts.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhosts.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhosts.c 2024-10-01 18:30:01.000000000 +0000 @@ -30,6 +30,56 @@ #include "sss_client/ssh/sss_ssh_client.h" + +/* + * Parse the received hostname, which is expected in the format described in + * the “SSH_KNOWN_HOSTS FILE FORMAT” section of sshd(8). The parsed host name + * and port are returned as strings allocated with malloc(3), and not talloc(3), + * and must be freed by the caller. + * + * Some of the recognized formats are not expected from ssh, but it is easier + * to identify them and useful in the case the tool is launched manually by a + * user. + * + * If any of the expected values (host or port) is not found, their respective + * output arguments will NOT be modified. + */ +static errno_t parse_ssh_host(const char *ssh_host, + const char **_host, const char **_port) +{ + int values; + + /* Host name between brackets and with a port number. + * ssh can use this format. + */ + values = sscanf(ssh_host, "[%m[^]]]:%ms", _host, _port); + if (values == 2) { + return EOK; + } + /* Just a host name enclosed between brackets. + * ssh is not expected to use this format but... who knows? + */ + if (values == 1) { + return EOK; + } + + /* A host name without brackets but with a port number. + * This is not expected from ssh, but users will certainly use it. + */ + values = sscanf(ssh_host, "%m[^:]:%ms", _host, _port); + if (values == 2) { + return EOK; + } + /* A host name without brackets or port number. + * This is probably the most common case. + */ + if (values == 1) { + return EOK; + } + + return EINVAL; +} + static errno_t known_hosts(TALLOC_CTX *mem_ctx, const char *domain, - const char *host, struct sss_ssh_ent **_ent) + const char *ssh_host, int only_host_name) { errno_t ret; @@ -37,13 +87,23 @@ struct addrinfo *ai = NULL; char canonhost[NI_MAXHOST]; + const char *host = NULL; + const char *port = NULL; const char *canonname = NULL; struct sss_ssh_ent *ent = NULL; + size_t i; - if (_ent == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "NULL _ent received\n"); - ERROR("Internal error\n"); - return EINVAL; + /* WARNING: + * Memory for host and port is allocated with malloc(3) instead of talloc(3) + */ + ret = parse_ssh_host(ssh_host, &host, &port); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Failed to parse the host name: %s\n", ssh_host); + goto done; } + DEBUG(SSSDBG_FUNC_DATA, "Parsed hostname: %s, port: %s\n", + host, port == NULL ? "default" : port); + /* Canonicalize the host name in case the user used an alias or IP address */ memset(&ai_hint, 0, sizeof(struct addrinfo)); ai_hint.ai_family = AF_UNSPEC; @@ -52,9 +112,8 @@ ai_hint.ai_flags = AI_NUMERICHOST; - DEBUG(SSSDBG_FUNC_DATA, "Looking up canonical name for: %s\n", host); - ret = getaddrinfo(host, NULL, &ai_hint, &ai); + ret = getaddrinfo(host, port, &ai_hint, &ai); if (ret != EOK) { ai_hint.ai_flags = AI_CANONNAME; - ret = getaddrinfo(host, NULL, &ai_hint, &ai); + ret = getaddrinfo(host, port, &ai_hint, &ai); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -66,5 +125,5 @@ } else { ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, - canonhost, NI_MAXHOST, NULL, 0, NI_NAMEREQD); + canonhost, sizeof(canonhost), NULL, 0, NI_NAMEREQD); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -90,8 +149,26 @@ } - *_ent = ent; + /* Print the results. + * We pass the host name to handle the case when the key doesn't include + * the host name */ + for (i = 0; i < ent->num_pubkeys; i++) { + ret = sss_ssh_print_pubkey(&ent->pubkeys[i], + only_host_name ? host : ssh_host, + host); + if (ret != EOK && ret != EINVAL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "ssh_ssh_print_pubkey() failed (%d): %s\n", + ret, strerror(ret)); + goto done; + } + } + ret = EOK; done: + talloc_free(ent); + /* These two strings were allocated with malloc() */ + free(discard_const(host)); + free(discard_const(port)); if (ai != NULL) { freeaddrinfo(ai); @@ -104,4 +181,5 @@ TALLOC_CTX *mem_ctx = NULL; int pc_debug = SSSDBG_TOOLS_DEFAULT; + int pc_only_host_name = false; const char *pc_domain = NULL; const char *pc_host = NULL; @@ -111,10 +189,10 @@ _("The debug level to run with"), NULL }, { "domain", 'd', POPT_ARG_STRING, &pc_domain, 0, - _("The SSSD domain to use"), NULL }, + _("The SSSD domain to use"), _("domain name") }, + { "only-host-name", 'o', POPT_ARG_VAL, &pc_only_host_name, true, + _("When the key has no host name, add only the host name"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; - struct sss_ssh_ent *ent; - size_t i; int ret; errno_t res; @@ -155,13 +233,4 @@ } - /* look up the public keys */ - res = known_hosts(mem_ctx, pc_domain, pc_host, &ent); - if (res != EOK) { - /* On a successful execution, even if no key was found, - * ssh expects EXIT_SUCCESS. */ - ret = (res == ENOENT ? EXIT_SUCCESS : EXIT_FAILURE); - goto fini; - } - /* If the other side closes its end of the pipe, we don't want this tool * to exit abruptly, but to finish gracefully instead because the valid @@ -170,13 +239,11 @@ signal(SIGPIPE, SIG_IGN); - /* print results */ - for (i = 0; i < ent->num_pubkeys; i++) { - ret = sss_ssh_print_pubkey(&ent->pubkeys[i], pc_host); - if (ret != EOK && ret != EINVAL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "ssh_ssh_print_pubkey() failed (%d): %s\n", - ret, strerror(ret)); - goto fini; - } + /* look up the public keys */ + res = known_hosts(mem_ctx, pc_domain, pc_host, pc_only_host_name); + if (res != EOK) { + /* On a successful execution, even if no key was found, + * ssh expects EXIT_SUCCESS. */ + ret = (res == ENOENT ? EXIT_SUCCESS : EXIT_FAILURE); + goto fini; } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhostsproxy.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhostsproxy.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhostsproxy.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/ssh/sss_ssh_knownhostsproxy.c 2024-10-01 18:30:01.000000000 +0000 @@ -311,5 +311,5 @@ if (ent != NULL) { for (size_t i = 0; i < ent->num_pubkeys; i++) { - ret = sss_ssh_print_pubkey(&ent->pubkeys[i], NULL); + ret = sss_ssh_print_pubkey(&ent->pubkeys[i], NULL, NULL); if (ret != EOK && ret != EINVAL) { DEBUG(SSSDBG_CRIT_FAILURE, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/sss_pam_macros.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/sss_pam_macros.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/sss_client/sss_pam_macros.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/sss_client/sss_pam_macros.h 2024-10-01 18:30:01.000000000 +0000 @@ -26,33 +26,4 @@ #define _SSS_PAM_MACROS_H -/* Older versions of the pam development headers do not include the - * _pam_overwrite_n(n,x) macro. This implementation is copied from - * the Fedora 11 _pam_macros.h. - */ -#ifdef HAVE_SECURITY__PAM_MACROS_H -# include -#endif /* HAVE_SECURITY__PAM_MACROS_H */ - -#ifndef _pam_overwrite -#define _pam_overwrite(x) \ -do { \ - register char *__xx__; \ - if ((__xx__=(x))) \ - while (*__xx__) \ - *__xx__++ = '\0'; \ -} while (0) -#endif /* _pam_overwrite */ - -#ifndef _pam_overwrite_n -#define _pam_overwrite_n(x,n) \ -do { \ - register char *__xx__; \ - register unsigned int __i__ = 0; \ - if ((__xx__=(x))) \ - for (;__i__confdb, "FILES", + ret = test_domain_init(test_ctx, test_ctx->confdb, "FILES", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_auth.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_auth.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_auth.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_auth.c 2024-10-01 18:30:01.000000000 +0000 @@ -31,7 +31,9 @@ #include "tests/common.h" #include "providers/ldap/ldap_auth.h" +#include "providers/ldap/ldap_opts.h" #include "tests/cmocka/test_expire_common.h" struct check_pwexpire_policy_wrap_indata { + struct sdap_options *opts; enum pwexpire type; void *time_fmt; @@ -44,5 +46,6 @@ (struct check_pwexpire_policy_wrap_indata*) in; - ret = check_pwexpire_policy(data->type, data->time_fmt, NULL, 0); + ret = check_pwexpire_policy(data->type, data->time_fmt, + NULL, 0, data->opts); *(errno_t*)_out = ret; } @@ -53,4 +56,15 @@ enum pwexpire type = PWEXPIRE_KERBEROS; errno_t ret; + struct sdap_options *opts; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_new(NULL); + + opts = talloc_zero(mem_ctx, struct sdap_options); + assert_non_null(opts); + + ret = dp_copy_defaults(opts, default_basic_opts, + SDAP_OPTS_BASIC, &opts->basic); + assert_int_equal(ret, ERR_OK); tc = talloc_get_type(*state, struct expire_test_ctx); @@ -58,17 +72,18 @@ ret = check_pwexpire_policy(type, - (void*) tc->invalid_longer_format, NULL, 0); + (void*) tc->invalid_longer_format, + NULL, 0, opts); assert_int_equal(ret, ERR_TIMESPEC_NOT_SUPPORTED); ret = check_pwexpire_policy(type, (void*) tc->invalid_format, - NULL, 0); + NULL, 0, opts); assert_int_equal(ret, ERR_TIMESPEC_NOT_SUPPORTED); ret = check_pwexpire_policy(type, (void*) tc->past_time, - NULL, 0); + NULL, 0, opts); assert_int_equal(ret, ERR_PASSWORD_EXPIRED); ret = check_pwexpire_policy(type, (void*) tc->future_time, - NULL, 0); + NULL, 0, opts); assert_int_equal(ret, EOK); @@ -77,4 +92,5 @@ data.type = type; data.time_fmt = (void*)tc->future_time; + data.opts = opts; expire_test_tz("GST-2", check_pwexpire_policy_wrap, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_id_cleanup.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_id_cleanup.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_id_cleanup.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_ldap_id_cleanup.c 2024-10-01 18:30:01.000000000 +0000 @@ -100,5 +100,5 @@ assert_int_equal(ret, EOK); - ret = sssd_domain_init(test_ctx, test_ctx->confdb, "FILES", + ret = test_domain_init(test_ctx, test_ctx->confdb, "FILES", TESTS_PATH, &test_ctx->domain); assert_int_equal(ret, EOK); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_sysdb_views.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_sysdb_views.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/cmocka/test_sysdb_views.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/cmocka/test_sysdb_views.c 2024-10-01 18:30:01.000000000 +0000 @@ -108,5 +108,5 @@ assert_int_equal(ret, EOK); - ret = sssd_domain_init(test_ctx, test_ctx->confdb, "FILES", + ret = test_domain_init(test_ctx, test_ctx->confdb, "FILES", TESTS_PATH, &test_ctx->domain); assert_int_equal(ret, EOK); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/common.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/common.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/common.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/common.h 2024-10-01 18:30:01.000000000 +0000 @@ -93,4 +93,10 @@ void reset_ldb_errstrings(struct sss_domain_info *dom); +errno_t test_domain_init(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *domain_name, + const char *db_path, + struct sss_domain_info **_domain); + struct sss_test_ctx * create_multidom_test_ctx(TALLOC_CTX *mem_ctx, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/common_dom.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/common_dom.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/common_dom.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/common_dom.c 2024-10-01 18:30:01.000000000 +0000 @@ -182,4 +182,32 @@ } +errno_t test_domain_init(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *domain_name, + const char *db_path, + struct sss_domain_info **_domain) +{ + /* This is a replacement of `sssd_domain_init()` + * that uses `sysdb_domain_init_internal()` instead of `sysdb_domain_init()` + * under the hood to let tests create sysdb cache files + */ + int ret; + + ret = confdb_get_domain(cdb, domain_name, _domain); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Error retrieving domain configuration.\n"); + return ret; + } + + ret = sysdb_domain_init_internal(mem_ctx, *_domain, + db_path, true, NULL, &(*_domain)->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Error opening cache database.\n"); + return ret; + } + + return EOK; +} + static errno_t mock_domain(TALLOC_CTX *mem_ctx, @@ -193,7 +221,7 @@ /* initialize sysdb */ - ret = sssd_domain_init(mem_ctx, cdb, name, db_path, &domain); + ret = test_domain_init(mem_ctx, cdb, name, db_path, &domain); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "sssd_domain_init() of %s failed " + DEBUG(SSSDBG_CRIT_FAILURE, "test_domain_init() of %s failed " "[%d]: %s\n", name, ret, sss_strerror(ret)); goto done; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/dlopen-tests.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/dlopen-tests.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/dlopen-tests.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/dlopen-tests.c 2024-10-01 18:30:01.000000000 +0000 @@ -49,9 +49,7 @@ { "pam_sss.so", { LIBPFX"pam_sss.so", NULL } }, { "pam_sss_gss.so", { LIBPFX"pam_sss_gss.so", NULL } }, -#ifdef BUILD_IFP #ifdef BUILD_LIBSIFP { "libsss_simpleifp.so", { LIBPFX"libsss_simpleifp.so", NULL } }, #endif /* BUILD_LIBSIFP */ -#endif /* BUILD_IFP */ #ifdef BUILD_SUDO { "libsss_sudo.so", { LIBPFX"libsss_sudo.so", NULL } }, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg/Makefile.am /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/intg/Makefile.am --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg/Makefile.am 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/intg/Makefile.am 2024-10-01 18:30:01.000000000 +0000 @@ -24,9 +24,7 @@ test_sssctl.py \ files_ops.py \ - test_files_ops.py \ test_files_provider.py \ kdc.py \ krb5utils.py \ - test_kcm.py \ test_pac_responder.py \ data/ad_data.ldif \ @@ -39,10 +37,8 @@ test_ssh_pubkey.py \ test_pam_responder.py \ - test_sudo.py \ test_resolver.py \ conftest.py \ sssd_hosts.py \ sssd_nets.py \ - test_confdb.py \ test_sss_cache.py \ $(NULL) Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg: test_confdb.py Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg: test_files_ops.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg/test_infopipe.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/intg/test_infopipe.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg/test_infopipe.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/intg/test_infopipe.py 2024-10-01 18:30:01.000000000 +0000 @@ -814,43 +814,2 @@ assert str(ex) == \ "sbus.Error.NoCA: Certificate authority file not found" - - -def test_list_by_attr(dbus_system_bus, ldap_conn, sanity_rfc2307): - users = get_user_by_attr(dbus_system_bus, "extraName", "user2") - assert len(users) == 2 - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1002' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user2_40app' in users - - users = get_user_by_attr(dbus_system_bus, "extraName", "user*") - assert len(users) == 6 - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1001' in users - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1002' in users - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1003' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user1_40app' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user2_40app' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user3_40app' in users - - users = get_user_by_attr(dbus_system_bus, "extraName", "nouser*") - assert len(users) == 0 - - users = get_user_by_attr(dbus_system_bus, "noattr", "*") - assert len(users) == 0 - - -def test_list_by_name(dbus_system_bus, ldap_conn, sanity_rfc2307): - users = get_user_by_name(dbus_system_bus, "user2") - assert len(users) == 2 - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1002' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user2_40app' in users - - users = get_user_by_name(dbus_system_bus, "user*") - assert len(users) == 6 - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1001' in users - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1002' in users - assert '/org/freedesktop/sssd/infopipe/Users/LDAP/1003' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user1_40app' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user2_40app' in users - assert '/org/freedesktop/sssd/infopipe/Users/app/user3_40app' in users - - users = get_user_by_name(dbus_system_bus, "nouser*") - assert len(users) == 0 Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg: test_kcm.py Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/intg: test_sudo.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/ad/test_adparameters_ported.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/ad/test_adparameters_ported.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/ad/test_adparameters_ported.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/ad/test_adparameters_ported.py 2024-10-01 18:30:01.000000000 +0000 @@ -190,5 +190,5 @@ -@pytest.mark.flaky(reruns=3, reruns_delay=30) +@pytest.mark.flaky(max_runs=3) @pytest.mark.adparameters @pytest.mark.usefixtures("change_client_hostname") diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/conftest.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/conftest.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/conftest.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/conftest.py 2024-10-01 18:30:01.000000000 +0000 @@ -183,5 +183,6 @@ client.client_install_pkgs() client.update_resolv_conf(session_multihost.ad[1].ip) - client.clear_sssd_cache() + # Sssd is not configured yet so we do not start it here. + client.clear_sssd_cache(start=False) client.systemsssdauth(realm, ad_host) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/test_multidomain.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/test_multidomain.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/test_multidomain.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/admultidomain/test_multidomain.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,3 @@ import re - import pytest @@ -194,2 +193,69 @@ assert getent2.returncode == 0, f'Could not find child_user1@{child_domain}!' assert getent3.returncode == 0, f'Could not find tree_user1@{tree_domain}!' + + @pytest.mark.ticket(bz=1913284, jira=["SSSD-3092", "RHEL-4974"]) + @staticmethod + def test_0004_bz1913284_keytab_as_nonroot(multihost, newhostname, adchildjoin): + """ + :title: IDM-SSSD-TC: ad_provider: forests: krb5_kt_start_seq_get failed: + Permission denied when running as unprivileged user sssd + :id: 53a6871e-95a6-4865-9e61-1e12815ec35b + :setup: + 1. Configure parent and child domain + 2. Join client to child domain + :steps: + 1. Lookup user from child domain + 2. Lookup user from parent domain + 3. Check log for a keytab error + :expectedresults: + 1. Parent user is found + 2. Child user is found + 3. The permission denied error is not present in log. + :customerscenario: True + :bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1913284 + """ + adchildjoin(membersw='adcli') + ad_domain = multihost.ad[0].domainname + child_domain = multihost.ad[1].domainname + ad_server = multihost.ad[1].hostname + + # Configure sssd + client = sssdTools(multihost.client[0], multihost.ad[1]) + if client.sssd_user != "sssd": + pytest.skip("The test is not applicable without non-root fetaure (sssd 2.10+)!") + multihost.client[0].service_sssd('stop') + client.backup_sssd_conf() + dom_section = f'domain/{client.get_domain_section_name()}' + sssd_params = { + 'ad_domain': child_domain, + 'debug_level': '9', + 'use_fully_qualified_names': 'True', + 'ad_server': ad_server, + 'cache_credentials': 'True', + } + client.sssd_conf(dom_section, sssd_params) + client.clear_sssd_cache() + + # Search for the user in root domain + getent_root_user1 = multihost.client[0].run_command( + f'getent passwd user1@{ad_domain}', + raiseonerr=False + ) + # Search for the user in child domain + getent_child_user1 = multihost.client[0].run_command( + f'getent passwd child_user1@{child_domain}', + raiseonerr=False + ) + # Download sssd log + log_str = multihost.client[0].get_file_contents( + f"/var/log/sssd/sssd_{multihost.ad[1].domainname.lower()}.log"). \ + decode('utf-8') + client.restore_sssd_conf() + client.clear_sssd_cache() + + # Evaluate test results + assert getent_root_user1.returncode == 0 + assert getent_child_user1.returncode == 0 + assert "krb5_kt_start_seq_get failed: Permission denied" not in log_str + assert "Failed to read keytab [FILE:/etc/krb5.keytab]: No " \ + "suitable principal found in keytab" not in log_str diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/conftest.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/conftest.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/conftest.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/conftest.py 2024-10-01 18:30:01.000000000 +0000 @@ -1192,54 +1192,18 @@ session_multihost.client[0].put_file_contents('/etc/sysconfig/sssd', contents) - start_journald = 'systemctl start systemd-journald' - session_multihost.client[0].run_command(start_journald) + restart_journald = 'systemctl restart systemd-journald' + session_multihost.client[0].run_command(restart_journald) def remove_journalsssd(): """ Remove /etc/sysconfig/sssd""" cmd = 'rm -f /etc/sysconfig/sssd' - stop_journald = 'systemctl stop systemd-journald' + restart_journald = 'systemctl restart systemd-journald' restart_sssd = 'systemctl restart sssd' session_multihost.client[0].run_command(cmd) - session_multihost.client[0].run_command(stop_journald) + session_multihost.client[0].run_command(restart_journald) session_multihost.client[0].run_command(restart_sssd) request.addfinalizer(remove_journalsssd) -@pytest.fixture(scope='class') -def update_journald_conf(session_multihost, request): - """ - Update journald.conf - To turn off any kind of rate limiting, set RateLimitIntervalSec value to 0. - """ - cmd = session_multihost.client[0].run_command( - 'test -f /etc/systemd/journald.conf', raiseonerr=False) - if cmd.returncode == 0: - j_config = '/etc/systemd/journald.conf' - else: - j_config = '/usr/lib/systemd/journald.conf' - - bkup_cmd = f'cp -f {j_config} /tmp/journald.conf.bkup' - session_multihost.client[0].run_command(bkup_cmd, raiseonerr=False) - up_ratelimit = 'RateLimitIntervalSec=0' - journald_conf = session_multihost.client[0].get_file_contents( - j_config) - if isinstance(journald_conf, bytes): - contents = journald_conf.decode('utf-8') - else: - contents = journald_conf - contents = contents.replace(up_ratelimit, '') + up_ratelimit - session_multihost.client[0].put_file_contents(j_config, contents) - session_multihost.client[0].run_command( - "systemctl daemon-reload", raiseonerr=False) - session_multihost.client[0].run_command( - "systemctl restart systemd-journald", raiseonerr=False) - - def restore_journalsssd(): - """ Restore journalsssd.conf """ - bkup_cmd = f'cp -f /tmp/journald.conf.bkup {j_config}' - session_multihost.client[0].run_command(bkup_cmd) - request.addfinalizer(restore_journalsssd) - - @pytest.fixture(scope="class") def enable_autofs_schema(session_multihost, request): @@ -1609,4 +1573,6 @@ # ==================== Session Scoped Fixtures ================ + + @pytest.fixture(scope="session", autouse=True) # pylint: disable=unused-argument diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_automount.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_automount.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_automount.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_automount.py 2024-10-01 18:30:01.000000000 +0000 @@ -521,4 +521,5 @@ client.firewall_port('ALL', 'delall') client.service_ctrl("stop", "firewalld") + multihost.client[0].run_command("iptables -F") time.sleep(60) cmd2 = client.service_ctrl("start", "autofs") diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_journald.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_journald.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_journald.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_journald.py 2024-10-01 18:30:01.000000000 +0000 @@ -15,5 +15,5 @@ @pytest.mark.usefixtures('setup_sssd', 'create_posix_usersgroups', - 'update_journald_conf', 'write_journalsssd') + 'write_journalsssd') @pytest.mark.journald class TestJournald(object): Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests: test_offline.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_proxy.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_proxy.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_proxy.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/alltests/test_proxy.py 2024-10-01 18:30:01.000000000 +0000 @@ -41,5 +41,5 @@ add_user = 'useradd foo1' # delete user - del_user = 'userdel -r foo1' + del_user = 'userdel -rf foo1' multihost.client[0].run_command(add_user) domain_params = {'id_provider': 'proxy', Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost: basic diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/custom_log.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/custom_log.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/custom_log.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/custom_log.py 2024-10-01 18:30:01.000000000 +0000 @@ -41,6 +41,8 @@ test_name = test_name.translate( str.maketrans('":<>|*? [/', "----------", "]()")) - logdir = os.path.join(os.path.dirname(self.config.option.log_file), - 'logs') + if self.config.option.log_file: + logdir = os.path.join(os.path.dirname(self.config.option.log_file), 'logs') + else: + logdir = os.path.join(os.getcwd(), 'logs') os.makedirs(logdir, exist_ok=True) logpath = os.path.join(logdir, f'{test_name}.log') diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/fixtures.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/fixtures.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/fixtures.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/fixtures.py 2024-10-01 18:30:01.000000000 +0000 @@ -110,2 +110,36 @@ request.addfinalizer(remove_test_dir) + + +@pytest.fixture(scope='session', autouse=True) +def disable_journald_rate_limit(session_multihost, request): + """ + Update journald.conf + To turn off any kind of rate limiting, set RateLimitIntervalSec value to 0. + """ + cmd = session_multihost.client[0].run_command( + 'test -f /etc/systemd/journald.conf', raiseonerr=False) + if cmd.returncode == 0: + j_config = '/etc/systemd/journald.conf' + else: + j_config = '/usr/lib/systemd/journald.conf' + + bkup_cmd = f'cp -Zpf {j_config} /tmp/journald.conf.bkup' + session_multihost.client[0].run_command(bkup_cmd, raiseonerr=False) + up_ratelimit = 'RateLimitIntervalSec=0' + journald_conf = session_multihost.client[0].get_file_contents( + j_config) + if isinstance(journald_conf, bytes): + contents = journald_conf.decode('utf-8') + else: + contents = journald_conf + contents = contents.replace(up_ratelimit, '') + up_ratelimit + session_multihost.client[0].put_file_contents(j_config, contents) + session_multihost.client[0].run_command( + "systemctl restart systemd-journald", raiseonerr=False) + + def restore_journalsssd(): + """ Restore journalsssd.conf """ + bkup_cmd = f'cp -Zpf /tmp/journald.conf.bkup {j_config}' + session_multihost.client[0].run_command(bkup_cmd) + request.addfinalizer(restore_journalsssd) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/qe_class.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/qe_class.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/qe_class.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/qe_class.py 2024-10-01 18:30:01.000000000 +0000 @@ -149,4 +149,5 @@ return cmd.returncode self.run_command('journalctl -xeu sssd.service', raiseonerr=False) + self.run_command('cat /var/log/sssd/sssd.log', raiseonerr=False) raise SSSDException(f'Unable to {action} sssd', 1) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/utils.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/utils.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/utils.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/multihost/sssd/testlib/common/utils.py 2024-10-01 18:30:01.000000000 +0000 @@ -211,25 +211,38 @@ def update_resolv_conf(self, ip_addr): - """ Update /etc/resolv.conf with Windows AD IP address + """ Set nameserver to specific ip address (Like AD server) - :param str ip_addr: IP Address to be added in resolv.conf + :param str ip_addr: IP Address to be set :return: None """ - self.multihost.log.info("Add ip addr %s in resolv.conf" % ip_addr) - nameserver = 'nameserver %s\n' % ip_addr - resolv_conf = self.multihost.get_file_contents('/etc/resolv.conf') - if isinstance(resolv_conf, bytes): - contents = resolv_conf.decode('utf-8') + self.multihost.log.info(f"Set dns to ip addr: {ip_addr}") + cmd = self.multihost.run_command(f'readlink /etc/resolv.conf', raiseonerr=False) + if 'stub-resolv.conf' in cmd.stdout_text: + # Try to change dns settings on a machine with systemd-resolved + self.set_dns_systemd_resolved(ip_addr) else: - contents = resolv_conf - contents = nameserver + contents.replace(nameserver, '') - # Chattr will not work on symlink (like from systemd resolved) - # so we ignore result - self.multihost.run_command("chattr -i /etc/resolv.conf", raiseonerr=False) - self.multihost.put_file_contents('/etc/resolv.conf', contents) - self.multihost.run_command("chattr +i /etc/resolv.conf", raiseonerr=False) - # Try to change dns settings on a machine with systemd.resolved - change_stub = f"sed -ie 's/#\?DNS=.*/DNS={ip_addr}/' /etc/systemd/resolved.conf" - self.multihost.run_command(change_stub, raiseonerr=False) + nameserver = 'nameserver %s\n' % ip_addr + resolv_conf = self.multihost.get_file_contents('/etc/resolv.conf') + if isinstance(resolv_conf, bytes): + contents = resolv_conf.decode('utf-8') + else: + contents = resolv_conf + contents = nameserver + contents.replace(nameserver, '') + # Chattr will not work on symlink (like from systemd resolved) + # so we ignore result + self.multihost.run_command("chattr -i /etc/resolv.conf", raiseonerr=False) + self.multihost.put_file_contents('/etc/resolv.conf', contents) + self.multihost.run_command("chattr +i /etc/resolv.conf", raiseonerr=False) + + def set_dns_systemd_resolved(self, ip_addr): + """ Configure systemd-resolved with an IP address + + :param str ip_addr: IP Address to be used + :return: None + """ + self.multihost.log.info(f"Configuring systemd-resolved to use: {ip_addr}") + change_dns = rf"sed -ie 's/#\?DNS=.*/DNS={ip_addr}/'" + for x in ['/etc/systemd/resolved.conf', '/usr/lib/systemd/resolved.conf']: + self.multihost.run_command(f'{change_dns} {x}', raiseonerr=False) self.multihost.run_command( "systemctl restart systemd-resolved", raiseonerr=False diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/sysdb-tests.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/sysdb-tests.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/sysdb-tests.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/sysdb-tests.c 2024-10-01 18:30:01.000000000 +0000 @@ -152,5 +152,5 @@ } - ret = sssd_domain_init(test_ctx, test_ctx->confdb, "FILES", + ret = test_domain_init(test_ctx, test_ctx->confdb, "FILES", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/sysdb_ssh-tests.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/sysdb_ssh-tests.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/sysdb_ssh-tests.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/sysdb_ssh-tests.c 2024-10-01 18:30:01.000000000 +0000 @@ -130,5 +130,5 @@ } - ret = sssd_domain_init(test_ctx, test_ctx->confdb, "FILES", + ret = test_domain_init(test_ctx, test_ctx->confdb, "FILES", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/data: test_ipa Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/data/test_passkey: readme.md Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/data: test_sss_ssh_knownhosts diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/mhc.yaml /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/mhc.yaml --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/mhc.yaml 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/mhc.yaml 2024-10-01 18:30:01.000000000 +0000 @@ -37,5 +37,6 @@ os: family: windows - ssh: + conn: + type: ssh username: Administrator@ad.test password: vagrant diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/pytest.ini /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/pytest.ini --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/pytest.ini 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/pytest.ini 2024-10-01 18:30:01.000000000 +0000 @@ -5,10 +5,9 @@ markers = authentication: - authorization: cache: config: contains_workaround_for(gh=...,bz=...): identity: - schema: + integration: slow: tools: diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/requirements.txt /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/requirements.txt --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/requirements.txt 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/requirements.txt 2024-10-01 18:30:01.000000000 +0000 @@ -1,2 +1,3 @@ +flaky pytest git+https://github.com/next-actions/pytest-importance diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_authentication.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_authentication.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_authentication.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_authentication.py 2024-10-01 18:30:01.000000000 +0000 @@ -2,5 +2,5 @@ SSSD Authentication Test Cases -:requirement: offline +:requirement: authentication """ @@ -17,32 +17,33 @@ @pytest.mark.parametrize("method", ["su", "ssh"]) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) +@pytest.mark.importance("critical") @pytest.mark.require( lambda client, sssd_service_user: ((sssd_service_user == "root") or client.features["non-privileged"]), "SSSD was built without support for running under non-root", ) -def test_authentication__using_a_good_then_bad_password( +def test_authentication__with_default_settings( client: Client, provider: GenericProvider, method: str, sssd_service_user: str ): """ - :title: SSH and su authentication + :title: Authenticate with default settings :setup: - 1. Add user to SSSD - 2. Set password for user - 3. Start SSSD + 1. Create user + 2. Start SSSD :steps: 1. Authenticate user with correct password 2. Authenticate user with incorrect password :expectedresults: - 1. User is authenticated - 2. User is not authenticated + 1. Authentication is successful + 2. Authentication is unsuccessful :customerscenario: False """ provider.user("user1").add(password="Secret123") - client.sssd.set_service_user(sssd_service_user) - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) - assert client.auth.parametrize(method).password("user1", "Secret123"), "login with correct password failed" - assert not client.auth.parametrize(method).password("user1", "NOTSecret123"), "login with wrong password succeeded" + assert client.auth.parametrize(method).password("user1", "Secret123"), "User failed login!" + assert not client.auth.parametrize(method).password( + "user1", "NOTSecret123" + ), "User logged in with an invalid password!" @@ -50,32 +51,27 @@ @pytest.mark.parametrize("method", ["su", "ssh"]) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) +@pytest.mark.importance("critical") @pytest.mark.require( lambda client, sssd_service_user: ((sssd_service_user == "root") or client.features["non-privileged"]), "SSSD was built without support for running under non-root", ) -def test_authentication__using_a_good_then_bad_password_when_offline( +def test_authentication__default_settings_when_the_provider_is_offline( client: Client, provider: GenericProvider, method: str, sssd_service_user: str ): """ - :title: Offline ssh/su login + :title: Authenticate with default settings when the provider is offline :setup: - 1. Add user to SSSD and set its password - 2. In SSSD domain change "cache_credentials" and "krb5_store_password_if_offline" to "True" - 3. In SSSD pam change "offline_credentials_expiration" to "0" - 4. Start SSSD + 1. Create user + 2. Configure SSSD with "cache_credentials = true" and "krb5_store_password_if_offline = true" and + "offline_credentials_expiration = 0" + 3 Start SSSD :steps: - 1. Authenticate user with wrong password - 2. Authenticate user with correct password - 3. Make server offline (by blocking traffic to the provider) - 4. Bring SSSD offline explicitly - 5. Offline authentication of user with correct password - 6. Offline authentication of user with wrong password + 1. Authenticate user with correct password + 2. Offline user authentication with correct password + 3. Offline user authentication with incorrect password :expectedresults: - 1. User is not authenticated - 2. User is authenticated - 3. Firewall rule added, traffic is dropped. - 4. SSSD is offline - 5. Offline authentication is successful - 6. Offline authentication is not successful + 1. User authentication is successful + 2. User authentication is successful + 3. User authentication is unsuccessful :customerscenario: False """ @@ -85,22 +81,19 @@ provider.user(user).add(password=correct) - client.sssd.set_service_user(sssd_service_user) client.sssd.domain["cache_credentials"] = "True" client.sssd.domain["krb5_store_password_if_offline"] = "True" client.sssd.pam["offline_credentials_expiration"] = "0" - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) - assert not client.auth.parametrize(method).password(user, wrong), "login with wrong password succeeded" - assert client.auth.parametrize(method).password(user, correct), "login with correct password failed" + assert client.auth.parametrize(method).password(user, correct), "User failed login!" - # Block provider. client.firewall.outbound.reject_host(provider) # There might be active connections that are not terminated by creating firewall rule. - # We need to terminated it by bringing SSSD to offline state explicitly. + # We need to terminate it by forcing SSSD offline. client.sssd.bring_offline() - assert client.auth.parametrize(method).password(user, correct), "offline login with correct password failed" - assert not client.auth.parametrize(method).password(user, wrong), "offline login with wrong password succeeded" + assert client.auth.parametrize(method).password(user, correct), "User failed login!" + assert not client.auth.parametrize(method).password(user, wrong), "User logged in with an incorrect password!" @@ -109,15 +102,16 @@ @pytest.mark.parametrize("method", ["su", "ssh"]) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) +@pytest.mark.importance("critical") @pytest.mark.require( lambda client, sssd_service_user: ((sssd_service_user == "root") or client.features["non-privileged"]), "SSSD was built without support for running under non-root", ) -def test_authentication__login_using_email_address(client: Client, ad: AD, method: str, sssd_service_user: str): +def test_authentication__using_the_users_email_address(client: Client, ad: AD, method: str, sssd_service_user: str): """ - :title: Login using user's email address + :title: Login using the user's email address :description: - Testing the feature to login using an email address instead of the userid. The username used, must match one of - directory attribute values for "EmailAddress". The login should be case insensitive and permit special - characters. + Testing the feature to login using an email address instead of the userid. The username used, + must match one of the user's LDAP attribute values, "EmailAddress". The login should be + case-insensitive and permit special characters. :setup: 1. Add AD users with different email addresses @@ -126,5 +120,5 @@ 1. Authenticate users using their email address and in different cases :expectedresults: - 1. Authentication is successful using the email address and is case insensitive + 1. Authentication is successful using the email address and is case-insensitive :customerscenario: False """ @@ -133,14 +127,13 @@ ad.user("user_3").add(password="Secret123", email="user_3@alias-domain.com") - client.sssd.set_service_user(sssd_service_user) - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) assert client.auth.parametrize(method).password( f"user-1@{ad.host.domain}", "Secret123" - ), "login with correct password failed" + ), f"User user-1@{ad.host.domain} failed login!" assert client.auth.parametrize(method).password( "user-2@alias-domain.com", "Secret123" - ), "login with correct password failed" + ), "User user-2@alias-domain.com failed login!" assert client.auth.parametrize(method).password( "uSEr_3@alias-dOMain.com", "Secret123" - ), "login with correct password failed" + ), "User uSEr_3@alias-dOMain.com failed login!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_autofs.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_autofs.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_autofs.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_autofs.py 2024-10-01 18:30:01.000000000 +0000 @@ -53,8 +53,7 @@ # Start SSSD - client.sssd.set_service_user(sssd_service_user) client.sssd.common.autofs() client.sssd.autofs["cache_first"] = str(cache_first) - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) # Reload automounter in order fetch updated maps @@ -62,10 +61,10 @@ # Check that we can mount the exported directory - assert client.automount.mount("/export/export", nfs_export) + assert client.automount.mount("/export/export", nfs_export), "Unable to mount /export/export!" # Check that the maps are correctly fetched assert client.automount.dumpmaps() == { "/export": {"map": "auto.export", "keys": [str(key)]}, - } + }, "Automount maps do not match!" @@ -105,5 +104,5 @@ break - assert offline_status_propagated + assert offline_status_propagated, "Offline status not propagated!" @@ -153,5 +152,5 @@ break - assert offline_status_propagated + assert offline_status_propagated, "Offline status not propagated!" @@ -209,8 +208,8 @@ # Check that we can mount the exported directory - assert client.automount.mount("/export/export", nfs_export) + assert client.automount.mount("/export/export", nfs_export), "Unable to mount /export/export!" # Check that the maps are correctly fetched assert client.automount.dumpmaps() == { "/export": {"map": "auto.export", "keys": [str(key)]}, - } + }, "Automount maps do not match!" Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_cache.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_failover.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_failover.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_failover.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_failover.py 2024-10-01 18:30:01.000000000 +0000 @@ -8,7 +8,11 @@ import pytest +from sssd_test_framework.roles.ad import AD from sssd_test_framework.roles.client import Client +from sssd_test_framework.roles.generic import GenericProvider +from sssd_test_framework.roles.ipa import IPA from sssd_test_framework.roles.ldap import LDAP -from sssd_test_framework.topology import KnownTopology +from sssd_test_framework.roles.samba import Samba +from sssd_test_framework.topology import KnownTopologyGroup @@ -16,25 +20,27 @@ @pytest.mark.importance("low") @pytest.mark.ticket(gh=7375, jira="RHEL-17659") -@pytest.mark.topology(KnownTopology.LDAP) -def test_failover__retry_primary(client: Client, ldap: LDAP, value: int | None, expected: int): +@pytest.mark.topology(KnownTopologyGroup.AnyProvider) +def test_failover__reactivation_timeout_is_honored( + client: Client, provider: GenericProvider, value: int | None, expected: int +): """ - :title: Primary server reactivation timeout is respected + :title: Primary server reactivation timeout is honored :setup: - 1. Create LDAP user "user-1" + 1. Create user "user-1" 2. Set failover_primary_timeout to @value - 3. Set ldap_uri to invalid, not working server - 4. Set ldap_backup_uri to working server + 3. Set server/URI to an invalid server + 4. Set backup server/URI to the server 5. Start SSSD :steps: 1. Lookup user-1 - 2. Check that SSSD is connected to backup server + 2. Check that SSSD is connected to the backup server 3. Find "Primary server reactivation timeout set to @expected seconds" in domain logs :expectedresults: - 1. SSSD failover to backup server - 2. SSSD is indeed connected to the backup server + 1. User is found + 2. SSSD is connected to the backup server 3. String is found :customerscenario: True """ - ldap.user("user-1").add() + provider.user("user-1").add() if value is not None: @@ -42,18 +48,35 @@ client.sssd.enable_responder("ifp") - client.sssd.domain["ldap_uri"] = "ldap://ldap.invalid" - client.sssd.domain["ldap_backup_uri"] = f"ldap://{ldap.host.hostname}" + + if isinstance(provider, LDAP): + client.sssd.domain["ldap_uri"] = "ldap://ldap.invalid" + client.sssd.domain["ldap_backup_uri"] = f"ldap://{provider.host.hostname}" + + if isinstance(provider, AD): + client.sssd.domain["ad_server"] = "invalid.ad.test" + client.sssd.domain["ad_backup_server"] = f"{provider.host.hostname}" + + if isinstance(provider, Samba): + client.sssd.domain["ad_server"] = "invalid.samba.test" + client.sssd.domain["ad_backup_server"] = f"{provider.host.hostname}" + + if isinstance(provider, IPA): + client.sssd.domain["ipa_server"] = "invalid.ipa.test" + client.sssd.domain["ipa_backup_server"] = f"{provider.host.hostname}" + client.sssd.start() - # Lookup user to make sure SSSD did correctly failover to backup server + # Lookup user to make sure SSSD did correctly failover to the backup server result = client.tools.id("user-1") - assert result is not None + assert result is not None, "User is not found!" - # Check that SSSD is indeed connected to backup server - assert client.sssd.default_domain is not None + # Check that SSSD is indeed connected to the backup server + assert client.sssd.default_domain is not None, "Default domain is not set!" status = client.sssctl.domain_status(client.sssd.default_domain, active=True) - assert ldap.host.hostname in status.stdout + assert provider.host.hostname in status.stdout, f"{provider.host.hostname} is not found in domain status!" # Check that primary server reactivation timeout was correctly created log = client.fs.read(client.sssd.logs.domain()) - assert f"Primary server reactivation timeout set to {expected} seconds" in log + assert ( + f"Primary server reactivation timeout set to {expected} seconds" in log + ), f"'Primary server reactivation timeout set to {expected} seconds' not found in logs!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_files.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_files.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_files.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_files.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,7 @@ """ -SSSD File Provider Test Case +Files Provider Test Cases + +The files provider allows SSSD to use system users to authenticate. +This feature has been removed in SSSD 2.9.0 for the proxy provider. :requirement: IDM-SSSD-REQ :: SSSD is default for local resolution @@ -14,16 +17,21 @@ +@pytest.mark.importance("low") @pytest.mark.builtwith("files-provider") @pytest.mark.topology(KnownTopology.Client) -def test_files__lookup_root(client: Client): +def test_files__root_user_is_ignored_on_lookups(client: Client): """ - :title: Getent call doesnt work on root, when service specified as "sss" + :title: The root user is always ignored on sss service lookups + :description: This ensures that the local root user is always returned + and cannot be tampered with. :setup: - 1. Enable files domain + 1. Configure SSSD with files provider 2. Start SSSD :steps: - 1. getent passwd -s sss root + 1. Lookup root user using sss service + 2. Lookup root user without the sss service :expectedresults: - 1. Call failed + 1. The root user is not found + 2. The root user is found :customerscenario: False """ @@ -31,23 +39,24 @@ client.sssd.start() - result = client.tools.getent.passwd("root", service="sss") - assert result is None, "Getent call was successful, which is not expected" + assert client.tools.getent.passwd("root", service="sss") is None, "Root user is found using 'sss' service!" + assert client.tools.getent.passwd("root"), "Root user is not found using all services!" +@pytest.mark.importance("low") @pytest.mark.builtwith("files-provider") @pytest.mark.topology(KnownTopology.Client) def test_files__lookup_user(client: Client): """ - :title: Simple getent call + :title: Lookup user :setup: - 1. Add local user "user1" - 2. Enable files domain + 1. Create user + 2. Configure SSSD with files provider 3. Start SSSD :steps: - 1. getent passwd -s sss user1 - 2. Check uid of result + 1. Lookup user + 2. Check results :expectedresults: - 1. Call was successful - 2. Uid is correct + 1. User is found + 2. The uid matches :customerscenario: False """ @@ -57,20 +66,23 @@ result = client.tools.getent.passwd("user1", service="sss") - assert result is not None, "Getent failed" - assert result.uid == 10001, "Uid is not correct" + assert result is not None, "User not found!" + assert result.uid == 10001, "UID does not match!" +@pytest.mark.importance("low") @pytest.mark.builtwith("files-provider") @pytest.mark.topology(KnownTopology.Client) -def test_files__lookup_should_not_enumerate_users(client: Client): +def test_files__enumeration_should_not_work(client: Client): """ - :title: Files provider should not enumerate + :title: Enumeration should not work + :description: Enumeration pulls down the directory data and stores it locally. + Running an unspecified getent will return all users or groups. :setup: - 1. Enable files domain + 1. Configure SSSD with files provider 2. Start SSSD :steps: - 1. getent passwd -s sss without specified user + 1. Run getent with nothing specified :expectedresults: - 1. Output is empty + 1. Nothing found :customerscenario: False """ @@ -78,29 +90,29 @@ client.sssd.start() - result = client.host.ssh.run("getent passwd -s sss") - assert not result.stdout + assert not client.host.conn.run("getent passwd -s sss").stdout, "Entries found!" +@pytest.mark.importance("low") @pytest.mark.builtwith("files-provider") @pytest.mark.topology(KnownTopology.Client) -def test_files__lookup_user_shows_updated_user_info(client: Client): +def test_files__lookup_returns_the_latest_data(client: Client): """ - :title: User have his homedir updated, after passwd + :title: Looking up a user returns the latest data :setup: - 1. Add local user "user1" with specified homedir - 2. Enable files domain + 1. Create user and specify home directory + 2. Configure SSSD with files provider 3. Start SSSD :steps: - 1. getent passwd -s sss user1 - 2. Check that homedir is correct - 3. Modify user1's homedir - 4. Wait for changes to be propagated - 5. Check that homedir is correct + 1. Lookup user + 2. Check results + 3. Change user's home directory + 4. Lookup user again + 5. Check results :expectedresults: - 1. Call is successful - 2. homedir is correct - 3. homedir modified successfully - 4. Slept well - 5. homedir is updated correctly + 1. User is found + 2. The homedir matches + 3. Home directory is changed + 4. User is found + 5. Home directory reflects the new value :customerscenario: False """ @@ -110,6 +122,6 @@ result = client.tools.getent.passwd("user1", service="sss") - assert result is not None - assert result.home == "/home/user1-tmp" + assert result is not None, "User not found!" + assert result.home == "/home/user1-tmp", "User's homedir is not correct!" client.local.user("user1").modify(home="/home/user1") @@ -117,4 +129,4 @@ time.sleep(1) result = client.tools.getent.passwd("user1", service="sss") - assert result is not None - assert result.home == "/home/user1" + assert result is not None, "User not found!" + assert result.home == "/home/user1", "User's homedir is not correct!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_gpo.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_gpo.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_gpo.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_gpo.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,4 @@ """ -SSSD GPO Tests +Access Control - Group Policy Objects (GPO) Tests Switch user (su), and Remote (ssh) access is parameterized fixture for the tests. When SeRemoteInteractiveLogonRight is @@ -9,14 +9,15 @@ .. code-block:: - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, group, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, group, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [], } + ) An administrative user or group always needs to be specified, to prevent administrative lock outs, for the tests "Domain Admins" group is used. -The following GPO related parameters are not tested +The following GPO related parameters are not tested - ad_gpo_cache_timeout - ad_gpo_map_network @@ -35,11 +36,12 @@ from sssd_test_framework.roles.ad import AD from sssd_test_framework.roles.client import Client -from sssd_test_framework.topology import KnownTopology +from sssd_test_framework.roles.generic import GenericADProvider +from sssd_test_framework.topology import KnownTopology, KnownTopologyGroup @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["su", "ssh"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__is_set_to_enforcing(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__is_set_to_enforcing(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to enforcing and users are allowed @@ -60,19 +62,19 @@ :expectedresults: 1. User authentication is unsuccessful - 2. Users authentication are successful - 3. Users authentication are unsuccessful + 2. User authentications are successful + 3. User authentications are unsuccessful :customerscenario: True """ - ad.user("user").add() - user1 = ad.user("user1").add() - user2 = ad.user("user2").add() - deny_user1 = ad.user("deny_user1").add() - deny_user2 = ad.user("deny_user2").add() - group = ad.group("group").add().add_members([user2]) - deny_group = ad.group("deny_group").add().add_members([deny_user2]) + provider.user("user").add() + user1 = provider.user("user1").add() + user2 = provider.user("user2").add() + deny_user1 = provider.user("deny_user1").add() + deny_user2 = provider.user("deny_user2").add() + group = provider.group("group").add().add_members([user2]) + deny_group = provider.group("deny_group").add().add_members([deny_user2]) - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, group, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, group, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1, deny_group], } @@ -82,15 +84,29 @@ client.sssd.start() - assert not client.auth.parametrize(method).password(username="user", password="Secret123") - assert client.auth.parametrize(method).password(username="user1", password="Secret123") - assert client.auth.parametrize(method).password(username="user2", password="Secret123") - assert not client.auth.parametrize(method).password(username="deny_user1", password="Secret123") - assert not client.auth.parametrize(method).password(username="deny_user2", password="Secret123") + assert not client.auth.parametrize(method).password( + username="user", password="Secret123" + ), "User absent from policy authenticated successfully!" + + assert client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert client.auth.parametrize(method).password( + username="user2", password="Secret123" + ), "Allowed group user authentication failed!" + + assert not client.auth.parametrize(method).password( + username="deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" + + assert not client.auth.parametrize(method).password( + username="deny_user2", password="Secret123" + ), "Denied group user authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["su", "ssh"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__is_set_to_enforcing_with_no_policy(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__is_set_to_enforcing_with_no_policy(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to enforcing with no policy @@ -110,5 +126,5 @@ :customerscenario: True """ - ad.user("user").add() + provider.user("user").add() client.sssd.domain["ad_gpo_access_control"] = "enforcing" @@ -120,6 +136,6 @@ @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["su", "ssh"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__is_set_to_permissive_and_users_are_allowed(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__is_set_to_permissive_and_users_are_allowed(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to permissive @@ -143,9 +159,9 @@ :customerscenario: True """ - user1 = ad.user("user1").add() + user1 = provider.user("user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [], } @@ -155,15 +171,20 @@ client.sssd.start() - assert client.auth.parametrize(method).password(username="user1", password="Secret123") - + assert client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "(Permissive) Allowed user authentication failed!" log_str = client.fs.read(client.sssd.logs.domain()) - assert "Option ad_gpo_access_control has value permissive" in log_str - assert "access_granted = 1" in log_str + + assert ( + "Option ad_gpo_access_control has value permissive" in log_str + ), "'Option ad_gpo_access_control has value permissive' not in logs!" + + assert "access_granted = 1" in log_str, "'access_granted = 1' not in logs!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["su", "ssh"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__is_set_to_permissive_and_users_are_denied(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__is_set_to_permissive_and_users_are_denied(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to permissive @@ -187,9 +208,9 @@ :customerscenario: True """ - deny_user1 = ad.user("deny_user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [ad.group("Domain Admins")], + "SeInteractiveLogonRight": [provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } @@ -199,15 +220,20 @@ client.sssd.start() - assert client.auth.parametrize(method).password(username="deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + username="deny_user1", password="Secret123" + ), "(Permissive) Denied user authentication failed!" log_str = client.fs.read(client.sssd.logs.domain()) - assert "Option ad_gpo_access_control has value permissive" in log_str - assert "access_denied = 1" in log_str + assert ( + "Option ad_gpo_access_control has value permissive" in log_str + ), "'Option ad_gpo_access_control has value permissive' not in logs!" + + assert "access_granted = 0" in log_str, "'access_granted = 1' not in logs!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["su", "ssh"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__is_set_to_disabled_and_all_users_are_allowed(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__is_set_to_disabled_and_all_users_are_allowed(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to disabled and all users are allowed @@ -229,11 +255,11 @@ :customerscenario: True """ - ad.user("user").add() - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() + provider.user("user").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } @@ -243,17 +269,27 @@ client.sssd.start() - assert client.auth.parametrize(method).password(username="user", password="Secret123") - assert client.auth.parametrize(method).password(username="user1", password="Secret123") - assert client.auth.parametrize(method).password(username="deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + username="user", password="Secret123" + ), "(Disabled) User authentication failed!" + + assert client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "(Disabled) User authentication failed!" + + assert client.auth.parametrize(method).password( + username="deny_user1", password="Secret123" + ), "(Disabled) User authentication failed!" log_str = client.fs.read(client.sssd.logs.domain()) - assert "Option ad_gpo_access_control has value disabled" in log_str + assert ( + "Option ad_gpo_access_control has value disabled" in log_str + ), "'Option ad_gpo_access_control has value disabled' not in logs!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) +@pytest.mark.topology(KnownTopologyGroup.AnyAD) @pytest.mark.ticket(bz=1695576) -def test_gpo__implicit_deny_is_set_to_true(client: Client, ad: AD, method: str): +def test_gpo__implicit_deny_is_set_to_true(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control is set to enforcing and implicit deny is true @@ -271,5 +307,5 @@ :customerscenario: True """ - ad.user("user").add() + provider.user("user").add() client.sssd.domain["ad_gpo_access_control"] = "enforcing" @@ -277,11 +313,15 @@ client.sssd.start() - assert not client.auth.parametrize(method).password(username="user", password="Secret123") + assert not client.auth.parametrize(method).password( + username="user", password="Secret123" + ), "User authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__domain_and_sites_inheritance_when_site_is_enforcing(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__domain_and_sites_inheritance_when_site_is_enforcing( + client: Client, provider: GenericADProvider, method: str +): """ :title: Group policy object host base access control checking inheritance for sites enforced and domains @@ -308,39 +348,37 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - user2 = ad.user("user2").add() + user1 = provider.user("user1").add() + user2 = provider.user("user2").add() - site_policy = ( - ad.gpo("site policy") - .add() - .policy( - { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], - "SeDenyInteractiveLogonRight": [user2], - } - ) - .link() - ) + provider.gpo("site policy").add().policy( + { + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], + "SeDenyInteractiveLogonRight": [user2], + } + ).link(enforced=True) - ad.gpo("domain policy").add().policy( + provider.gpo("domain policy").add().policy( { - "SeInteractiveLogonRight": [user2, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user2, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [user1], } - ).link(target=f"{ad.host.naming_context}") - - site_policy.link("Set", args=["-Enforced Yes"]) + ).link(target=f"{provider.naming_context}") client.sssd.domain["ad_gpo_access_control"] = "enforcing" client.sssd.start() - assert client.auth.parametrize(method).password(username="user1", password="Secret123") - assert not client.auth.parametrize(method).password(username="user2", password="Secret123") + assert client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "User authentication failed!" + + assert not client.auth.parametrize(method).password( + username="user2", password="Secret123" + ), "User authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__domain_and_sites_inheritance(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__domain_and_sites_inheritance(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host base access control checking inheritance for sites and domains. @@ -366,32 +404,37 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - user2 = ad.user("user2").add() + user1 = provider.user("user1").add() + user2 = provider.user("user2").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [user2], } ).link() - ad.gpo("domain policy").add().policy( + provider.gpo("domain policy").add().policy( { - "SeInteractiveLogonRight": [user2, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user2, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [user1], } - ).link(target=f"{ad.host.naming_context}") + ).link(target=f"{provider.naming_context}") client.sssd.domain["ad_gpo_access_control"] = "enforcing" client.sssd.start() - assert not client.auth.parametrize(method).password(username="user1", password="Secret123") - assert client.auth.parametrize(method).password(username="user2", password="Secret123") + assert not client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "Site user authenticated successfully!" + + assert client.auth.parametrize(method).password( + username="user2", password="Secret123" + ), "Domain user authentication failed!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__ou_and_domain_inheritance(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__ou_and_domain_inheritance(client: Client, provider: AD, method: str): """ :title: Group policy object host base access control checking inheritance between ous and domains. @@ -419,29 +462,34 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - user2 = ad.user("user2").add() - ou = ad.ou("test").add().dn + user1 = provider.user("user1").add() + user2 = provider.user("user2").add() + ou = provider.ou("test").add().dn - ad.gpo("domain policy").add().policy( + provider.gpo("domain policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [user2], } - ).link(target=f"{ad.host.naming_context}") + ).link(target=f"{provider.host.naming_context}") - ad.gpo("ou policy").add().policy( + provider.gpo("ou policy").add().policy( { - "SeInteractiveLogonRight": [user2, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user2, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [user1], } ).link(target=ou) - ad.computer(client.host.hostname.split(".")[0]).move(ou) + provider.computer(client.host.hostname.split(".")[0]).move(ou) client.sssd.domain["ad_gpo_access_control"] = "enforcing" client.sssd.start() - assert not client.auth.parametrize(method).password(username="user1", password="Secret123") - assert client.auth.parametrize(method).password(username="user2", password="Secret123") + assert not client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "Domain user authenticated successfully!" + + assert client.auth.parametrize(method).password( + username="user2", password="Secret123" + ), "OU user authentication failed!" @@ -487,16 +535,19 @@ "SeDenyInteractiveLogonRight": [user1], } - ).link(args=["-Order 1"]) + ).link(order=1) client.sssd.domain["ad_gpo_access_control"] = "enforcing" client.sssd.start() - assert not client.auth.parametrize(method).password(username="user1", password="Secret123") - assert client.auth.parametrize(method).password(username="user2", password="Secret123") + assert not client.auth.parametrize(method).password( + username="user1", password="Secret123" + ), "User authenticated successfully!" + + assert client.auth.parametrize(method).password(username="user2", password="Secret123"), "User failed login!" @pytest.mark.importance("critical") -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__map_interactive_disabling_login_su_and_su_l(client: Client, ad: AD): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__map_interactive_disabling_login_su_and_su_l(client: Client, provider: GenericADProvider): """ :title: Group policy object host based access disabling logon, su, su-l GPO evaluation. @@ -524,10 +575,10 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } @@ -538,13 +589,19 @@ client.sssd.start() - assert not client.auth.su.password("user1", password="Secret123") - assert client.auth.ssh.password("user1", password="Secret123") - assert not client.auth.su.password("deny_user1", password="Secret123") - assert not client.auth.ssh.password("deny_user1", password="Secret123") + assert not client.auth.su.password("user1", password="Secret123"), "Allowed user, authenticated SU successfully!" + assert client.auth.ssh.password("user1", password="Secret123"), "Allowed user SSH authentication failed!" + + assert not client.auth.su.password( + "deny_user1", password="Secret123" + ), "Denied user, authenticated SU successfully!" + + assert not client.auth.ssh.password( + "deny_user1", password="Secret123" + ), "Denied user authenticated SSH successfully!" @pytest.mark.importance("critical") -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__map_remote_interactive_disabling_sshd(client: Client, ad: AD): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__map_remote_interactive_disabling_sshd(client: Client, provider: GenericADProvider): """ :title: Group policy object host based access disabling ssh and cockpit GPO evaluation. @@ -571,10 +628,10 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } @@ -585,14 +642,20 @@ client.sssd.start() - assert client.auth.su.password("user1", password="Secret123") - assert not client.auth.ssh.password("user1", password="Secret123") - assert not client.auth.su.password("deny_user1", password="Secret123") - assert not client.auth.ssh.password("deny_user1", password="Secret123") + assert client.auth.su.password("user1", password="Secret123"), "Allowed user SU authentication failed!" + assert not client.auth.ssh.password("user1", password="Secret123"), "Allowed user, authenticated SSH successfully!" + + assert not client.auth.su.password( + "deny_user1", password="Secret123" + ), "Denied user, authenticated SU successfully!" + + assert not client.auth.ssh.password( + "deny_user1", password="Secret123" + ), "Denied user, authenticated SSH successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) -def test_gpo__works_when_the_server_is_unreachable(client: Client, ad: AD, method: str): +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +def test_gpo__works_when_the_server_is_unreachable(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host based works when the server is unreachable. @@ -619,10 +682,10 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } @@ -635,19 +698,29 @@ client.sssd.start() - assert client.auth.parametrize(method).password("user1", password="Secret123") - assert not client.auth.parametrize(method).password("deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" - client.firewall.outbound.drop_host(ad) + client.firewall.outbound.drop_host(provider) client.sssd.bring_offline() - assert client.auth.parametrize(method).password("user1", password="Secret123") - assert not client.auth.parametrize(method).password("deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) +@pytest.mark.topology(KnownTopologyGroup.AnyAD) @pytest.mark.ticket(bz=1547234) -def test_gpo__honors_the_ad_site_parameter(client: Client, ad: AD, method: str): +def test_gpo__honors_the_ad_site_parameter(client: Client, provider: GenericADProvider, method: str): """ :title: Group policy object host based access control honors the ad_site parameter in the configuration. @@ -675,14 +748,14 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() - ad.site("New-Site").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() + provider.site("New-Site").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], } - ).link(target=f"cn=New-Site,cn=sites,cn=configuration,{ad.host.naming_context}") + ).link(target=f"cn=New-Site,cn=sites,cn=configuration,{provider.naming_context}") client.sssd.domain["ad_gpo_access_control"] = "enforcing" @@ -690,6 +763,11 @@ client.sssd.start() - assert client.auth.ssh.password("user1", password="Secret123") - assert not client.auth.ssh.password("deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" @@ -743,13 +821,20 @@ client.sssd.start() - assert client.auth.parametrize(method).password("user1", password="Secret123") - assert not client.auth.parametrize(method).password("deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) +@pytest.mark.topology(KnownTopologyGroup.AnyAD) @pytest.mark.ticket(bz=1316164) -def test_gpo__ignores_invalid_and_unnecessary_keys_and_values(client: Client, ad: AD, method: str): +def test_gpo__ignores_invalid_and_unnecessary_keys_and_values( + client: Client, provider: GenericADProvider, method: str +): """ :title: Group policy object host based access control ignores invalid and unnecessary keys and values. @@ -773,10 +858,10 @@ :customerscenario: True """ - user1 = ad.user("user1").add() - deny_user1 = ad.user("deny_user1").add() + user1 = provider.user("user1").add() + deny_user1 = provider.user("deny_user1").add() - ad.gpo("policy invalid keys and values").add().policy( + provider.gpo("policy invalid keys and values").add().policy( { - "SeInteractiveLogonRight": [user1, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [deny_user1], }, @@ -787,6 +872,11 @@ client.sssd.start() - assert client.auth.parametrize(method).password(username="user1", password="Secret123") - assert not client.auth.parametrize(method).password(username="deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" @@ -835,38 +925,43 @@ client.sssd.start() - assert client.auth.parametrize(method).password("user1", password="Secret123") - assert not client.auth.parametrize(method).password("deny_user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + + assert not client.auth.parametrize(method).password( + "deny_user1", password="Secret123" + ), "Denied user authenticated successfully!" @pytest.mark.importance("critical") @pytest.mark.parametrize("method", ["ssh", "su"]) -@pytest.mark.topology(KnownTopology.AD) +@pytest.mark.topology(KnownTopologyGroup.AnyAD) @pytest.mark.ticket(bz=2151450) -def test_gpo__works_when_auto_private_groups_is_set_true(client: Client, ad: AD, method: str): +def test_gpo__finds_all_groups_when_auto_private_groups_is_set_true( + client: Client, provider: GenericADProvider, method: str +): """ - :title: Group policy object host based access control works when auto_private_groups is set to true. + :title: Primary group is missing from users when auto_private_groups are enabled :description: This tests for a bug where the primary group is not returned when the user is looked up. :setup: 1. Create the following user 'user1' - 2. Create the following group 'group' and add 'user1' to the group - 3. Create and link the GPO 'site policy' and add 'user1', groups, 'group' and 'Domain Admins' to - SeInteractiveLogonRight key. - 4. Configure sssd.conf with 'ad_gpo_access_control' = 'enforcing' and 'ldap_use_tokengroup' = 'False' - 5. Start SSSD + 2. Create and link the GPO 'site policy' and add 'user1' and 'Domain Admins' to SeInteractiveLogonRight key. + 3. Configure sssd.conf with 'ad_gpo_access_control = enforcing', 'ldap_use_tokengroups = false' and + 'auto_private_groups = true' + 4. Start SSSD :steps: 1. Authenticate as 'user1' - 2. Id as 'user1' + 2. Lookup user :expectedresults: - 1. 'user1' authentication is successful - 2. Primary group 'Domain Users' is listed + 1. Authentication is successful + 2. User found and primary group 'Domain Users' is listed :customerscenario: True """ - user1 = ad.user("user1").add() - group = ad.group("group").add().add_members([user1]) + user1 = provider.user("user1").add() - ad.gpo("site policy").add().policy( + provider.gpo("site policy").add().policy( { - "SeInteractiveLogonRight": [user1, group, ad.group("Domain Admins")], + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], "SeDenyInteractiveLogonRight": [], } @@ -875,9 +970,58 @@ client.sssd.domain["ad_gpo_access_control"] = "enforcing" client.sssd.domain["auto_private_groups"] = "true" + client.sssd.domain["ldap_use_tokengroups"] = "false" client.sssd.start() - assert client.auth.parametrize(method).password(username="user1", password="Secret123") + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" result = client.tools.id("user1") - assert result is not None, "id command for user1 failed" - assert result.memberof("domain users") + assert result is not None, "User not found!" + assert result.memberof("domain users"), "User missing from group 'domain users'!" + + +@pytest.mark.importance("critical") +@pytest.mark.parametrize("method", ["ssh", "su"]) +@pytest.mark.parametrize("auto_private_groups", ["true", "false", "hybrid"]) +@pytest.mark.topology(KnownTopologyGroup.AnyAD) +@pytest.mark.ticket(gh=7452) +def test_gpo__works_when_auto_private_group_is_used_with_posix_accounts( + client: Client, provider: GenericADProvider, method: str, auto_private_groups: str +): + """ + :title: GPO evaluation fails when auto_private_groups used with posix accounts + :setup: + 1. Create the following user 'user1' and 'deny_user1' with uids and gids + 2. Create and link the GPO 'site policy' and add 'user1' and 'Domain Admins' to + SeInteractiveLogonRight key. Add 'deny_user1 to SeDenyInteractiveLogonRight key' + 3. Configure sssd.conf with 'ad_gpo_access_control = enforcing', + 'auto_private_groups = parameter' and 'ldap_id_mapping = false' + 4. Start SSSD + :steps: + 1. Authenticate as 'user1' + 2. Authenticate as 'deny_user1' + :expectedresults: + 1. Authentication is successful + 2. Authenticated user is unsuccessful + :customerscenario: True + """ + user1 = provider.user("user1").add(uid=10000, gid=10000) + deny_user1 = provider.user("deny_user1").add(uid=10001, gid=10001) + + provider.gpo("site policy").add().policy( + { + "SeInteractiveLogonRight": [user1, provider.group("Domain Admins")], + "SeDenyInteractiveLogonRight": [deny_user1], + } + ).link() + + client.sssd.domain["ad_gpo_access_control"] = "enforcing" + client.sssd.domain["auto_private_groups"] = auto_private_groups + client.sssd.domain["ldap_id_mapping"] = "false" + client.sssd.start() + + assert client.auth.parametrize(method).password( + "user1", password="Secret123" + ), "Allowed user authentication failed!" + assert not client.auth.parametrize(method).password("deny_user1", password="Secret123"), "Denied user logged in!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_identity.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_identity.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_identity.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_identity.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,6 +1,8 @@ """ -SSSD Identity Lookup Test Cases +Identity Tests -:requirement: IDM-SSSD-REQ: Client side performance improvements +These tests cover all the searches, queries, and lookups performed by SSSD. + +:requirement: Identity """ @@ -10,4 +12,5 @@ from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.generic import GenericADProvider, GenericProvider +from sssd_test_framework.roles.ipa import IPA from sssd_test_framework.topology import KnownTopologyGroup @@ -20,19 +23,16 @@ "SSSD was built without support for running under non-root", ) -def test_identity__lookup_username_with_id(client: Client, provider: GenericProvider, sssd_service_user: str): +def test_identity__lookup_username_with_id_command(client: Client, provider: GenericProvider, sssd_service_user: str): """ - :title: Resolve user by name with id + :title: Resolve user by name with "id" :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Set users uids and gids - 3. Start SSSD + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'user1', 'user2' and 'user3' with id(name) - 2. Check that results have correct names - 3. Check that results have correct ids + 1. Lookup 'user1', 'user2' and 'user3' using the UID + 2. Check the results :expectedresults: 1. Users are found - 2. Users have correct names - 3. Users have correct ids + 2. Results have the correct name and UIDs :customerscenario: False """ @@ -41,13 +41,12 @@ provider.user(user).add(uid=id, gid=id + 500) - client.sssd.set_service_user(sssd_service_user) client.sssd.domain["ldap_id_mapping"] = "false" - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) for name, uid in ids: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.user.name == name, f"Username {result.user.name} is incorrect, {name} expected" - assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected" + assert result is not None, f"User {name} was not found using id!" + assert result.user.name == name, f"Username {result.user.name} is incorrect, {name} expected!" + assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected!" @@ -59,19 +58,16 @@ "SSSD was built without support for running under non-root", ) -def test_identity__lookup_uid_with_id(client: Client, provider: GenericProvider, sssd_service_user: str): +def test_identity__lookup_uid_with_id_command(client: Client, provider: GenericProvider, sssd_service_user: str): """ - :title: Resolve user by uid with id + :title: Resolve user by uid with "id" :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Set users uids and gids - 3. Start SSSD + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'user1', 'user2' and 'user3' with id(uid) - 2. Check that users have correct names - 3. Check that users have correct ids + 1. Lookup 'user1', 'user2' and 'user3' using the UID + 2. Check the results :expectedresults: 1. Users are found - 2. Users have correct names - 3. Users have correct ids + 2. Results have the correct name and UID :customerscenario: False """ @@ -80,13 +76,12 @@ provider.user(user).add(uid=id, gid=id + 500) - client.sssd.set_service_user(sssd_service_user) client.sssd.domain["ldap_id_mapping"] = "false" - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) for name, uid in ids: result = client.tools.id(uid) - assert result is not None, f"User with uid {uid} was not found using id" - assert result.user.name == name, f"Username {result.user.name} is incorrect, {name} expected" - assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected" + assert result is not None, f"User with uid {uid} was not found using id!" + assert result.user.name == name, f"Username {result.user.name} is incorrect, {name} expected!" + assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected!" @@ -95,17 +90,14 @@ def test_identity__lookup_groupname_with_getent(client: Client, provider: GenericProvider): """ - :title: Resolve group by name with getent.group + :title: Resolve group by name with getent :setup: - 1. Add 'group1', 'group2' and 'group3' to SSSD - 2. Set groups gids - 3. Start SSSD - :steps: - 1. Find 'group1', 'group2' and 'group3' with getent.group(name) - 2. Check that groups have correct names - 3. Check that groups have correct gids + 1. Create the following groups 'group1', 'group2' and 'group3' specifying the GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD + :steps: + 1. Lookup the groups + 2. Check the results :expectedresults: 1. Groups are found - 2. Groups have correct names - 3. Groups have correct gids + 2. Results have the correct names and GIDs :customerscenario: False """ @@ -119,26 +111,23 @@ for name, gid in ids: result = client.tools.getent.group(name) - assert result is not None, f"Group {name} was not found using getent" - assert result.name == name, f"Groupname {result.name} is incorrect, {name} expected" - assert result.gid == gid, f"Group gid {result.gid} is incorrect, {gid} expected" + assert result is not None, f"Group {name} was not found using getent!" + assert result.name == name, f"Groupname {result.name} is incorrect, {name} expected!" + assert result.gid == gid, f"Group gid {result.gid} is incorrect, {gid} expected!" @pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_gid_with_getent(client: Client, provider: GenericProvider): +def test_identity__lookup_group_gid_with_getent(client: Client, provider: GenericProvider): """ - :title: Resolve group with by gid with getent.group + :title: Resolve group with by gid with getent :setup: - 1. Add 'group1', 'group2' and 'group3' to SSSD - 2. Set groups gids - 3. Start SSSD + 1. Create the following groups 'group1', 'group2' and 'group3' specifying the GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'group1', 'group2' and 'group3' with getent.group(gid) - 2. Check that users have correct names - 3. Check that users have correct gids + 1. Lookup the groups using their GID with getent + 2. Check the results :expectedresults: 1. Groups are found - 2. Groups have correct names - 3. Groups have correct gids + 2. Groups have the correct names and GIDs :customerscenario: False """ @@ -152,7 +141,7 @@ for name, gid in ids: result = client.tools.getent.group(gid) - assert result is not None, f"Group with gid {gid} was not found using getent" - assert result.name == name, f"Groupname {result.name} is incorrect, {name} expected" - assert result.gid == gid, f"Group gid {result.gid} is incorrect, {gid} expected" + assert result is not None, f"Group with gid {gid} was not found using getent!" + assert result.name == name, f"Groupname {result.name} is incorrect, {name} expected!" + assert result.gid == gid, f"Group gid {result.gid} is incorrect, {gid} expected!" @@ -161,21 +150,18 @@ def test_identity__lookup_user_with_getent(client: Client, provider: GenericProvider): """ - :title: Resolve user with getent.passwd + :title: Resolve user with getent :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Set users uids and gids - 3. Add 'group1', 'group2' and 'group3' to SSSD - 4. Add users to groups - 5. Start SSSD - :steps: - 1. Find 'user1', 'user2' and 'user3' with getent.passwd(name) - 2. Find 'user1', 'user2' and 'user3' with getent.passwd(uid) - 3. Check that users have correct names - 4. Check that users have correct ids + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD + :steps: + 1. Lookup the users using their name + 2. Check the results + 3. Lookup the users using their uid + 4. Check the results :expectedresults: 1. Users are found - 2. Users are found - 3. Users have correct names - 4. Users have correct ids + 2. Users have correct names and uids + 3. Users are found + 4. Users have correct names and uids :customerscenario: False """ @@ -189,33 +175,32 @@ for name, uid in ids: result = client.tools.getent.passwd(name) - assert result is not None, f"User {name} was not found using getent" - assert result.name == name, f"Username {result.name} is incorrect, {name} expected" - assert result.uid == uid, f"User id {result.uid} is incorrect, {uid} expected" + assert result is not None, f"User {name} was not found using getent!" + assert result.name == name, f"Username {result.name} is incorrect, {name} expected!" + assert result.uid == uid, f"User id {result.uid} is incorrect, {uid} expected!" result = client.tools.getent.passwd(uid) - assert result is not None, f"User with uid {uid} was not found using getent" - assert result.name == name, f"Username {result.name} is incorrect, {name} expected" - assert result.uid == uid, f"User id {result.uid} is incorrect, {uid} expected" + assert result is not None, f"User with uid {uid} was not found using getent!" + assert result.name == name, f"Username {result.name} is incorrect, {name} expected!" + assert result.uid == uid, f"User id {result.uid} is incorrect, {uid} expected!" @pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_user_by_group_with_getent(client: Client, provider: GenericProvider): +def test_identity__lookup_groups_by_name_and_gid_with_getent(client: Client, provider: GenericProvider): """ - :title: Resolve user with getent.group + :title: Resolve groups with getent :setup: - 1. Add 'group1', 'group2' and 'group3' to SSSD - 2. Set groups gids - 3. Start SSSD + 1. Create the following groups 'group1', 'group2' and 'group3' specifying the GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'group1', 'group2' and 'group3' with getent.group(name) - 2. Find 'group1', 'group2' and 'group3' with getent.group(gid) - 3. Check that groups have correct names - 4. Check that groups have correct gids + 1. Lookup the groups using their name + 2. Check the results + 3. Lookup the groups using their gid + 4. Check the results :expectedresults: 1. Groups are found - 2. Groups are found - 3. Groups have correct names - 4. Groups have correct gids + 2. Groups have correct names and gids + 3. Groups are found + 4. Groups have correct names and gids :customerscenario: False """ @@ -229,12 +214,12 @@ for group, id in groups: result = client.tools.getent.group(group) - assert result is not None, f"Group {group} was not found using getent" - assert result.name == group, f"Groupname {result.name} is incorrect, {group} expected" - assert result.gid == id, f"Group gid {result.gid} is incorrect, {id} expected" + assert result is not None, f"Group {group} was not found using getent!" + assert result.name == group, f"Groupname {result.name} is incorrect, {group} expected!" + assert result.gid == id, f"Group gid {result.gid} is incorrect, {id} expected!" result = client.tools.getent.group(id) - assert result is not None, f"Group with gid {id} was not found using getent" - assert result.name == group, f"Groupname {result.name} is incorrect, {group} expected" - assert result.gid == id, f"Group gid {result.gid} is incorrect, {id} expected" + assert result is not None, f"Group with gid {id} was not found using getent!" + assert result.name == group, f"Groupname {result.name} is incorrect, {group} expected!" + assert result.gid == id, f"Group gid {result.gid} is incorrect, {id} expected!" @@ -246,20 +231,19 @@ "SSSD was built without support for running under non-root", ) -def test_identity__lookup_group_membership_by_username_with_id( +def test_identity__lookup_group_membership_by_username_with_id_command( client: Client, provider: GenericProvider, sssd_service_user: str ): """ - :title: Check membership of user by group name with id + :title: Check membership of user by group name with "id" :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Add 'group1' to SSSD - 3. Add members to group - 4. Start SSSD + 1. Create the following users 'user1', 'user2', 'user3', and 'user4' + 2. Create 'group1' and add all users to group except for 'user4' + 3. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'user1', 'user2' and 'user3' with id(name) - 2. Check that users are members of correct group using memberof([name]) + 1. Lookup users by name + 2. Check results :expectedresults: 1. Users are found - 2. Users are members of correct group + 2. All users except 'user4' are members of 'group1' :customerscenario: False """ @@ -268,32 +252,35 @@ u2 = provider.user("user2").add() u3 = provider.user("user3").add() + u4 = provider.user("user4").add() provider.group("group1").add().add_members([u1, u2, u3]) - client.sssd.set_service_user(sssd_service_user) - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) for name, groups in users: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.memberof(groups), f"User {name} is member of wrong groups" + assert result is not None, f"User {name} was not found using id!" + assert result.memberof(groups), f"User {name} is a member of the wrong groups!" + + result = client.tools.id(u4.name) + assert result is not None, "User not found!" + assert not result.memberof("group1"), f"User {u4.name} is a member of the wrong groups!" @pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_group_membership_by_group_with_id(client: Client, provider: GenericProvider): +def test_identity__lookup_group_membership_by_group_with_id_command(client: Client, provider: GenericProvider): """ - :title: Check membership of user by gid with id + :title: Check membership of user by gid with "id" :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Add 'group1' to SSSD - 3. Add members to group - 4. Start SSSD + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Create 'group1' and add all users to group + 3. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Find 'user1', 'user2' and 'user3' with id(name) - 2. Check that users are members of correct groups using memberof(gid) + 1. Lookup users by name with "id" + 2. Check results :expectedresults: 1. Users are found - 2. Users are members of correct group + 2. Users are members of the group checked using the GID :customerscenario: False """ @@ -310,6 +297,6 @@ for name, gids in users: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.memberof(gids), f"User {name} is member of wrong groups" + assert result is not None, f"User {name} was not found using id!" + assert result.memberof(gids), f"User {name} is member of wrong groups!" @@ -320,17 +307,13 @@ :title: Check initgroups of user :setup: - 1. Add users to SSSD - 2. Add groups to SSSD - 3. Set groups gids - 4. Add members to groups - 5. Start SSSD - :steps: - 1. Find users with getent.initgroups(name) - 2. Check that user has correct name - 3. Check that user has correct initgroups + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Create the following groups 'group1', 'group2' and 'group3' and add all users to all groups + 3. Configure SSSD with "ldap_id_mapping = false" and start SSSD + :steps: + 1. Lookup users using initgroups with getent + 2. Check results :expectedresults: 1. Users are found - 2. User has correct names - 3. User has correct initgroups + 2. Users are in the groups checked by GIDs :customerscenario: False """ @@ -349,6 +332,6 @@ for name in users: result = client.tools.getent.initgroups(name) - assert result.name == name, f"Username {result.name} is incorrect, {name} expected" - assert result.memberof([10001, 10002, 10003]), f"User {name} is member of wrong groups" + assert result.name == name, f"Username {result.name} is incorrect, {name} expected!" + assert result.memberof([10001, 10002, 10003]), f"User {name} is member of wrong groups!" @@ -359,18 +342,14 @@ :title: Resolve user when 'use_fully_qualified_names' is 'true' :setup: - 1. Add 'user1' and 'user2' to SSSD - 2. Set users uids and gids - 3. In SSSD domain change 'use_fully_qualified_names' to 'true' - 4. Start SSSD - :steps: - 1. Find 'user1' and 'user2' with id(name) - 2. Find 'user1' and 'user2' with id(name@domain) - 3. Check that users have correct full names - 4. Check that users have correct ids + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and "use_fully_qualified_name = true" and start SSSD + :steps: + 1. Lookup users with their username + 2. Lookup users with their fully qualified name + 3. Check results :expectedresults: 1. Users are not found 2. Users are found - 3. Users have correct full names - 4. Users have correct ids + 3. Users have the correct names and UIDs :customerscenario: False """ @@ -382,36 +361,32 @@ client.sssd.start() - assert client.tools.id("user1") is None, "User user1 should be found only with fq name" - assert client.tools.id("user2") is None, "User user2 should be found only with fq name" + assert client.tools.id("user1") is None, "User user1 should be found only with fq name!" + assert client.tools.id("user2") is None, "User user2 should be found only with fq name!" result = client.tools.id("user1@test") - assert result is not None, "User user1@test was not found using id" - assert result.user.name == "user1@test", f"Username {result.user.name} is incorrect, user1@test expected" - assert result.user.id == 10001, f"User id {result.user.id} is incorrect, 10001 expected" + assert result is not None, "User user1@test was not found using id!" + assert result.user.name == "user1@test", f"Username {result.user.name} is incorrect, user1@test expected!" + assert result.user.id == 10001, f"User id {result.user.id} is incorrect, 10001 expected!" result = client.tools.id("user2@test") - assert result is not None, "User user2@test was not found using id" - assert result.user.name == "user2@test", f"Username {result.user.name} is incorrect, user2@test expected" - assert result.user.id == 10002, f"User id {result.user.id} is incorrect, 10002 expected" + assert result is not None, "User user2@test was not found using id!" + assert result.user.name == "user2@test", f"Username {result.user.name} is incorrect, user2@test expected!" + assert result.user.id == 10002, f"User id {result.user.id} is incorrect, 10002 expected!" @pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_users_when_case_insensitive(client: Client, provider: GenericProvider): +def test_identity__lookup_users_when_case_sensitive_is_false(client: Client, provider: GenericProvider): """ - :title: Search user with case insensitive name when 'case_sensitive' is 'false' + :title: Search user with case-sensitivity is false :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Set users uids - 3. In SSSD domain change 'case_sensitive' to 'false' - 4. Start SSSD + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Configure SSSD with "ldap_id_mapping = false" and "case_sensitive = false" and start SSSD :steps: - 1. Find users with id(name), where name is in random lower and upper case format - 2. Check that usernames are correctly set - 3. Check that users have correct ids + 1. Lookup users by their name randomizing the capitalization of letters in the name + 2. Check the results :expectedresults: 1. Users are found - 2. Users have correct names - 3. Users have correct ids + 2. Results have the correct name and UID :customerscenario: False """ @@ -436,32 +411,29 @@ ]: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.user.name == name.lower(), f"Username {result.user.name} is incorrect, {name.lower()} expected" - assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected" + assert result is not None, f"User {name} was not found using id!" + assert result.user.name == name.lower(), f"Username {result.user.name} is incorrect, {name.lower()} expected!" + assert result.user.id == uid, f"User id {result.user.id} is incorrect, {uid} expected!" @pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_users_fully_qualified_name_and_case_insensitive(client: Client, provider: GenericProvider): +def test_identity__lookup_users_fully_qualified_name_and_case_sensitive_is_false( + client: Client, provider: GenericProvider +): """ - :title: Search user with fq case insensitive name when - 'case_sensitive' is 'false' and 'use_fully_qualified_names' is 'true' + :title: Search user with fully qualified name when case-sensitive is false :setup: - 1. Add 'user1', 'user2' and 'user3' to SSSD - 2. Set users gids and uids - 3. Add 'group1', 'group2' and 'group3' to SSSD - 4. Set groups gids - 5. Add members to the groups - 6. In SSSD domain change 'use_fully_qualified_names' to 'true' - 7. In SSSD domain change 'case_sensitive' to 'false' - 8. Start SSSD + 1. Create the following users 'user1', 'user2' and 'user3' specifying the UIDs and GIDs + 2. Create the following groups 'group1', 'group2' and 'group3' specifying the GIDs + 3. Configure SSSD with "ldap_id_mapping = false", "case_sensitive = false" and + "use_fully_qualified_name = true" and start SSSD :steps: - 1. Find users with id(name) - 2. Find users with id(name@domain) - name is in random lower and upper case format + 1. Lookup users by their name with id + 2. Lookup users with their fully qualified name randomizing the capitalization of letters in the name 3. Check that users have correct groups :expectedresults: 1. Users are not found 2. Users are found - 3. Users are members of correct groups + 3. Users are in the correct groups :customerscenario: False """ @@ -479,49 +451,50 @@ client.sssd.start() - assert client.tools.id("user1") is None, "User user1 should be found only with fq name" - assert client.tools.id("user2") is None, "User user2 should be found only with fq name" - assert client.tools.id("user3") is None, "User user3 should be found only with fq name" + assert client.tools.id("user1") is None, "User user1 should be found only with fully qualified name!" + assert client.tools.id("user2") is None, "User user2 should be found only with fully qualified name!" + assert client.tools.id("user3") is None, "User user3 should be found only with fully qualified name!" for name in ["User1@TesT", "UseR1@TesT", "UsER1@TesT"]: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.memberof([101, 1001, 1002, 1003]), f"User {name} is member of wrong groups" + assert result is not None, f"User {name} was not found using id!" + assert result.memberof([101, 1001, 1002, 1003]), f"User {name} is a member of the wrong groups!" for name in ["uSer2@TeST", "user2@TEsT", "uSER2@tesT"]: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.memberof([102, 1002, 1003]), f"User {name} is member of wrong groups" + assert result is not None, f"User {name} was not found using id!" + assert result.memberof([102, 1002, 1003]), f"User {name} is a member of the wrong groups!" + assert not result.memberof(1001), f"User {name} is in the wrong groups!" for name in ["USer3@TeST", "uSer3@TeST", "USER3@Test"]: result = client.tools.id(name) - assert result is not None, f"User {name} was not found using id" - assert result.memberof([103, 1003]), f"User {name} is member of wrong groups" + assert result is not None, f"User {name} was not found using id!" + assert result.memberof([103, 1003]), f"User {name} is a member of the wrong groups!" + assert not result.memberof([1001, 1002]), f"User {name} is in the wrong groups!" @pytest.mark.importance("critical") -@pytest.mark.authentication @pytest.mark.topology(KnownTopologyGroup.AnyAD) -def test_identity__lookup_idmapping_of_posix_and_non_posix_user_and_group(client: Client, provider: GenericADProvider): +def test_identity__lookup_id_mapping_of_posix_and_non_posix_user_and_group( + client: Client, provider: GenericADProvider +): """ - :title: Check ID mapping of POSIX and non POSIX users in AD type directories when ldap_id_mapping is false + :title: Check ID mapping of POSIX and non-POSIX users in AD directories when id mapping is false + :note: This is a generic provider test, AD is a workaround to create users with no posix attributes :setup: - 1. Create user with POSIX attriubtes + 1. Create user with POSIX attributes 2. Create group with POSIX attributes 3. Create user with no POSIX attributes 4. Create group with no POSIX attributes - 5. Configure SSSD with "ldap_id_mapping" = false - 6. Start SSSD + 5. Configure SSSD with "ldap_id_mapping = false" and start SSSD :steps: - 1. Query POSIX group information - 2. Query POSIX user information - 3. Query Non-POSIX group information - 4. Query Non-POSIX user information - :expectedresults: - 1. POSIX group information should be returned and - gid matches the one supplied in creation - 2. POSIX user information should be returned and - uid matches the one supplied in creation - 3. Non-POSIX group information should not be returned - 4. Non-POSIX user information should not be returned + 1. Query POSIX user information + 2. Query Non-POSIX user information + 3. Query POSIX group information + 4. Query Non-POSIX group information + :expectedresults: + 1. POSIX user found with the correct values + 2. User is not found + 3. POSIX group found with the correct values + 4. Group is not found :customerscenario: False """ @@ -538,34 +511,147 @@ client.sssd.start() - result = client.tools.id("posix_user") - assert result is not None, "posix-user is not returned by sssd" - assert result.group.id == 20001, "gid returned not matched the one provided" - assert result.user.id == 10001, "uid returned not matched the one provided" - - assert client.tools.getent.group("posix_group") is not None, "posix-group is not returned by sssd" - assert client.tools.getent.group("nonposix_group") is None, "non-posix group is returned by sssd, it should not be" + user = client.tools.getent.passwd("posix_user") + assert user is not None, "posix-user not found!" + assert user.uid == 10001, "gid returned does not matched the one provided!" + assert user.gid == 20001, "uid returned does not matched the one provided!" + assert client.tools.getent.passwd("nonposix_user") is None, "nonposix-user found!" + + group = client.tools.getent.group("posix_group") + assert group is not None, "posix-group not found!" + assert group.gid == 20001, "gid is not the correct value!" + assert client.tools.getent.group("nonposix_group") is None, "nonposix-group found!" @pytest.mark.ticket(bz=1695577) +@pytest.mark.importance("critical") @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_identity__lookup_when_private_groups_set_to_hybrid(client: Client, provider: GenericProvider): +def test_identity__lookup_when_auto_private_groups_is_set_to_true(client: Client, provider: GenericProvider): """ - :title: auto_private_groups set to hybrid - :setup: - 1. Add user "user_same" with uid equals to gid - 2. Add user "user_different" with uid not equals to gid - 3. Set auto_private_groups in sssd.conf to hybrid and turn of ldap_id_mapping - 4. Start SSSD + :title: Look up users when auto private groups is set to true + :description: + When true, the user's gid will match the uid, even when the object isn't + a real group in the directory. If it is a real group, the user values will override + the name and gid. In this test, only the users exist in LDAP. + :setup: + 1. Create the following users 'user_same_gid', 'user_diff_gid' and 'user_group_gid'. + Set the uids and gids to match the condition defined by in the username + 2. Configure SSSD with "ldap_id_mapping = false" and "auto_private_groups = true" and start SSSD :steps: - 1. getent passwd "user_same" - 2. getent passwd "user_different" + 1. Lookup all users and compare their uid to their gid + 2. Lookup up the user's gid :expectedresults: - 1. Uid equals to gid - 2. Uid does not equal to gid + 1. All users uid and gid match + 2. All groups are found + :customerscenario: True + :requirement: IDM-SSSD-REQ: SSSD can automatically create user private groups for users + """ + provider.user("user_same_gid").add(uid=111111, gid=111111) + provider.user("user_diff_gid").add(uid=222222, gid=333333) + provider.user("user_no_gid").add(uid=444444) + + client.sssd.domain["auto_private_groups"] = "true" + client.sssd.domain["ldap_id_mapping"] = "false" + + client.sssd.start() + + for i in [("user_same_gid", 111111), ("user_diff_gid", 222222), ("user_no_gid", 444444)]: + user = client.tools.getent.passwd(i[0]) + assert user is not None, f"User '{i[0]}' is not found!" + assert user.uid == (i[1]), "uid does not match expected value!" + assert user.uid == user.gid, "uid does not match gid!" + + group = client.tools.getent.group(i[0]) + assert group is not None, f"{i[0]} group is not found!" + + +@pytest.mark.ticket(bz=1695577) +@pytest.mark.importance("high") +@pytest.mark.topology(KnownTopologyGroup.AnyProvider) +def test_identity__lookup_when_auto_private_groups_is_set_to_false(client: Client, provider: GenericProvider): + """ + :title: Look up users when auto private groups is set to false + :description: + When false, to be able to look up the group, the group needs to exist + in the directory. In this test, only the 'user_group_gid' user has a valid LDAP group. + :setup: + 1. Create a group + 2. Create the following users 'user_same_gid', 'user_diff_gid' and 'user_group_gid'. + Set the uids and gids to match the condition defined by in the username + 3. Configure SSSD with "ldap_id_mapping = false" and "auto_private_groups = false" and start SSSD + :steps: + 1. Lookup 'user_same_gid' and look up the user's gid + 2. Lookup 'user_diff_gid' and look up the user's gid + 3. Lookup 'user_group_gid' and look up the user's gid + :expectedresults: + 1. The user is found with the configured values, and the group is *NOT* found + 2. The user is found with the configured values, and the group is *NOT* found + 3. The user is found with the configured values, and the group is found + :customerscenario: True + :requirement: IDM-SSSD-REQ: SSSD can automatically create user private groups for users + """ + provider.group("group").add(gid=444444) + provider.user("user_same_gid").add(uid=111111, gid=111111) + provider.user("user_diff_gid").add(uid=222222, gid=333333) + provider.user("user_group_gid").add(uid=444444, gid=444444) + + client.sssd.domain["auto_private_groups"] = "false" + client.sssd.domain["ldap_id_mapping"] = "false" + + client.sssd.start() + + result = client.tools.getent.passwd("user_same_gid") + assert result is not None, "User 'user_same_gid' not found!" + assert result.gid == 111111, "gid does not match expected value!" + + # IPA manages auto_private_groups on the server and is true by default + if isinstance(provider, IPA): + assert client.tools.getent.group(111111), "Group is not found!" + else: + assert not client.tools.getent.group(111111), "Group should not be found!" + + result = client.tools.getent.passwd("user_diff_gid") + assert result is not None, "User 'user_diff_gid' is not found!" + assert result.gid == 333333, "gid does not match expected value!" + assert client.tools.getent.group(333333) is None, "group is found!" + + result = client.tools.getent.passwd("user_group_gid") + assert result is not None, "User 'user_group_gid' is not found!" + assert result.gid == 444444, "gid does not match expected value!" + assert client.tools.getent.group(444444) is not None, "group is not found!" + + +@pytest.mark.ticket(bz=1695577) +@pytest.mark.importance("high") +@pytest.mark.topology(KnownTopologyGroup.AnyProvider) +def test_identity__lookup_when_auto_private_groups_is_set_to_hybrid(client: Client, provider: GenericProvider): + """ + :title: Look up users when auto private groups is set to hybrid + :description: + When set to hybrid, if the uid and gid match for the user, it will act as if a + group exists similar to when the parameter is set to true. Like when it's set to false, if the + group exists in LDAP, it will look at whatever is existing for its values. + :setup: + 1. Create a group + 2. Create the following users 'user_same_gid', 'user_diff_gid', 'user_no_gid' and 'user_group_gid'. + Set the uids and gids to match the condition defined by in the username + 3. Configure SSSD with "ldap_id_mapping = false" and "auto_private_groups = hybrid" start SSSD + :steps: + 1. Lookup 'user_same_gid' and look up the user's gid + 2. Lookup 'user_diff_gid' and look up the user's gid + 3. Lookup 'user_no_gid' and look up the user's gid + 4. Lookup 'user_group_gid' and look up the user's gid + :expectedresults: + 1. The user is found with the configured values, and the group is found + 2. The user is found with the configured values, and the group is *NOT* found + 3. The user is found with the configured values, and the group is *NOT* found + 4. The user is found with the configured values, and the group is found :customerscenario: True :requirement: IDM-SSSD-REQ: SSSD can automatically create user private groups for users """ - provider.user("user_same").add(uid=111111, gid=111111) - provider.user("user_different").add(uid=111111, gid=100000) + provider.group("group").add(gid=55555) + provider.user("user_same_gid").add(uid=111111, gid=111111) + provider.user("user_diff_gid").add(uid=222222, gid=333333) + provider.user("user_no_gid").add(uid=444444) + provider.user("user_group_gid").add(uid=555555, gid=555555) client.sssd.domain["auto_private_groups"] = "hybrid" @@ -574,9 +660,24 @@ client.sssd.start() - result = client.tools.getent.passwd("user_same@test") - assert result, "getent passwd failed on user_same" - assert result.uid == result.gid, "gid and uid for user_same are not same" - - result = client.tools.getent.passwd("user_different@test") - assert result, "getent passwd failed on user_different" - assert result.uid != result.gid, "gid and uid for user_different are same" + result = client.tools.getent.passwd("user_same_gid") + assert result is not None, "User 'user_same_gid' not found!" + assert result.gid == 111111, "gid does not match expected value!" + assert client.tools.getent.group(111111) is not None, "auto private group not found!" + + result = client.tools.getent.passwd("user_diff_gid") + assert result is not None, "User 'user_diff_gid' not found!" + assert result.gid == 333333, "gid does not match expected value!" + assert client.tools.getent.group(333333) is None, "auto private group should not be found!" + + # IPA manages auto_private_groups on the server and is true by default + if isinstance(provider, IPA): + result = client.tools.getent.passwd("user_group_gid") + assert result is not None, "User 'user_group_gid' not found!" + assert result.gid == 555555, "gid is not found!" + else: + assert client.tools.getent.passwd("user_no_id") is None, "gid should not be found!" + + result = client.tools.getent.passwd("user_group_gid") + assert result is not None, "User 'user_group_gid' not found!" + assert result.gid == 555555, "gid does not match expected value!" + assert client.tools.getent.group(555555) is not None, "auto private group not found!" Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_infopipe.py Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_ipa.py Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_ipa_trusts.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_kcm.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_kcm.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_kcm.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_kcm.py 2024-10-01 18:30:01.000000000 +0000 @@ -10,5 +10,5 @@ import pytest -from pytest_mh.ssh import SSHProcessError +from pytest_mh.conn import ProcessError from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.kdc import KDC @@ -33,5 +33,5 @@ 2. Count existing credential caches 3. Kinit as "tuser" - 4. Check that TGT was aquired + 4. Check that TGT was acquired 5. Count existing credential caches 6. Repeat steps 3-5 @@ -54,13 +54,13 @@ with client.ssh("tuser", "Secret123") as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.cache_count() == 0 + assert krb.cache_count() == 0, "KRB cache is not empty!" - assert krb.kinit("tuser", password="Secret123").rc == 0 - assert krb.has_tgt("tuser", kdc.realm) - assert krb.cache_count() == 1 - - assert krb.kinit("tuser", password="Secret123").rc == 0 - assert krb.has_tgt("tuser", kdc.realm) - assert krb.cache_count() == 1 + assert krb.kinit("tuser", password="Secret123").rc == 0, "kinit failed!" + assert krb.has_tgt("tuser", kdc.realm), "No ticket found!" + assert krb.cache_count() == 1, "KRB cache value is not 1!" + + assert krb.kinit("tuser", password="Secret123").rc == 0, "kinit failed!" + assert krb.has_tgt("tuser", kdc.realm), "No ticket found!" + assert krb.cache_count() == 1, "KRB cache value is not 1!" @@ -98,5 +98,5 @@ 6. 3 ccaches exist, "carol" is the primary ccache, TGT is only ticket in "alice" and "bob" ccache, TGT and "host/myhost" are only tickets in "carol" ccache - 7. 2 cacches exit + 7. 2 ccaches exit 8. 3 ccaches exist, "carol" is the primary ccache, TGT is only ticket in "alice", "bob" and "carol" ccache 9. No ccache is available @@ -115,39 +115,41 @@ with client.ssh("tuser", "Secret123") as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.cache_count() == 0 + assert krb.cache_count() == 0, "KRB cache is not empty!" krb.kinit("alice", password="Secret123") - assert krb.cache_count() == 1 - assert krb.has_primary_cache("alice", kdc.realm) - assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]) + assert krb.cache_count() == 1, "KRB cache value is not 1!" + assert krb.has_primary_cache("alice", kdc.realm), "User 'alice' missing in cache!" + assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]), "No ticket for user 'alice' found!" krb.kinit("bob", password="Secret123") - assert krb.cache_count() == 2 - assert krb.has_primary_cache("bob", kdc.realm) - assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]) + assert krb.cache_count() == 2, "KRB cache value is not 2!" + assert krb.has_primary_cache("bob", kdc.realm), "User 'bob' missing in cache!" + assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]), "No ticket for user 'bob' found!" krb.kinit("carol", password="Secret123") - assert krb.cache_count() == 3 - assert krb.has_primary_cache("carol", kdc.realm) - assert krb.has_tickets("carol", kdc.realm, [kdc.tgt]) + assert krb.cache_count() == 3, "KRB cache value is not 3!" + assert krb.has_primary_cache("carol", kdc.realm), "User 'carol' missing in cache!" + assert krb.has_tickets("carol", kdc.realm, [kdc.tgt]), "No ticket for user 'carol' found!" krb.kvno("host/myhost") - assert krb.cache_count() == 3 - assert krb.has_primary_cache("carol", kdc.realm) - assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]) - assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]) - assert krb.has_tickets("carol", kdc.realm, [kdc.tgt, kdc.qualify("host/myhost")]) + assert krb.cache_count() == 3, "KRB cache value is not 3!" + assert krb.has_primary_cache("carol", kdc.realm), "User 'carol' missing in cache!" + assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]), "No ticket for user 'alice' found!" + assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]), "No ticket for user 'bob' found!" + assert krb.has_tickets( + "carol", kdc.realm, [kdc.tgt, kdc.qualify("host/myhost")] + ), "No ticket for user 'carol' found!" # kdestroy 'carol' is the last primary cache krb.kdestroy() - assert krb.cache_count() == 2 + assert krb.cache_count() == 2, "KRB cache value is not 2!" # kinit 'carol' again krb.kinit("carol", password="Secret123") - assert krb.cache_count() == 3 - assert krb.has_primary_cache("carol", kdc.realm) - assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]) - assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]) - assert krb.has_tickets("carol", kdc.realm, [kdc.tgt]) + assert krb.cache_count() == 3, "KRB cache value is not 3!" + assert krb.has_primary_cache("carol", kdc.realm), "User 'carol' missing in cache!" + assert krb.has_tickets("alice", kdc.realm, [kdc.tgt]), "No ticket for user 'alice' found!" + assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]), "No ticket for user 'bob' found!" + assert krb.has_tickets("carol", kdc.realm, [kdc.tgt]), "No ticket for user 'carol' found!" # kdestroy all @@ -203,25 +205,31 @@ with client.ssh("tuser", "Secret123") as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.cache_count() == 0 + assert krb.cache_count() == 0, "KRB cache is not empty!" krb.kinit("alice", password="Secret123") - assert krb.has_primary_cache("alice", kdc.realm) + assert krb.has_primary_cache("alice", kdc.realm), "User 'alice' missing in cache!" krb.kinit("bob", password="Secret123") - assert krb.has_primary_cache("bob", kdc.realm) + assert krb.has_primary_cache("bob", kdc.realm), "User 'bob' missing in cache!" krb.kswitch("alice", kdc.realm) - assert krb.has_primary_cache("alice", kdc.realm) + assert krb.has_primary_cache("alice", kdc.realm), "User 'alice' missing in cache!" krb.kvno("host/alice") - assert krb.cache_count() == 2 - assert krb.has_tickets("alice", kdc.realm, [kdc.tgt, kdc.qualify("host/alice")]) - assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]) + assert krb.cache_count() == 2, "KRB cache value is not 2!" + assert krb.has_tickets( + "alice", kdc.realm, [kdc.tgt, kdc.qualify("host/alice")] + ), "No ticket for user 'alice' found!" + assert krb.has_tickets("bob", kdc.realm, [kdc.tgt]), "No ticket for user 'bob' found!" krb.kswitch("bob", kdc.realm) krb.kvno("host/bob") - assert krb.cache_count() == 2 - assert krb.has_tickets("alice", kdc.realm, [kdc.tgt, kdc.qualify("host/alice")]) - assert krb.has_tickets("bob", kdc.realm, [kdc.tgt, kdc.qualify("host/bob")]) + assert krb.cache_count() == 2, "KRB cache value is not 2!" + assert krb.has_tickets( + "alice", kdc.realm, [kdc.tgt, kdc.qualify("host/alice")] + ), "No ticket for user 'alice' found!" + assert krb.has_tickets( + "bob", kdc.realm, [kdc.tgt, kdc.qualify("host/bob")] + ), "No ticket for user 'bob' found!" @@ -275,5 +283,5 @@ with client.ssh("tuser", "Secret123") as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.cache_count() == 0 + assert krb.cache_count() == 0, "KRB cache value is not 0!" krb.kinit("alice", password="Secret123") @@ -288,17 +296,21 @@ } - assert krb.cache_count() == 2 + assert krb.cache_count() == 2, "KRB cache value is not 2!" for principal, ccache in krb.list_ccaches().items(): principals = krb.list_principals(env={"KRB5CCNAME": ccache}) - assert len(principals) == 1 - assert principal in principals - assert principals[principal] == expected[principal] + assert len(principals) == 1, "Principals count is not 1!" + assert principal in principals, f"{principal} not in {principals}!" + assert principals[principal] == expected[principal], "Principal ccache contains incorrect data!" principals = krb.list_principals(env={"KRB5CCNAME": "KCM:"}) - assert len(principals) == 2 - assert kdc.qualify("alice") in principals - assert kdc.qualify("bob") in principals - assert principals[kdc.qualify("alice")] == expected[kdc.qualify("alice")] - assert principals[kdc.qualify("bob")] == expected[kdc.qualify("bob")] + assert len(principals) == 2, "KCM principals count is not 2!" + assert kdc.qualify("alice") in principals, "'alice' not in principals!" + assert kdc.qualify("bob") in principals, "'bob' not in principals!" + assert ( + principals[kdc.qualify("alice")] == expected[kdc.qualify("alice")] + ), "Principal 'alice' in KCM does not match 'alice' in ccache!" + assert ( + principals[kdc.qualify("bob")] == expected[kdc.qualify("bob")] + ), "Principal 'bob' in KCM does not match 'bob' in ccache!" @@ -332,9 +344,9 @@ with client.ssh("tuser", "Secret123") as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.cache_count() == 0 + assert krb.cache_count() == 0, "KRB cache value is not 0!" try: krb.kdestroy() except Exception as e: - assert False, f"kdestroy raised an error: {e}" + assert False, f"Destroying cache raised an error: {e}" @@ -353,5 +365,5 @@ 1. Authenticate as "tuser" over SSH 2. Kinit as "tuser" and request renewable ticket - 3. Wait until automatic renewal is triggered and check that is was renewed + 3. Wait until automatic renewal is triggered and check that it was renewed :expectedresults: 1. User is logged into the host @@ -377,5 +389,5 @@ (renew_start, _) = krb.list_tgt_times(kdc.realm) - assert init_start < renew_start + assert init_start < renew_start, "Initial renewal times exceeds renewal interval!" @@ -411,8 +423,8 @@ with client.ssh(username, password) as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.kinit(username, password=password).rc == 0, "Kinit with correct password failed" - with pytest.raises(SSHProcessError): + assert krb.kinit(username, password=password).rc == 0, "kinit failed!" + with pytest.raises(ProcessError): krb.kinit(username, password="wrong") - assert krb.klist().rc == 0, "Klist failed" + assert krb.klist().rc == 0, "klist failed!" @@ -451,5 +463,5 @@ output = client.fs.wc(kcm_log_file, lines=True).stdout return int(output.split()[0]) - except SSHProcessError: + except ProcessError: return 0 @@ -475,9 +487,9 @@ end_log_nodebug = kcm_log_length() - assert start_log_length == end_log_nodebug, "Debug messages were generated" + assert start_log_length == end_log_nodebug, "Debug messages present!" client.sssd.kcm["debug_level"] = "9" client.sssd.config_apply() - assert client.svc.restart("sssd-kcm").rc == 0, "Restart of kcm failed" + assert client.svc.restart("sssd-kcm").rc == 0, "KCM restart failed!" with client.ssh(user, password) as ssh: @@ -486,12 +498,12 @@ end_log_debug = kcm_log_length() - assert start_log_length + 100 < end_log_debug, "Debug messages were not generated" + assert start_log_length + 100 < end_log_debug, "Debug messages missing!" @pytest.mark.importance("high") @pytest.mark.topology(KnownTopology.LDAP) -def test_kcm_ssh_login_creates_kerberos_ticket(client: Client, ldap: LDAP, kdc: KDC): +def test_kcm__ssh_login_creates_kerberos_ticket(client: Client, ldap: LDAP, kdc: KDC): """ - :title: kcm: Verify ssh login is successuful with kcm as default + :title: kcm: Verify ssh login is successful with kcm as default :setup: 1. Add user and principal @@ -515,5 +527,5 @@ with client.auth.kerberos(ssh) as krb: res = krb.klist() - assert res.rc == 0, "Klist failed" + assert res.rc == 0, "klist failed!" @@ -530,5 +542,5 @@ 1. Authenticate as "user0" over SSH 2. Set "max_uid_ccaches" to "1" and check its enforcement - 3. Remove "max_uid_ccaches" so its set to default + 3. Remove "max_uid_ccaches" to use the default value 4. Check the enforcement of quotas 5. Set "max_uid_ccaches" to "65" and check its enforcement @@ -567,6 +579,6 @@ client.sssd.config_apply() client.svc.restart("sssd-kcm") - assert krb.kinit(user0, password=password).rc == 0 - with pytest.raises(SSHProcessError): + assert krb.kinit(user0, password=password).rc == 0, "max_uid_ccache = 1, kinit failed!" + with pytest.raises(ProcessError): krb.kinit(user1, password=password) @@ -577,6 +589,6 @@ for i in range(1, 64): user = f"user{i}" - assert krb.kinit(user, password=password).rc == 0 - with pytest.raises(SSHProcessError): + assert krb.kinit(user, password=password).rc == 0, "max_uid_ccache = 64, kinit failed!" + with pytest.raises(ProcessError): krb.kinit("user64", password=password) @@ -585,6 +597,6 @@ client.sssd.config_apply() client.svc.restart("sssd-kcm") - assert krb.kinit("user64", password=password).rc == 0 - with pytest.raises(SSHProcessError): + assert krb.kinit("user64", password=password).rc == 0, "max_uid_ccache = 65, kinit failed!" + with pytest.raises(ProcessError): krb.kinit("user65", password=password) @@ -592,9 +604,9 @@ with client.ssh(user1, password) as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.kinit("user65", password=password).rc == 0 + assert krb.kinit("user65", password=password).rc == 0, "kinit failed!" # kdestroy and then kinit with client.ssh("user0", password) as ssh: with client.auth.kerberos(ssh) as krb: - assert krb.kdestroy(all=True).rc == 0 - assert krb.kinit("user65", password=password).rc == 0 + assert krb.kdestroy(all=True).rc == 0, "kdestroy all tickets failed!" + assert krb.kinit("user65", password=password).rc == 0, "kinit failed!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_ldap.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_ldap.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_ldap.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_ldap.py 2024-10-01 18:30:01.000000000 +0000 @@ -17,24 +17,33 @@ @pytest.mark.ticket(bz=[795044, 1695574]) @pytest.mark.importance("critical") -@pytest.mark.authentication @pytest.mark.parametrize("modify_mode", ["exop", "ldap_modify"]) @pytest.mark.parametrize("use_ppolicy", ["true", "false"]) -@pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) +@pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.require( lambda client, sssd_service_user: ((sssd_service_user == "root") or client.features["non-privileged"]), "SSSD was built without support for running under non-root", ) -def test_ldap__password_change(client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str, sssd_service_user: str): +@pytest.mark.builtwith("ldap_use_ppolicy") +def test_ldap__password_change_using_ppolicy( + client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str, sssd_service_user: str +): """ - :title: Change password with "ldap_pwmodify_mode" set to @modify_mode + :title: Password change using ppolicy + :description: PPolicy overlay is the latest implementation of IETF password policy for LDAP. + This extends the password policy for the LDAP server and is configured in SSSD using + 'ldap_use_ppolicy'. + + Two password modification modes are tested, Extended Operation (exop), the default and then + LDAP (ldapmodify), set by 'ldap_pwmodify_mode' parameter. + :note: This feature is introduced in SSSD 2.10.0 :setup: - 1. Add user to LDAP, set his password - 2. Allow user to change his password + 1. Add a user to LDAP + 2. Configure the LDAP ACI to permit user password changes 3. Set "ldap_pwmodify_mode" 4. Start SSSD :steps: - 1. Authenticate user with old password - 2. Change password of user to new password + 1. Authenticate as user + 2. Change the password of user 3. Authenticate user with new password 4. Authenticate user with old password @@ -53,30 +62,31 @@ ldap.aci.add('(targetattr="userpassword")(version 3.0; acl "pwp test"; allow (all) userdn="ldap:///self";)') - client.sssd.set_service_user(sssd_service_user) client.sssd.domain["ldap_pwmodify_mode"] = modify_mode client.sssd.domain["ldap_use_ppolicy"] = use_ppolicy - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) - assert client.auth.ssh.password(user, old_pass), "Authentication with old correct password failed" + assert client.auth.ssh.password(user, old_pass), "Login with old password failed!" - assert client.auth.passwd.password(user, old_pass, new_pass), "Password change was not successful" + assert client.auth.passwd.password(user, old_pass, new_pass), "Password change failed!" - assert client.auth.ssh.password(user, new_pass), "Authentication with new correct password failed" - assert not client.auth.ssh.password(user, old_pass), "Authentication with old incorrect password did not fail" + assert client.auth.ssh.password(user, new_pass), "User login failed!" + assert not client.auth.ssh.password(user, old_pass), "Login with old password passed!" @pytest.mark.ticket(bz=[795044, 1695574]) +@pytest.mark.importance("critical") @pytest.mark.parametrize("modify_mode", ["exop", "ldap_modify"]) @pytest.mark.parametrize("use_ppolicy", ["true", "false"]) @pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__password_change_new_passwords_do_not_match( +@pytest.mark.builtwith("ldap_use_ppolicy") +def test_ldap__password_change_new_passwords_do_not_match_using_ppolicy( client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str ): """ - :title: Change password with "ldap_pwmodify_mode" set to @modify_mode, but retyped password do not match + :title: Password change when the new passwords do not match :setup: - 1. Add user to LDAP, set his password - 2. Allow user to change his password - 3. Set "ldap_pwmodify_mode" + 1. Add user to LDAP + 2. Configure the LDAP ACI to permit user password changes + 3. set "ldap_pwmodify_mode" 4. Start SSSD :steps: @@ -95,19 +105,21 @@ assert not client.auth.passwd.password( "user1", "Secret123", "Red123", "Hat000" - ), "Password changed successfully, which is not expected" + ), "Password should not have been able to be changed!" @pytest.mark.ticket(bz=[795044, 1695574, 1795220]) +@pytest.mark.importance("critical") @pytest.mark.parametrize("modify_mode", ["exop", "ldap_modify"]) @pytest.mark.parametrize("use_ppolicy", ["true", "false"]) @pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__password_change_new_password_does_not_meet_complexity_requirements( +@pytest.mark.builtwith("ldap_use_ppolicy") +def test_ldap__password_change_new_password_does_not_meet_complexity_requirements_using_ppolicy( client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str ): """ - :title: Change password to lower-case letters, password check fail + :title: Password change when the new passwords do not meet the complexity requirements using ppolicy :setup: - 1. Add user to LDAP, set his password - 2. Allow user to change his password + 1. Add a user to LDAP + 2. Configure the LDAP ACI to permit user password changes 3. Set "passwordCheckSyntax" to "on" 4. Set "ldap_pwmodify_mode" @@ -131,26 +143,30 @@ assert not client.auth.passwd.password( "user1", "Secret123", "red_32" - ), "Password changed successfully, which is not expected" + ), "Password should not have been able to be changed!" assert ( "pam_sss(passwd:chauthtok): User info message: Password change failed." - in client.host.ssh.run("journalctl").stdout + in client.host.conn.run("journalctl").stdout ) @pytest.mark.ticket(bz=[1695574, 1795220]) +@pytest.mark.importance("critical") @pytest.mark.parametrize("modify_mode", ["exop", "ldap_modify"]) @pytest.mark.parametrize("use_ppolicy", ["true", "false"]) @pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__password_change_failed_current_password(client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str): +@pytest.mark.builtwith("ldap_use_ppolicy") +def test_ldap__password_change_with_invalid_current_password_using_ppolicy( + client: Client, ldap: LDAP, modify_mode: str, use_ppolicy: str +): """ - :title: Password change failed because an incorrect password was used + :title: Password change fails with invalid current password :setup: - 1. Add user to LDAP, set his password - 2. Allow user to change his password + 1. Add a user to LDAP, set his password + 2. Configure the LDAP ACI to permit user password changes 3. Set "ldap_pwmodify_mode" 4. Start SSSD :steps: - 1. Change password to new password, but enter wrong password + 1. Attempt to change the password but enter the incorrect password :expectedresults: 1. Password change is not successful @@ -164,34 +180,37 @@ client.sssd.start() - assert not client.auth.passwd.password("user1", "wrong123", "Newpass123"), "Password change did not fail" + assert not client.auth.passwd.password( + "user1", "wrong123", "Newpass123" + ), "Password should not have been able to be changed!" +@pytest.mark.importance("low") @pytest.mark.ticket(bz=[1067476, 1065534]) @pytest.mark.topology(KnownTopology.LDAP) def test_ldap__authenticate_user_with_whitespace_prefix_in_userid(client: Client, ldap: LDAP): """ - :title: user with a whitespace at beginning is able to login and "id" + :title: Authenticate with a user containing a blank space in the userid + :description: This can only be tested on LDAP because most directories have + constraints on the values, protecting the integrity of the data. This scenario + is most likely created migrating and, or upgrading old databases. :setup: - 1. Add users " space1" and "user1" to LDAP - 2. Set uids and passwords to users - 3. Clear memcache, logs and db - 4. Start SSSD + 1. Add users " space1" and "user1" + 2. Start SSSD :steps: - 1. Fetch user " space1" information using 'id' - 2. Login user " space1" via ssh - 3. Login user "space1" via ssh - 4. Fetch "user1" user information using 'id' - 5. Fetch " user1" user information using 'id' - :expectedresults: - 1. " space1" is fetched and has correct id - 2. " space1" is able to login - 3. "space1" is not able to login - 4. "user1" is fetched and has correct id - 5. " user1" is not fetched + 1. Lookup user " space1" + 2. Login user " space1" + 3. Login user "space1" + 4. Lookup "user1" user + 5. Lookup " user1" user + :expectedresults: + 1. " space1" is found and has correct id + 2. " space1" is able to log in + 3. "space1" is not able to log in + 4. "user1" is found and has correct id + 5. " user1" is not found :customerscenario: True """ ldap.user(" space1").add(uid=10011, password="Secret123") ldap.user("user1").add(uid=10012, password="Secret123") - client.sssd.clear(db=True, memcache=True, logs=True) client.sssd.start() @@ -200,34 +219,34 @@ assert result.user.id == 10011, "User ' space1' has wrong id" - assert client.auth.ssh.password(" space1", "Secret123"), "Authentication for user ' space1' failed" - assert not client.auth.ssh.password("space1", "Secret123"), "Authentication for user 'space1' did not fail" + assert client.auth.ssh.password(" space1", "Secret123"), "User ' space1' login failed!" + assert not client.auth.ssh.password("space1", "Secret123"), "User 'space1' login should have failed!" result = client.tools.id("user1") - assert result is not None, "User 'user1' was not found" - assert result.user.id == 10012, "User 'user1' has wrong id" + assert result is not None, "User 'user1' not found!" + assert result.user.id == 10012, "User 'user1' has the wrong uid!" result = client.tools.id(" user1") - assert result is None, "User ' user1' was found, not expected" + assert result is None, "User ' user1' should not be found!" @pytest.mark.importance("high") -@pytest.mark.authentication @pytest.mark.ticket(bz=1507035) @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.parametrize("method", ["su", "ssh"]) -def test_ldap__change_password_when_ldap_pwd_policy_is_set_shadow(client: Client, ldap: LDAP, method: str): +def test_ldap__change_password_when_ldap_pwd_policy_is_set_to_shadow(client: Client, ldap: LDAP, method: str): """ - :title: Change password with shadow ldap password policy + :title: Change password with shadow ldap password policy is set to shadow + :description: Changing a password when the password policy is managed by the shadowAccount objectclass. :setup: - 1. Allow user to change its own password in LDAP - 2. Create LDAP user "tuser" with shadowLastChange = 0 - 3. Set ldap_pwd_policy to "shadow" - 4. Set ldap_chpass_update_last_change to "True" + 1. Configure the LDAP ACI to permit user password changes + 2. Create user with shadowLastChange = 0, shadowMin = 0, shadowMax = 99999 and shadowWarning = 7 + 3. Set "ldap_pwd_policy = shadow" + 4. Set "ldap_chpass_update_last_change = True" 5. Start SSSD :steps: 1. Authenticate as "tuser" with old password - 2. Autheticate as "tuser" with new password + 2. Authenticate as "tuser" with new password :expectedresults: - 1. Password was expired and new password was expected and provided + 1. The password is expired, and the user is forced to change their password 2. Authentication with new password was successful :customerscenario: True @@ -242,50 +261,8 @@ client.sssd.start() - # Password is expired, change it - assert client.auth.parametrize(method).password_expired("tuser", "Secret123", "Redhat@321") - - # Authenticate with new password - assert client.auth.parametrize(method).password("tuser", "Redhat@321") - - -@pytest.mark.importance("medium") -@pytest.mark.ticket(bz=1928648) -@pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__network_timeout_parameters_shown_in_logs(client: Client, ldap: LDAP): - """ - :title: Each timeout setting is properly logged in logs - :setup: - 1. Add user - 2. Start SSSD - :steps: - 1. Check that "Setting 6 seconds timeout [ldap_network_timeout] for connecting" is in logs - 2. Fetch information about user - 3. Block LDAP traffic - 4. Connect user over SSH - 5. Logs should contain following timeout parameters - - ldap_opt_timeout - - ldap_search_timeout - - ldap_network_timeout - - dns_resolver_timeout - :expectedresults: - 1. Timeout setting is stored in logs - 2. User is found - 3. LDAP traffic is blocked - 4. User is unable to connect - 5. The timeout parameters are in the logs - :customerscenario: True - """ - ldap.user("user1").add(password="Secret123") - client.sssd.start() - - log = client.fs.read(f"/var/log/sssd/sssd_{client.sssd.default_domain}.log") - assert "Setting 6 seconds timeout [ldap_network_timeout] for connecting" in log - - assert client.tools.id("user1") is not None - - client.firewall.outbound.drop_host(ldap) - - with pytest.raises(Exception): - client.ssh("user1", "Secret123").connect() + assert client.auth.parametrize(method).password_expired( + "tuser", "Secret123", "Redhat@321" + ), "Password change failed!" + assert client.auth.parametrize(method).password("tuser", "Redhat@321"), "User 'tuser' login failed!" log = client.fs.read(f"/var/log/sssd/sssd_{client.sssd.default_domain}.log") @@ -294,35 +271,28 @@ +@pytest.mark.importance("critical") @pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__authenticate_user_with_empty_ldap_search_base(client: Client, ldap: LDAP): +def test_ldap__search_base_is_discovered_and_defaults_to_root_dse(client: Client, ldap: LDAP): """ - :title: Without ldapsearch base specified in sssd conf and rootDSE exists + :title: Search base is discovered and defaults to the directories root DSE :setup: - 1. With sssd config set enumerate = True. - 2. Set sssd config nss part with filter_groups and filter_users to root. - 3. Add test user with password and make sure it can authenticate. + 1. Create OU + 2. Create user, and put the user object in the new OU + 3. Start SSSD :steps: - 1. Without ldap_search_base set when user authenticates certain logs - should appear in sssd domain logs. - 2. Now set ldap_search_base in sssd config try with user authentication , - in sssd domain logs sdap_set_config_options_with_rootdse should not appear. + 1. Authenticate as user and check the logs + 2. Add "ldap_search_base" to the configuration and cleanly restart SSSD + 3. Authenticate as user and check the logs :expectedresults: - 1. Certain logs should appear in sssd domain logs - 2. In sssd domain logs sdap_set_config_options_with_rootdse should not appear. + 1. User authentication is successful, and logs contain messages discovering root DSE + 2. SSSD is configured and cleanly restarted + 3. User authentication is successful, and logs contain no messages searching root DSE :customerscenario: False """ base = ldap.ldap.naming_context - client.sssd.dom("test")["enumerate"] = "true" - client.sssd.config["nss"] = { - "filter_groups": "root", - "filter_users": "root", - } - ou_users = ldap.ou("users").add() user = ldap.user("puser1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") - client.sssd.stop() - client.sssd.clear() client.sssd.start() @@ -337,5 +307,5 @@ f"Setting option [ldap_netgroup_search_base] to [{base}]", ]: - assert doc in str(log) + assert doc in str(log), f"String '{doc}' not found in logs!" client.sssd.dom("test")["ldap_search_base"] = ldap.ldap.naming_context @@ -344,11 +314,12 @@ client.sssd.start() - assert client.auth.ssh.password("puser1", "Secret123") + assert client.auth.ssh.password("puser1", "Secret123"), "User 'puser1' login failed!" time.sleep(3) log = client.fs.read(client.sssd.logs.domain()) - assert "sdap_set_config_options_with_rootdse" not in log + assert "sdap_set_config_options_with_rootdse" not in log, "sdap_set_config_options_with_rootdse found in logs!" +@pytest.mark.importance("medium") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.parametrize( @@ -360,37 +331,24 @@ ], ) -def test_ldap__authenticate_user_with_search_base_set(client: Client, ldap: LDAP, user_search_base, search_base): +def test_ldap__search_base_is_discovered_and_defaults_to_root_dse_users_groups_and_netgroups( + client: Client, ldap: LDAP, user_search_base, search_base +): """ - :title: Without ldapsearch base and with ldap user search base specified + :title: Search base is discovered and defaults to the directories root DSE for users, groups and netgroups :setup: - 1. With sssd config set enumerate = True. - 2. Set sssd config nss part with filter_groups and filter_users to root. - 3. Add test user with password and make sure it can authenticate. + 1. Create People OU + 2. Create user, and put the user object in the new OU + 3. Configure SSSD with "user_search_base" and start SSSD :steps: - 1. Set user_search_base to sssd config. - 2. Set ldap_group_search_base to sssd config. - 3. Set ldap_netgroup_search_base to sssd config. - 4. With each search base there will be different logs generated in sssd domain logs. + 1. Lookup user and authenticate as user and check the logs :expectedresults: - 1. User_search_base should be set to sssd config. - 2. Ldap_group_search_base should be set to sssd config. - 3. Ldap_netgroup_search_base should be set to sssd config. - 4. There will be different logs generated in sssd domain logs. + 1. User authentication is successful, and logs contain messages setting ldap_x_search_base to the root DSE :customerscenario: False """ base = ldap.ldap.naming_context - - client.sssd.dom("test")["enumerate"] = "true" - client.sssd.dom("test")[user_search_base] = search_base - client.sssd.config["nss"] = { - "filter_groups": "root", - "filter_users": "root", - } - ou_users = ldap.ou("People").add() user = ldap.user("puser1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") - client.sssd.stop() - client.sssd.clear() + client.sssd.dom("test")[user_search_base] = search_base client.sssd.start() @@ -411,5 +369,5 @@ f"Setting option [ldap_netgroup_search_base] to [{base}]", ]: - assert doc in str(log) + assert doc in str(log), f"String '{doc}' not found in logs!" case "ldap_group_search_base": for doc in [ @@ -419,5 +377,5 @@ f"Setting option [ldap_netgroup_search_base] to [{base}]", ]: - assert doc in str(log) + assert doc in str(log), f"String '{doc}' not found in logs!" case "ldap_netgroup_search_base": for doc in [ @@ -427,67 +385,57 @@ f"Setting option [ldap_group_search_base] to [{base}]", ]: - assert doc in str(log) + assert doc in str(log), f"String '{doc}, not found in logs!" @pytest.mark.topology(KnownTopology.LDAP) -def test_ldap__lookup_user_default_naming_context_and_no_search_base(client: Client, ldap: LDAP): +def test_ldap__lookup_user_with_search_bases(client: Client, ldap: LDAP): """ - :title: Without ldapsearch base and default namingContexts + :title: Looking up with no search base configured :setup: - 1. With sssd config set enumerate = True. - 2. Set sssd config nss part with filter_groups and filter_users to root. - 3. Add test user with password and make sure it can authenticate. + 1. Create People OU + 2. Create user and put the user object into the OU + 3. Start SSSD :steps: - 1. Sssd without ldapsearch base and default namingContexts. - 2. Sssd should generate some logs when try to authenticate with users. + 1. Lookup user + 2. Look at logs :expectedresults: - 1. Sssd should work without ldapsearch base and default namingContexts. - 2. Sssd should generate some logs when try to authenticate with users. + 1. User is found + 2. Strings pertaining to rootdse search base discovery are found :customerscenario: False """ base = ldap.ldap.naming_context - client.sssd.dom("test")["enumerate"] = "true" - client.sssd.config["nss"] = { - "filter_groups": "root", - "filter_users": "root", - } - ou_users = ldap.ou("People").add() user = ldap.user("puser1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") - client.sssd.stop() - client.sssd.clear() client.sssd.start() result = client.tools.getent.passwd(user.name) - assert result is not None - assert result.name == user.name + assert result is not None, "User not found!" + assert result.name == user.name, "Username is not correct!" time.sleep(3) log = client.fs.read(client.sssd.logs.domain()) - assert "Got rootdse" in log - assert "Using value from [defaultNamingContext] as naming context" in log - assert f"Setting option [ldap_search_base] to [{base}]" in log + assert "Got rootdse" in log, "Unable to find rootDSE!" + assert "Using value from [defaultNamingContext] as naming context" in log, "Unable to find naming context!" + assert f"Setting option [ldap_search_base] to [{base}]" in log, "Unable to set ldap_search_base!" +@pytest.mark.importance("low") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.parametrize("user_search_base", ["dc=ldap,dc=test", "dc=shanks,dc=com"]) -def test_ldap__lookup_user_multiple_naming_contexts_and_no_search_base(client: Client, ldap: LDAP, user_search_base): +def test_ldap__lookup_and_authenticate_as_user_with_different_object_search_bases( + client: Client, ldap: LDAP, user_search_base +): """ - :title: Without ldapsearch base and multiple namingContexts + :title: Looking up and authenticating as a user when the default, user and group search bases are different :setup: - 1. With sssd config set enumerate = True. - 2. Set sssd config nss part with filter_groups and filter_users to root. - 3. Add test user with password and make sure it can authenticate. + 1. Create People OU + 2. Create user and put the user object into the new OU + 3. Configure "ldap_search_base", "ldap_user|group_search_base" and start SSSD :steps: - 1. Sssd with user_search_base "dc=ldap,dc=test" - 2. Sssd with user_search_base "dc=shanks,dc=com" - 3. With both the cases sssd authentication should work when we configure it with ldap_search_base, - ldap_user_search_base, ldap_group_search_base. + 1. Lookup and authenticate as user :expectedresults: - 1. Sssd should be configured user_search_base "dc=ldap,dc=test" - 2. Sssd should be configured user_search_base "dc=shanks,dc=com" - 3. User authentication should be success with both the cases. + 1. User lookup and authentication are successful :customerscenario: False """ @@ -497,19 +445,12 @@ user = ldap.user("puser1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") - client.sssd.dom("test")["enumerate"] = "true" client.sssd.dom("test")["ldap_search_base"] = user_search_base client.sssd.dom("test")["ldap_user_search_base"] = f"ou=People,{base}" client.sssd.dom("test")["ldap_group_search_base"] = f"ou=Groups,{base}" - client.sssd.config["nss"] = { - "filter_groups": "root", - "filter_users": "root", - } - client.sssd.stop() - client.sssd.clear() client.sssd.start() result = client.tools.getent.passwd(user.name) - assert result is not None - assert result.name == user.name - assert client.auth.ssh.password(user.name, "Secret123") + assert result is not None, "User is not found!" + assert result.name == user.name, "Username is not correct!" + assert client.auth.ssh.password(user.name, "Secret123"), "User login failed!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_logging.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_logging.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_logging.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_logging.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,7 @@ """ -Automation for default debug level +SSSD Logging Tests. + +client.sssd.start(debug_level=None), means no configuration. It is the same as if +the parameter is omitted from 'sssd.conf'. :requirement: SSSD - Default debug level @@ -14,16 +17,17 @@ +@pytest.mark.integration +@pytest.mark.importance("low") @pytest.mark.topology(KnownTopology.Client) -def test_logging__default_debug_level_check(client: Client): +def test_logging__default_settings_logs_debug_level(client: Client): """ - :title: Check default debug level when sssd started successfully + :title: Default settings writes the debug level to logs :setup: - 1. Clear logs and cache - 2. Start SSSD with default debug level + 1. Configure SSSD for local system authentication + 2. Clear logs and start SSSD with default debug level :steps: 1. Check log files :expectedresults: - 1. "Starting with debug level = 0x0070" is in each file and - if log contains more than one line, log message with number "0x3f7c0" is stored + 1. Logs messages contain default debug level 0x0070 :customerscenario: False """ @@ -31,108 +35,85 @@ client.sssd.default_domain = "local" - client.sssd.clear(db=True, memcache=True, logs=True, config=False) + client.sssd.clear(logs=True) client.sssd.start(debug_level=None) for file in [client.sssd.logs.monitor, client.sssd.logs.domain(), client.sssd.logs.nss, client.sssd.logs.pam]: log_str = client.fs.read(file) - assert "Starting with debug level = 0x0070" in log_str, f"Log file has wrong format: {log_str}" - - if len(log_str.split("\n")) > 1: - assert "(0x3f7c0)" in log_str, f"Log file has wrong format: {log_str}" + assert "level = 0x0070" in log_str, "Logs should contain debug_level = 0x0070!" +@pytest.mark.integration +@pytest.mark.importance("low") @pytest.mark.topology(KnownTopology.Client) -def test_logging__default_debug_level_check_with_login(client: Client): +def test_logging__default_settings_does_not_log_user_logins(client: Client): """ - :title: Successful login with default debug level doesn't generate any logs + :title: Default debug level does not log user logins :setup: - 1. Add local user, set its password - 2. Add fallback_homedir (generates extra logs on user auth if not specified) - 3. Clear cache and logs + 1. Create user + 2. Configure SSSD for local system authentication + 3. Clear cache and logs and start SSSD with default debug level :steps: - 1. Start SSSD with default debug level - 2. Authenticate with user - 3. Check that logs were not generated + 1. Store current logs and authenticate as a local user. + 2. Compare stored logs with the current ones. :expectedresults: - 1. SSSD started successfully - 2. User is authenticated - 3. Diff of copy and logs is empty + 1. Login was successful + 2. Before event did not generate any new logs lines :customerscenario: False """ - client.local.user("user1").add(password="Secret123") + client.local.user("user1").add() client.sssd.common.local() client.sssd.default_domain = "local" client.sssd.domain["fallback_homedir"] = "/home/%%u" - client.sssd.clear(db=True, memcache=True, logs=True, config=False) + client.sssd.clear(logs=True, config=False) client.sssd.start(debug_level=None) client.fs.copy("/var/log/sssd", "/tmp/copy") - assert client.auth.ssh.password("user1", "Secret123"), "Authentication failed" - assert not client.host.ssh.run("diff /var/log/sssd /tmp/copy").stdout, "Debug messages were generated" - - -@pytest.mark.ticket(bz=1893159) -@pytest.mark.topology(KnownTopology.Client) -def test_logging__default_debug_level_fatal_and_critical_failures(client: Client): - """ - :title: Check that messages with levels 0 and 1 are logged for fatal or critical failures - :setup: - 1. Start SSSD with default debug level (config file is created) - 2. Restrict sssd.conf permissions - :steps: - 1. Restart sssd and check exit code - :expectedresults: - 1. SSSD failed to start with expected error code - :customerscenario: True - """ - client.sssd.common.local() - client.sssd.default_domain = "local" - client.sssd.start(debug_level=None) - client.fs.chmod(mode="444", path="/etc/sssd/sssd.conf") - - assert ( - client.sssd.restart(debug_level=None, raise_on_error=False, apply_config=False).rc == 3 - ), "SSSD didn't fail to read config, which is not expected" + assert client.auth.ssh.password("user1", "Secret123"), "Login failed!" + assert not client.host.conn.run("diff /var/log/sssd /tmp/copy").stdout, "Debug messages were generated!" +@pytest.mark.integration +@pytest.mark.importance("low") @pytest.mark.ticket(bz=1893159) @pytest.mark.topology(KnownTopology.Client) -def test_logging__default_debug_level_cannot_load_sssd_config(client: Client): +def test_logging__default_settings_logs_domain_configuration_errors(client: Client): """ - :title: Check that messages with level 2 are logged when SSSD can't load config + :title: Default debug_level logs domain configuration errors :setup: - 1. Set 'domains' to 'non_existing_domain' in sssd section + 1. Configure SSSD with an invalid domain :steps: - 1. Try to start SSSD with default debug level + 1. Start SSSD with default debug level 2. Check logs :expectedresults: 1. SSSD failed to start - 2. Correct error message is in log file + 2. Logs contain error message :customerscenario: True """ client.sssd.sssd["domains"] = "non_existing_domain" - assert ( - client.sssd.start(debug_level=None, raise_on_error=False).rc != 0 - ), "SSSD started successfully, which is not expected" - assert "id_provider is not set for domain [non_existing_domain]" in client.fs.read(client.sssd.logs.monitor) + assert client.sssd.start(debug_level=None, raise_on_error=False).rc != 0, "SSSD erroneously started!" + assert "No properly configured domains, fatal error!" in client.fs.read( + client.sssd.logs.monitor + ), "Domain is configured!" +@pytest.mark.integration +@pytest.mark.importance("low") @pytest.mark.ticket(bz=1893159) @pytest.mark.topology(KnownTopology.LDAP) -def test_logging__default_debug_level_nonexisting_ldap_server(client: Client): +def test_logging__default_settings_logs_offline_errors(client: Client): """ - :title: Check that messages with level 2 are logged when LDAP server doesn't exist + :title: Default debug_level logs offline errors :setup: - 1. Set ldap_uri to a non-existing ldap-server - 2. Start sssd with default debug level - 3. Enable ifp responder + 1. Configure SSSD with an invalid uri and enable ifp responder + 2. Start SSSD with default debug level + 3. Enable infopipe responder :steps: 1. Check logs 2. Check default domain status :expectedresults: - 1. Domain logs should contain a log related to 'going offline' - 2. LDAP is not connected + 1. Logs contain connection errors + 2. SSSD is not connected :customerscenario: True """ @@ -142,56 +123,36 @@ logs = client.fs.read(client.sssd.logs.domain()) - assert "Failed to connect, going offline" in logs, "String was not found in the logs" - - assert client.sssd.default_domain, "default_domain is None" - res = client.sssctl.domain_status(client.sssd.default_domain) - assert "LDAP: not connected" in res.stdout - - -@pytest.mark.ticket(bz=1915319) -@pytest.mark.topology(KnownTopology.Client) -def test_logging__default_debug_level_sbus(client: Client): - """ - :title: SBUS doesn't trigger failure message at modules startup - :setup: - 1. Start sssd with default debug level - :steps: - 1. Check logs - :expectedresults: - 1. "Unable to remove key" is not in the logs - :customerscenario: True - """ - client.sssd.common.local() - client.sssd.default_domain = "local" - client.sssd.start(debug_level=None) + assert "Failed to connect, going offline" in logs, "Offline error messages are not in logs!" - for file in [client.sssd.logs.monitor, client.sssd.logs.domain(), client.sssd.logs.nss, client.sssd.logs.pam]: - assert "Unable to remove key" not in client.fs.read(file), f"'Unable to remove key' was found in file: {file}" + assert client.sssd.default_domain is not None, "Failed to load default domain!" + result = client.sssctl.domain_status(client.sssd.default_domain) + assert result is not None + assert "LDAP: not connected" in result.stdout, "LDAP is connected!" +@pytest.mark.integration +@pytest.mark.importance("low") @pytest.mark.ticket(bz=1416150) @pytest.mark.topology(KnownTopology.LDAP) -def test_logging__log_to_syslog_when_backend_goes_offline(client: Client): +def test_logging__default_settings_logs_to_syslog_when_ldap_is_offline(client: Client): """ - :title: Log to syslog when sssd cannot contact servers goes offline + :title: Log to syslog when sssd cannot contact ldap servers and the servers go offline :setup: - 1. Set an invalid hostname uri and disable the offset to refresh sudo rules - 2. Start SSSD + 1. Configure SSSD with an invalid uri and start SSSD :steps: - 1. Check domain status for default domain - 2. Clear journal and restart SSSD - 3. Check journalctl + 1. Check domain status using sssctl + 2. Clear syslog and restart SSSD and check syslog :expectedresults: 1. Domain is offline - 2. Succeed - 3. "Backend is offline" found + 2. Logs contain SSSD errors :customerscenario: True """ client.sssd.domain["ldap_uri"] = "ldaps://typo.invalid" - client.sssd.domain["ldap_sudo_random_offset"] = "0" client.sssd.start() - assert client.sssd.default_domain is not None, "Failed to load default domain" + + assert client.sssd.default_domain is not None, "Failed to load default domain!" status = client.sssctl.domain_status(client.sssd.default_domain) - assert "Offline" in status.stdout or "Unable to get online status" in status.stderr, "Domain is not offline" + assert status is not None + assert "Offline" in status.stdout or "Unable to get online status" in status.stderr, "Domain is not offline!" client.journald.clear() @@ -200,3 +161,3 @@ log = client.journald.journalctl(grep="Backend is offline", unit="sssd") - assert log.rc == 0, "'Backend is offline' is not logged" + assert log.rc == 0, "Offline error messages are not in logs!" Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_memcache.py Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests: test_memory_cache.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_passkey.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_passkey.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_passkey.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_passkey.py 2024-10-01 18:30:01.000000000 +0000 @@ -4,9 +4,64 @@ :requirement: passkey +Passkeys allow users to authenticate without having to enter a username or password, +or provide any additional authentication factor. +This technology aims to replace legacy authentication mechanisms such as passwords. + +The objective is to use a passkey to locally authenticate a user against centralized identity management system. +For that purpose an integration with a server like AD/Samba or IPA or LDAP is needed. + The passkey solution only enables to authenticate in a system where the -FIDO2 key is connected physically.This could be su login, the GUI, -or even ssh@localhost. +FIDO2 key is connected physically.This could be su login, the GDM login. +The passkey is another way to authenticate as the user, using a physical token. + +We can't support remote authentication (ssh) because there isn't any way of doing the remote authentication +when the key is attached to your laptop. Here, passkey support is tested with su, tests are running with umockdev, not with a physical key. + +We are creating the recording files and reusing them in test without having passkey connected to host. +To create the recording files we have to connect passkey and need biometric +authentication such as pin and finger touch. + +we use sssctl tool to create the passkey-mapping. +# sssctl passkey-register --username= --domain= +Next, it will ask for PIN and generate the passkey-mapping and token. + +.. code-block:: + mapping = client.sssctl.passkey_register( + username="user1", + domain="ldap.test", + pin=123456, + device=f"{moduledatadir}/umockdev.device", + ioctl=f"{moduledatadir}/umockdev.ioctl", + script=f"{testdatadir}/umockdev.script", + ) + +Once we add user along with passkey-mapping, we can test/assert the passkey authentication. +While authenticating we need to username, pin of passkey and some recording files which will use for authenticating +the user. + +.. code-block:: + assert client.auth.su.passkey( + username="user1", + pin=123456, + device=f"{moduledatadir}/umockdev.device", + ioctl=f"{moduledatadir}/umockdev.ioctl", + script=f"{testdatadir}/umockdev.script.{suffix}", + ) + +For IPA tests where we need to test commands after authentication of user, we the use following code. +Here, we have an extra argument as a command to test in session after authentication of user. +It returns returncode either 0 or 1 and output to fetch the console messages. + +.. code-block:: + rc, _, output, _ = client.auth.su.passkey_with_output( + username="user1", + pin=123456, + device=f"{moduledatadir}/umockdev.device", + ioctl=f"{moduledatadir}/umockdev.ioctl", + script=f"{testdatadir}/umockdev.script.ipa", + command="klist", + ) """ @@ -23,11 +78,4 @@ -def passkey_requires_root(client: Client) -> tuple[bool, str] | bool: - if client.svc.get_property("sssd", "User") != "root": - return False, "Passkey tests don't work if SSSD runs under non-root" - - return True - - @mh_fixture() def umockdev_ipaotpd_update(ipa: IPA, request: pytest.FixtureRequest): @@ -104,5 +152,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user(client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str): """ @@ -124,5 +171,5 @@ provider.user("user1").add().passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert client.auth.su.passkey( @@ -138,5 +185,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_with_failed_pin( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -160,5 +206,5 @@ provider.user("user1").add().passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert not client.auth.su.passkey( @@ -174,5 +220,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_with_incorrect_mapping( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -198,5 +243,5 @@ provider.user("user1").add().passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert not client.auth.su.passkey( @@ -212,5 +257,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_when_server_is_not_resolvable( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -246,5 +290,5 @@ provider.user("user1").add().passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") # First time check authentication to cache the user @@ -274,5 +318,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_when_offline( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -302,5 +345,5 @@ client.sssd.domain["local_auth_policy"] = "only" - client.sssd.start() + client.sssd.start(service_user="root") # First time check authentication to cache the user @@ -369,5 +412,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_with_multiple_keys( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -394,5 +436,5 @@ user_add.passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert client.auth.su.passkey( @@ -408,5 +450,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_same_key_for_other_users( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -427,5 +468,5 @@ client.sssd.domain["local_auth_policy"] = "only" - client.sssd.start() + client.sssd.start(service_user="root") for user in ["user1", "user2", "user3"]: @@ -484,5 +525,4 @@ @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_user_when_add_with_ssh_key_and_mapping( client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str @@ -510,5 +550,5 @@ user_add.passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert client.auth.su.passkey( @@ -527,5 +567,4 @@ @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.builtwith(client="passkey", provider="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_fips_fido_key(client: Client, provider: GenericProvider, moduledatadir: str, testdatadir: str): """ @@ -550,5 +589,5 @@ provider.user("user1").add().passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") assert client.auth.su.passkey( @@ -564,5 +603,4 @@ @pytest.mark.topology(KnownTopology.IPA) @pytest.mark.builtwith(client="passkey", ipa="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__check_tgt(client: Client, ipa: IPA, moduledatadir: str, testdatadir: str, umockdev_ipaotpd_update): """ @@ -582,5 +620,5 @@ ipa.user("user1").add(user_auth_type="passkey").passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") rc, _, output, _ = client.auth.su.passkey_with_output( @@ -600,5 +638,4 @@ @pytest.mark.topology(KnownTopology.IPA) @pytest.mark.builtwith(client="passkey", ipa="passkey") -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__ipa_server_offline( client: Client, ipa: IPA, moduledatadir: str, testdatadir: str, umockdev_ipaotpd_update @@ -624,5 +661,5 @@ ipa.user("user1").add(user_auth_type="passkey").passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") rc, _, output, _ = client.auth.su.passkey_with_output( @@ -660,5 +697,4 @@ @pytest.mark.builtwith(client="passkey", ipa="passkey") @pytest.mark.ticket(gh=6931) -@pytest.mark.require.with_args(passkey_requires_root) def test_passkey__su_with_12_mappings( client: Client, ipa: IPA, moduledatadir: str, testdatadir: str, umockdev_ipaotpd_update @@ -685,5 +721,5 @@ user_add.passkey_add(f.read().strip()) - client.sssd.start() + client.sssd.start(service_user="root") rc, _, output, _ = client.auth.su.passkey_with_output( diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_proxy.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_proxy.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_proxy.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_proxy.py 2024-10-01 18:30:01.000000000 +0000 @@ -13,43 +13,50 @@ +@pytest.mark.importance("low") +@pytest.mark.topology(KnownTopology.LDAP) +def test_proxy__lookup_and_authenticate_user_using_pam_ldap_and_nslcd(client: Client, ldap: LDAP): + """ + :title: Lookup and authenticate user using PAM LDAP and NSLCD. + :setup: + 1. Setup SSSD to use PAM LDAP and NSLCD. + 2. Create OU, and create a user in the new OU. + :steps: + 1. Lookup user. + 2. Login in as user. + :expectedresults: + 1. User found. + 2. User logged in. + :customerscenario: True + """ + client.sssd.common.proxy("ldap", ["id", "auth", "chpass"], server_hostname=ldap.host.hostname) + client.sssd.svc.restart("nslcd") + client.sssd.restart() + ou_users = ldap.ou("users").add() + user = ldap.user("user-1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") + + assert client.tools.id(user.name) is not None, "User not found!" + assert client.auth.ssh.password(user.name, password="Secret123"), "User login failed!" + + +@pytest.mark.importance("low") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.ticket(bz=895570) -def test_proxy__nslcd_fast_alias_set_to_true_with_no_ldb_modify_errors(client: Client, ldap: LDAP): +def test_proxy__lookup_user_using_pam_ldap_and_nslcd_with_proxy_fast_alias_enabled(client: Client, ldap: LDAP): """ - :title: Enabling proxy_fast_alias should not show "ldb_modify failed: [Invalid attribute syntax]" for id lookups. + :title: Lookup user using PAM LDAP and NSLCD with proxy_fast_alias enabled. + :description: This bugzilla was created to squash 'ldb_modify failed' message when proxy_fast_alias is enabled. :setup: - 1. Setup sssd for proxy provider. - 2. Enable proxy_fast_alias. - 3. Setup nslcd services. - 4. Add OU and User. + 1. Setup SSSD to use PAM LDAP and NSLCD and set "proxy_fast_alias = true". + 2. Create OU, and create a user in the new OU. :steps: - 1. id lookup a user. - 2. Check logs for "ldb_modify failed". + 1. Lookup user. + 2. Check logs for ldb_modify errors. :expectedresults: - 1. id look up should success. - 2. Errors should not be seen on enabling proxy_fast_alias. + 1. User found. + 2. No error messages in log. :customerscenario: True """ - client.sssd.config["domain/test"] = { - "id_provider": "proxy", - "debug_level": "0xFFF0", - "proxy_lib_name": "ldap", - "proxy_pam_target": "sssdproxyldap", - "proxy_fast_alias": "true", - } - client.fs.write( - "/etc/pam.d/sssdproxyldap", - """ - auth required pam_ldap.so - account required pam_ldap.so - password required pam_ldap.so - session required pam_ldap.so - """, - ) - client.fs.write( - "/etc/nslcd.conf", - f"uid nslcd\ngid ldap\nuri " f"ldap://{ldap.host.hostname}\nbase " f"{ldap.ldap.naming_context}\n", - dedent=False, - ) + client.sssd.common.proxy("ldap", ["id", "auth", "chpass"], server_hostname=ldap.host.hostname) + client.sssd.domain["proxy_fast_alias"] = "True" client.sssd.svc.restart("nslcd") client.sssd.restart() @@ -57,8 +64,6 @@ user = ldap.user("user-1", basedn=ou_users).add(uid=10001, gid=10001, password="Secret123") - result = client.tools.id(user.name) - assert result is not None - assert result.user.name == user.name + assert client.tools.id(user.name) is not None, "User not found!" log = client.fs.read(client.sssd.logs.domain()) - assert "ldb_modify failed: [Invalid attribute syntax]" not in log + assert "ldb_modify failed: [Invalid attribute syntax]" not in log, "'ldb_modify failed' message found in logs!" diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_schema.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_schema.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_schema.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_schema.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,9 @@ """ -schema tests. +SSSD Schema Tests. + +Tests related to directory schemas, formal definitions of LDAP objectClasses and attributes. + +These tests are generic topology and will run against AD, Samba, IPA and LDAP. +Specific topologies test may reside in their corresponding test file. :requirement: ldap_extra_attrs @@ -10,29 +15,26 @@ from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.generic import GenericProvider -from sssd_test_framework.roles.ldap import LDAP -from sssd_test_framework.topology import KnownTopology, KnownTopologyGroup +from sssd_test_framework.topology import KnownTopologyGroup @pytest.mark.importance("high") -@pytest.mark.schema @pytest.mark.ticket(gh=4153, bz=1362023) @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.parametrize("attrs", ["mail, firstname:givenname, lastname:sn", "given_email:mail"]) -def test_schema__ldap_extra_attrs_filled(client: Client, provider: GenericProvider, attrs: str): +def test_schema__user_extra_attributes_are_populated(client: Client, provider: GenericProvider, attrs: str): """ - :title: SSSD starts correctly when ldap_user_extra_attrs is filled + :title: SSSD starts correctly when ldap_extra_attrs is configured :setup: - 1. Create new user "tuser" - 2. Add "given_email:mail" to ldap_user_extra_attrs + 1. Create user "user1" + 2. Configure SSSD with "ldap_user_extra_attrs = attribute:value" :steps: 1. Start SSSD - 2. Run "getent passwd tuser" + 2. Lookup user :expectedresults: - 1. SSSD starts successfully - 2. "tuser" is present in the passwd db + 1. SSSD starts with no errors + 2. User found and name matches :customerscenario: False - """ - provider.user("tuser").add() + provider.user("user1").add() client.sssd.domain["ldap_user_extra_attrs"] = attrs @@ -42,145 +44,5 @@ pytest.fail(f"Exception shouldn't be raised but we got {type(e)}: str(e)") - result = client.tools.getent.passwd("tuser") - assert result is not None - assert result.name == "tuser" - - -@pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_schema__ldap_extra_attrs_check_ldb(client: Client, provider: GenericProvider): - """ - :title: Recently added extra attributes should be in cache db along with their value - :setup: - 1. Create new user "user1" - 2. Add "description:gecos, userID:uidNumber, shell:loginShell, groupID:gidNumber" to ldap_user_extra_attrs - 3. Add "ldap_id_mapping" to domain config, to ensure correct ids on all topologies - 4. Start SSSD - :steps: - 1. Run "getent passwd user1" to store user attributes to cache - 2. Run ldbsearch command - :expectedresults: - 1. User is found - 2. Result has correct values - :customerscenario: True - """ - provider.user("user1").add(gid=111111, uid=100110, gecos="gecos user1", shell="/bin/sh", home="/home/user1") - client.sssd.domain["ldap_user_extra_attrs"] = ( - "description:gecos, userID:uidNumber, shell:loginShell, groupID:gidNumber" - ) - client.sssd.domain["ldap_id_mapping"] = "false" - client.sssd.start() - - result = client.tools.getent.passwd("user1") - assert result is not None, "getent passwd user1 failed" - - search = client.ldb.search( - f"/var/lib/sss/db/cache_{client.sssd.default_domain}.ldb", f"cn=users,cn={client.sssd.default_domain},cn=sysdb" - ) - - user_dict = search["name=user1@test,cn=users,cn=test,cn=sysdb"] - assert user_dict["description"] == ["gecos user1"], "attribute 'description' was not correct" - assert user_dict["shell"] == ["/bin/sh"], "attribute 'shell' was not correct" - assert user_dict["userID"] == ["100110"], "attribute 'userID' was not correct" - assert user_dict["groupID"] == ["111111"], "attribute 'groupID' was not correct" - - -@pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_schema__ldap_extra_attrs_negative_cache(client: Client, provider: GenericProvider): - """ - :title: When extra attribute of user is added but not assigned, it is neither cached nor displayed - :setup: - 1. Create new user "user1" - 2. Add "number:telephonenumber" to ldap_user_extra_attrs - 3. Start SSSD - :steps: - 1. Run "getent passwd user1" to store user to cache - 2. Run ldbsearch command - :expectedresults: - 1. User is found - 2. "number" is not in the output - :customerscenario: False - """ - provider.user("user1").add() - - client.sssd.domain["ldap_user_extra_attrs"] = "number:telephonenumber" - - client.sssd.start() - - result = client.tools.getent.passwd("user1") - assert result is not None, "User is not found" - assert result.name == "user1", "User has wrong name" - - search = client.ldb.search( - f"/var/lib/sss/db/cache_{client.sssd.default_domain}.ldb", f"cn=users,cn={client.sssd.default_domain},cn=sysdb" - ) - - user_dict = search["name=user1@test,cn=users,cn=test,cn=sysdb"] - with pytest.raises(KeyError): - user_dict["number"] - - -@pytest.mark.topology(KnownTopology.LDAP) -def test_schema__ldap_extra_attrs_extra_email(client: Client, ldap: LDAP): - """ - :title: SSSD starts with ldap_user_email and ldap_user_extra_attrs and checks cached attributes - :setup: - 1. Create new user "user1", set them mail and gecos - 2. Edit config - ldap_user_extra_attrs = "email:mail, description:gecos" and ldap_user_email = "mail" - 3. Start SSSD - :steps: - 1. Run "getent passwd user1" to store user to cache - 2. Run ldbsearch command to get cached info - :expectedresults: - 1. User is found - 2. "mail" and "email" are in the output with correct value - :customerscenario: False - """ - ldap.user("user1").add(gecos="gecos1", mail="user1@example.test") - - client.sssd.domain["ldap_user_email"] = "mail" - client.sssd.domain["ldap_user_extra_attrs"] = "email:mail, description:gecos" - client.sssd.sssd["services"] = "nss, pam, ifp" - client.sssd.start() - result = client.tools.getent.passwd("user1") - assert result is not None, "User is not found" - assert result.name == "user1", "User has wrong name" - - search = client.ldb.search( - f"/var/lib/sss/db/cache_{client.sssd.default_domain}.ldb", f"cn=users,cn={client.sssd.default_domain},cn=sysdb" - ) - - user_dict = search["name=user1@test,cn=users,cn=test,cn=sysdb"] - assert user_dict["description"] == ["gecos1"], "attribute 'descripion' was not correct" - assert user_dict["mail"] == ["user1@example.test"], "attribute 'mail' was not correct" - assert user_dict["email"] == ["user1@example.test"], "attribute 'email' was not correct" - - -@pytest.mark.ticket(bz=1667252) -@pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_schema__ldap_extra_attrs_ifp(client: Client, provider: GenericProvider): - """ - :title: ifp do not crash when requesting extra attributes - :setup: - 1. Create new user "user1" - 2. Configure 'test' ldap user extra attribute - 3. Start SSSD - :steps: - 1. Run "sssctl user-checks user1" - 2. Check SSSD status - :expectedresults: - 1. Command succeeded - 2. Checked successfully - :customerscenario: True - """ - provider.user("user1").add() - client.sssd.sssd["services"] = "nss, pam, ifp" - client.sssd.domain["ldap_user_extra_attrs"] = "test:homeDirectory" - client.sssd.ifp["user_attributes"] = "+test" - client.sssd.start() - - result = client.sssctl.user_checks("user1") - assert result.rc == 0, "sssctl user-checks command failed" - - result = client.sssd.svc.status("sssd") - assert result.rc == 0, "service status sssd failed" + assert result is not None, "User not found!" + assert result.name == "user1", f"User 'user1' name is not the expected value `{result.name}`!" Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests: test_sss_cache.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sss_override.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sss_override.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sss_override.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sss_override.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,2 +1,10 @@ +""" +Local Override "sss_override" Tests. + +Note: IPA does not support this feature because, it manages user and group overrides using ID views on the IPA master. + +:requirement: IDM-SSSD-TC: ldap_provider: local_overrides +""" + from __future__ import annotations @@ -7,5 +15,5 @@ -@pytest.mark.importance("high") +@pytest.mark.importance("medium") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.topology(KnownTopology.AD) @@ -15,22 +23,17 @@ :title: Locally overriding the name and POSIX attributes of a user :setup: - 1. Create POSIX user "user1" with standard POSIX attributes defined - 2. Start SSSD + 1. Create POSIX user "user1" + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD + 3. Create local override for "user1" + 4. Restart SSSD, this is necessary to enable local overrides :steps: - 1. Create local override for "user1" and name it "o-user1" - 2. Restart SSSD, this is necessary to enable local overrides - 3. Authenticate as "user1", the short and fully qualified name - 4. Authenticate as "o-user1", the short and fully qualified name - 5. Query the user "user1" and then override the POSIX attributes - 6. Query the username "user1", and local override name, "o-user1" + 1. Authenticate as "user1", then as the override name, use the short and fully qualified name + 2. Lookup user by the overridden name, check the uid and gid + 3. Override user's uid, gid and homedir and lookup user by both names, check the uid and gid :expectedresults: - 1. Local override is created for "user1" - 2. SSSD has restarted successfully - 3. Authentication successful for both short and fully qualified name - 4. Authentication successful for both short and fully qualified name - 5. POSIX attributes for local override has been changed - 6. The name and overriden name is found and POSIX attributes are updated + 1. Users logins are successful + 2. User is found and uid and gid match original values + 3. User is found using both names and uid, gid and homedir match the new values :customerscenario: False - :requirement: IDM-SSSD-TC: ldap_provider: local_overrides: simple user override """ provider.user("user1").add( @@ -45,31 +48,35 @@ client.sssd.restart() - assert client.auth.ssh.password("user1", "Secret123") - assert client.auth.ssh.password(f"user1@{client.sssd.default_domain}", "Secret123") - assert client.auth.ssh.password("o-user1", "Secret123") - assert client.auth.ssh.password(f"o-user1@{client.sssd.default_domain}", "Secret123") + assert client.auth.ssh.password("user1", "Secret123"), "Failed login!" + assert client.auth.ssh.password( + f"user1@{client.sssd.default_domain}", "Secret123" + ), "Fully qualified name failed login!" + + assert client.auth.ssh.password("o-user1", "Secret123"), "Override name failed login!" + assert client.auth.ssh.password( + f"o-user1@{client.sssd.default_domain}", "Secret123" + ), "Override fully qualified name failed login!" result = client.tools.getent.passwd("o-user1") - - assert result is not None - assert result.uid == 999011 - assert result.gid == 999011 + assert result is not None, "User not found by override name!" + assert result.uid == 999011, "User's uid does not match original value!" + assert result.gid == 999011, "User's gid does not match original value!" client.sss_override.user("user1").add(name="o-user1", uid=999999, gid=888888, home="/home/o-user1") result = client.tools.getent.passwd("user1") - assert result is not None - assert result.uid == 999999 - assert result.gid == 888888 - assert result.home == "/home/o-user1" + assert result is not None, "User not found!" + assert result.uid == 999999, "User's uid does not match override value!" + assert result.gid == 888888, "User's gid does not match override value!" + assert result.home == "/home/o-user1", "User's homedir does not match override value!" result = client.tools.getent.passwd("o-user1") - assert result is not None - assert result.uid == 999999 - assert result.gid == 888888 - assert result.home == "/home/o-user1" + assert result is not None, "User not found by override name!" + assert result.uid == 999999, "Local override uid does not match override value!" + assert result.gid == 888888, "Local override gid does not match override value!" + assert result.home == "/home/o-user1", "User's override name homedir does not match override value!" -@pytest.mark.importance("high") +@pytest.mark.importance("medium") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.topology(KnownTopology.AD) @@ -79,20 +86,15 @@ :title: Locally overriding the name and GID of a group :setup: - 1. Create group "group1" with posix attributes defined - 2. Start SSSD + 1. Create POSIX group "group1" + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD + 3. Create local override for "group1" + 4. Restart SSSD, this is necessary to enable local overrides :steps: - 1. Create local override "group1" and name it "o-group1" - 2. Restart SSSD, this is necessary to enable local overrides - 3. Query groups by the local override name - 4. Override the GID for the group "group1" - 5. Query groups by the override name + 1. Lookup group name and overridden name and check gid + 2. Override group gid to a new value, lookup group name by both names and check gid :expectedresults: - 1. Group local override is created - 2. SSSD has restarted successfully - 3. Group is found by the overriden name "o-group1" - 4. Local override POSIX attribute updated - 5. Group is found by the overriden name "o-group1" and GID changed + 1. Groups are found and gid match original values + 2. Groups are found and gid matches new overridden value :customerscenario: False - :requirement: IDM-SSSD-TC: ldap_provider: local_overrides: simple group override """ provider.group("group1").add(gid=999999) @@ -107,15 +109,22 @@ result = client.tools.getent.group("group1") - assert result is not None - assert result.gid == 999999 - assert client.tools.getent.group("o-group1") + assert result is not None, "Group not found!" + assert result.gid == 999999, "Group gid does not match original value!" + result = client.tools.getent.group("o-group1") + assert result is not None, "Group not found by override name!" + assert result.gid == 999999, "Local override gid does match original value! " group.add(name="o-group1", gid=888888) - assert client.tools.getent.group("group1") - assert client.tools.getent.group("o-group1") + result = client.tools.getent.group("group1") + assert result is not None, "Group not found!" + assert result.gid == 888888, "Group gid does not match override value!" + result = client.tools.getent.group("o-group1") + assert result is not None, "Group not found by override name!" + assert result.gid == 888888, "Local override gid does not match override value!" -@pytest.mark.importance("high") + +@pytest.mark.importance("medium") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.topology(KnownTopology.AD) @@ -125,25 +134,22 @@ :title: Root user UID/GID cannot be overridden :setup: - 1. Create POSIX user "user1" with standard POSIX attributes defined - 2. Start SSSD + 1. Create POSIX user "user1" and "root" + 2. Configure SSSD with "use_fully_qualified_names = false" and start SSSD + 3. Create local override for "user1" and name it "root" root, set the uid/gid to '0' + 4. Restart SSSD, this is necessary to enable local overrides :steps: - 1. Create local override "root" for user1 and set UID/GID to 0 - 2. Restart SSSD, this is necessary to enable local overrides - 3. Query the root user - 4. Query the root user and use sss as the service - 5. Query the POSIX user that is overridden to the root user + 1. Lookup the root user and check his uid and gid + 2. Lookup the root user and use the sss service + 3. Lookup user and check his uid and gid :expectedresults: - 1. Local override is created - 2. SSSD has restarted successfully - 3. The root user UID/GID has not been modified - 4. The override has no UID/GID attribute - 5. The POSIX user UID/GID has not been changed + 1. The root user uid and gid has not been modified + 2. root user is not found + 3. User found and uid and gid is not roots :customerscenario: False - :requirement: IDM-SSSD-TC: ldap_provider: local_overrides: root user override """ - provider.user("user1").add( - uid=999011, gid=999011, home="/home/user1", gecos="user", shell="/bin/bash", password="Secret123" - ) + provider.user("user1").add(uid=999011, gid=999011) + provider.user("root").add(uid=999012, gid=999012) client.sssd.domain["ldap_id_mapping"] = "False" + client.sssd.domain["use_fully_qualified_names"] = "False" client.sssd.start() @@ -153,16 +159,18 @@ result = client.tools.getent.passwd("root") - assert result is not None - assert result.uid == 0 - assert result.gid == 0 + assert result is not None, "root user not found!" + assert result.uid == 0, "root uid is not 0" + assert result.gid == 0, "root gid is not 0" - result = client.tools.getent.passwd("root", service="sss") - assert result is None + # Root should be filtered out from any service other than files + assert client.tools.getent.passwd("root", service="sss") is None, "root user is found!" result = client.tools.getent.passwd("user1") - assert result is not None + assert result is not None, "user1 not found!" + assert result.uid != 0, "User uid is 0!" + assert result.gid != 0, "User gid is 0!" -@pytest.mark.importance("high") +@pytest.mark.importance("medium") @pytest.mark.topology(KnownTopology.LDAP) @pytest.mark.topology(KnownTopology.AD) @@ -179,9 +187,7 @@ 3. Override group "group1" to "o-group1" 4. Export user and group local overrides data to a file - 5. Delete overrides - 6. Restart SSSD - 7. Import user and group local overrides data - 8. Restart SSSD - 9. Search for user and group local overrides + 5. Delete overrides and restart SSSD + 6. Import user and group local overrides data and restart SSSD + 7. Search for user and group local overrides :expectedresults: 1. User local override has been created @@ -189,9 +195,7 @@ 3. Group local override has been created 4. Local overrides user and group data is exported to a file - 5. Local overrides are deleted - 6. SSSD has restarted successfully - 7. User and group local override data has been imported from the export - 8. SSSD has restarted successfully - 9. User and group local overrides are found + 5. SSSD is restarted and overrides data is gone + 6. User and group local override data has been imported from the export + 7. User and group local overrides is found :customerscenario: False :requirement: IDM-SSSD-TC: ldap_provider: local_overrides: import export user override @@ -219,4 +223,16 @@ assert not client.sss_override.user("user1").get() assert not client.sss_override.group("group1").get() + + assert ( + len( + client.ldb.search( + f"/var/lib/sss/db/cache_{client.sssd.default_domain}.ldb", + f"cn={client.sssd.default_domain},cn=sysdb", + filter="objectClass=userOverride", + ).items() + ) + < 1 + ), "Override is not empty!" + client.sss_override.import_data() client.sssd.restart() @@ -226,5 +242,5 @@ -@pytest.mark.importance("high") +@pytest.mark.importance("medium") @pytest.mark.ticket(bz=1254184) @pytest.mark.topology(KnownTopology.LDAP) @@ -235,24 +251,18 @@ :title: Overriding user when use_fully_qualified_names is true :setup: - 1. Create posix user "user1" with posix attributes defined + 1. Create user "user1" 2. Edit SSSD configuration and set "use_fully_qualified_names" = True 3. Start SSSD + 4. Create override for "user1" + 5. Restart SSSD, this is necessary to enable local overrides :steps: - 1. Override "user1" to "o-user1" - 2. Restart SSSD, this is necessary to enable local overrides - 3. Authenticate as "user1", only the fully qualified name - 4. Authenticate as "o-user1", only the fully qualified name + 1. Login with the username and overridden name + 2. Login with the fully qualified username and overridden name :expectedresults: - 1. User local override is created - 2. SSSD has restarted successfully - 3. Authentication successful - 4. Authentication successful + 1. Logins fail + 2. Login succeed :customerscenario: False - :requirement: IDM-SSSD-TC: ldap_provider: local_overrides: regression 2757 override - :bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1254184 """ - provider.user("user1").add( - uid=999011, gid=999011, home="/home/user1", gecos="user", shell="/bin/bash", password="Secret123" - ) + provider.user("user1").add() client.sssd.domain["use_fully_qualified_names"] = "True" client.sssd.start() @@ -262,6 +272,6 @@ client.sssd.restart() - assert client.auth.ssh.password("user1", "Secret123") is False - assert client.auth.ssh.password("o-user1", "Secret123") is False - assert client.auth.ssh.password(f"user1@{client.sssd.default_domain}", "Secret123") - assert client.auth.ssh.password(f"o-user1@{client.sssd.default_domain}", "Secret123") + assert not client.auth.ssh.password("user1", "Secret123"), "User logged in!" + assert not client.auth.ssh.password("o-user1", "Secret123"), "User logged in!" + assert client.auth.ssh.password(f"user1@{client.sssd.default_domain}", "Secret123"), "Login failed!" + assert client.auth.ssh.password(f"o-user1@{client.sssd.default_domain}", "Secret123"), "Login failed!" Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests: test_sss_ssh_knownhosts.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sssctl.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sssctl.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sssctl.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sssctl.py 2024-10-01 18:30:01.000000000 +0000 @@ -11,5 +11,6 @@ import pytest -from pytest_mh.ssh import SSHAuthenticationError, SSHProcessError +from pytest_mh.conn import ProcessError +from pytest_mh.conn.ssh import SSHAuthenticationError from sssd_test_framework.roles.client import Client from sssd_test_framework.roles.ldap import LDAP @@ -42,5 +43,5 @@ # Check the error message in output of # sssctl config-check - output = client.host.ssh.run("sssctl config-check", raise_on_error=False) + output = client.host.conn.run("sssctl config-check", raise_on_error=False) assert "[rule/sssd_checks]: Attribute 'id_provider' is missing in section 'domain/test'." in output.stdout_lines[1] @@ -72,5 +73,5 @@ # Check the return code of # sssctl config-check command - output = client.host.ssh.run("sssctl config-check", raise_on_error=False) + output = client.host.conn.run("sssctl config-check", raise_on_error=False) assert ( "[rule/sssd_checks]: Attribute 'id_provider' in section 'domain/test' has an invalid value: invalid" @@ -235,5 +236,5 @@ client.sssd.dom("")["debug_level"] = "9" - with pytest.raises(SSHProcessError) as ex: + with pytest.raises(ProcessError) as ex: client.sssd.start(raise_on_error=True, check_config=True) diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sudo.py /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sudo.py --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests/test_sudo.py 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests/test_sudo.py 2024-10-01 18:30:01.000000000 +0000 @@ -1,4 +1,4 @@ """ -SUDO responder tests. +SUDO Responder Tests. :requirement: sudo @@ -21,5 +21,4 @@ @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) @@ -53,17 +52,15 @@ provider.sudorule("test").add(user=u, host="ALL", command="/bin/ls") - client.sssd.set_service_user(sssd_service_user) client.sssd.common.sudo() - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]) - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root") + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]), "Sudo list failed!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" - assert not client.auth.sudo.list("user-2", "Secret123") - assert not client.auth.sudo.run("user-2", "Secret123", command="/bin/ls /root") + assert not client.auth.sudo.list("user-2", "Secret123"), "Sudo list successful!" + assert not client.auth.sudo.run("user-2", "Secret123", command="/bin/ls /root"), "Sudo command successful!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopology.AD) @pytest.mark.topology(KnownTopology.LDAP) @@ -104,18 +101,17 @@ # Try several users to make sure we don't mangle the list for user in ["user-1", "user-2", "user-3"]: - assert client.auth.sudo.list(user, "Secret123", expected=["(root) /bin/ls"]) - assert client.auth.sudo.run(user, "Secret123", command="/bin/ls /root") + assert client.auth.sudo.list(user, "Secret123", expected=["(root) /bin/ls"]), "Sudo list failed!" + assert client.auth.sudo.run(user, "Secret123", command="/bin/ls /root"), "sudo command failed!" - assert not client.auth.sudo.list("user-4", "Secret123") - assert not client.auth.sudo.run("user-4", "Secret123", command="/bin/ls /root") + assert not client.auth.sudo.list("user-4", "Secret123"), "Sudo list successful!" + assert not client.auth.sudo.run("user-4", "Secret123", command="/bin/ls /root"), "Sudo command successful!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.ticket(bz=1380436, gh=4236) @pytest.mark.topology(KnownTopologyGroup.AnyProvider) def test_sudo__case_sensitive_false(client: Client, provider: GenericProvider): """ - :title: Sudo rules work correctly for case insensitive domains + :title: Sudo rules work correctly for case-insensitive domains :setup: 1. Create user "USER-1" @@ -150,15 +146,18 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/less", "(root) /bin/more"]) - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/less /root/test") - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/more /root/test") - - assert client.auth.sudo.list("USER-1", "Secret123", expected=["(root) /bin/less", "(root) /bin/more"]) - assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/less /root/test") - assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/more /root/test") + assert client.auth.sudo.list( + "user-1", "Secret123", expected=["(root) /bin/less", "(root) /bin/more"] + ), "Sudo list failed!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/less /root/test"), "Sudo command failed!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/more /root/test"), "Sudo command failed!" + + assert client.auth.sudo.list( + "USER-1", "Secret123", expected=["(root) /bin/less", "(root) /bin/more"] + ), "Sudo list failed!" + assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/less /root/test"), "Sudo command failed!" + assert client.auth.sudo.run("USER-1", "Secret123", command="/bin/more /root/test"), "Sudo command failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @pytest.mark.parametrize("sssd_service_user", ("root", "sssd")) @@ -185,5 +184,5 @@ 2. Rule was modified 3. Time passed - 4. User is bale to run only /bin/less + 4. User is able to run only /bin/less :customerscenario: False """ @@ -191,21 +190,19 @@ r = provider.sudorule("test").add(user=u, host="ALL", command="/bin/ls") - client.sssd.set_service_user(sssd_service_user) client.sssd.common.sudo() client.sssd.domain["entry_cache_sudo_timeout"] = "2" - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]) + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]), "Sudo list failed!" r.modify(command="/bin/less") time.sleep(3) - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/less"]) + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/less"]), "Sudo command failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.ticket(bz=1372440, gh=4236) @pytest.mark.contains_workaround_for(gh=4483) @pytest.mark.topology(KnownTopologyGroup.AnyProvider) -def test_sudo__sudo_user_is_group(client: Client, provider: GenericProvider): +def test_sudo__user_is_group(client: Client, provider: GenericProvider): """ :title: POSIX groups can be set in sudoUser attribute @@ -236,13 +233,12 @@ client.tools.id("user-1") - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]) - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root") + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]), "Sudo list failed!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.ticket(bz=1826272, gh=5119) @pytest.mark.topology(KnownTopologyGroup.AnyAD) -def test_sudo__sudo_user_is_nonposix_group(client: Client, provider: GenericADProvider): +def test_sudo__user_is_nonposix_group(client: Client, provider: GenericADProvider): """ :title: Non-POSIX groups can be set in sudoUser attribute @@ -270,10 +266,9 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]) - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root") + assert client.auth.sudo.list("user-1", "Secret123", expected=["(root) /bin/ls"]), "Sudo list failed!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.ticket(bz=1910131) @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @@ -300,9 +295,8 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", "Secret123", expected=["(user-2) /bin/ls"]) + assert client.auth.sudo.list("user-1", "Secret123", expected=["(user-2) /bin/ls"]), "Sudo list failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopology.AD) @pytest.mark.topology(KnownTopology.LDAP) @@ -334,16 +328,13 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", "Secret123", expected=["(user-2) /bin/ls"]) + assert client.auth.sudo.list("user-1", "Secret123", expected=["(user-2) /bin/ls"]), "Sudo list failed!" @pytest.mark.importance("low") -@pytest.mark.authorization @pytest.mark.topology(KnownTopology.LDAP) def test_sudo__sudonotbefore_shorttime(client: Client, provider: LDAP): """ - Test that suduNotBefore and sudoNotAfter works even without minutes and - seconds specifier. - :title: sudoNotBefore and sudoNotAfter do not require minutes and seconds + :description: Test that sudoNotBefore and sudoNotAfter works even without minutes and seconds specifier. :setup: 1. Create user "user-1" @@ -359,5 +350,5 @@ Note: IPA does not support these attributes and AD/Samba time schema - requires minutes and seconds to be set. Therefore this test only applies to + requires minutes and seconds to be set. Therefor this test only applies to LDAP. """ @@ -390,9 +381,13 @@ "Secret123", expected=[f"(root) NOTBEFORE={fulltime(notbefore)} NOTAFTER={fulltime(notafter)} /bin/ls"], - ) + ), "Sudo list failed!" +# This test is testing randomized values, therefore it is possible that +# the same refresh interval is generated multiple times (i.e. full refresh +# is always 4 seconds) and therefore the test fails. However, we want to check +# that random values are assigned so we must repeat the test in this case. +@pytest.mark.flaky(max_runs=5) @pytest.mark.importance("low") -@pytest.mark.authorization @pytest.mark.slow(seconds=15) @pytest.mark.ticket(bz=1925514, gh=5609) @@ -419,10 +414,16 @@ ldap_sudo_random_offset="5", ) + + # Start SSSD and wait for few sudo updates to occur client.sssd.start() time.sleep(15) + + # Stop SSSD to ensure that all logs are written + client.sssd.stop() + log = client.fs.read(client.sssd.logs.domain()) smart = set() full = set() - for m in re.findall(r"Task \[SUDO (Smart|Full).*\]: scheduling task (\d+) seconds", log): + for m in re.findall(r"Task \[SUDO (Smart|Full) Refresh\]: scheduling task (\d+) seconds", log): match m[0]: case "Smart": @@ -431,10 +432,9 @@ full.add(m[1]) - assert len(smart) > 1 - assert len(full) > 1 + assert len(smart) > 1, "Smart refresh scheduling tasks is > 1!" + assert len(full) > 1, "Full refresh scheduling tasks is > 1!" @pytest.mark.importance("low") -@pytest.mark.authorization @pytest.mark.slow(seconds=10) @pytest.mark.ticket(bz=1925505, gh=5604) @@ -496,5 +496,5 @@ if is_task_end("SUDO Smart Refresh", line): - assert not expect_skip or is_skipped + assert not expect_skip or is_skipped, "Sudo refresh was not skipped!" is_skipped = False expect_skip = False @@ -505,5 +505,4 @@ @pytest.mark.importance("high") -@pytest.mark.authorization @pytest.mark.ticket(bz=1294670, gh=3969) @pytest.mark.topology(KnownTopologyGroup.AnyProvider) @@ -540,10 +539,9 @@ client.fs.write("/etc/sudoers.d/test", "user-1 ALL=(ALL) NOPASSWD:ALL") - client.sssd.set_service_user(sssd_service_user) client.sssd.common.sudo() client.sssd.nss.update( entry_negative_timeout="0", # disable standard negative cache to make sure we hit the local user case ) - client.sssd.start() + client.sssd.start(service_user=sssd_service_user) # Now there should be no query @@ -556,13 +554,12 @@ result = client.tools.tshark(["-r", "/tmp/sssd.pcap", "-V", "-2", "-R", "ldap.filter"]) - assert "uid=user-1" not in result.stdout + assert "uid=user-1" not in result.stdout, "Packets sent when resolving user!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopologyGroup.AnyProvider) def test_sudo__defaults_set_no_auth_and_sudorule_has_auth_undefined(client: Client, provider: GenericProvider): """ - :title: defaults sudo entry set !authentication and a sudo rule with undefined authentication + :title: Defaults sudo entry set !authentication and a sudo rule with undefined authentication :setup: 1. Create user "user-1" @@ -587,14 +584,13 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", expected=["(root) ALL"]) - assert client.auth.sudo.run("user-1", command="/bin/ls /root") + assert client.auth.sudo.list("user-1", expected=["(root) ALL"]), "Sudo list failed!" + assert client.auth.sudo.run("user-1", command="/bin/ls /root"), "Sudo command failed!" @pytest.mark.importance("critical") -@pytest.mark.authorization @pytest.mark.topology(KnownTopologyGroup.AnyProvider) def test_sudo__defaults_set_no_auth_and_sudo_rule_has_mandatory_auth(client: Client, provider: GenericProvider): """ - :title: defaults sudo entry set !authentication and a sudorule has mandatory authentication + :title: Defaults sudo entry set !authentication and a sudorule has mandatory authentication :setup: 1. Create user "user-1" @@ -619,5 +615,5 @@ client.sssd.start() - assert client.auth.sudo.list("user-1", expected=["(root) PASSWD: ALL"]) - assert not client.auth.sudo.run("user-1", command="/bin/ls /root") - assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root") + assert client.auth.sudo.list("user-1", expected=["(root) PASSWD: ALL"]), "Sudo list failed!" + assert not client.auth.sudo.run("user-1", command="/bin/ls /root"), "Sudo command successful!" + assert client.auth.sudo.run("user-1", "Secret123", command="/bin/ls /root"), "Sudo command failed!" Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/system/tests: test_tools.py Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/system/tests: test_trusts.py diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/test_CA/SSSD_test_cert_0005.config /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/test_CA/SSSD_test_cert_0005.config --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/test_CA/SSSD_test_cert_0005.config 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/test_CA/SSSD_test_cert_0005.config 2024-10-01 18:30:01.000000000 +0000 @@ -19,3 +19,3 @@ extendedKeyUsage = clientAuth subjectAltName = email:sssd-devel@lists.fedorahosted.org,URI:https://github.com/SSSD/sssd// -authorityInfoAccess = OCSP;URI:http://ocsp.my.server.test/ +authorityInfoAccess = OCSP;URI:http://ocsp.my.server.invalid/ diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/test_ssh_client.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/test_ssh_client.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tests/test_ssh_client.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tests/test_ssh_client.c 2024-10-01 18:30:01.000000000 +0000 @@ -44,4 +44,5 @@ char buf[5]; /* Ridiculously small buffer by design */ ssize_t len; + int return_code = 0; /* Set debug level to invalid value so we can decide if -d 0 was used. */ @@ -56,5 +57,6 @@ poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); - return 3; + return_code = 3; + goto end; } } @@ -63,9 +65,8 @@ if (pc_user == NULL) { fprintf(stderr, "No user specified\n"); - return 3; + return_code = 3; + goto end; } - poptFreeContext(pc); - DEBUG_CLI_INIT(debug_level); @@ -76,5 +77,6 @@ "Could not stat %s [%d]: %s\n", SSH_AK_CLIENT_PATH, ret, strerror(ret)); - return 3; + return_code = 3; + goto end; } @@ -82,5 +84,6 @@ if (ret != 0) { perror("pipe"); - return 3; + return_code = 3; + goto end; } @@ -91,5 +94,6 @@ close(p[1]); DEBUG(SSSDBG_CRIT_FAILURE, "fork failed: %d\n", ret); - return 3; + return_code = 3; + goto end; case 0: /* child */ @@ -102,9 +106,11 @@ if (ret == -1) { perror("dup2"); - return 3; + return_code = 3; + goto end; } execv(av[0], av); - return 3; + return_code = 3; + goto end; default: /* parent */ @@ -117,5 +123,6 @@ if (len == -1) { perror("waitpid"); - return 3; + return_code = 3; + goto end; } @@ -123,16 +130,22 @@ if (pid == -1) { perror("waitpid"); - return 3; + return_code = 3; + goto end; } if (WIFEXITED(status)) { printf("sss_ssh_authorizedkeys exited with return code %d\n", WEXITSTATUS(status)); - return 0; + return_code = 0; + goto end; } else if (WIFSIGNALED(status)) { printf("sss_ssh_authorizedkeys exited with signal %d\n", WTERMSIG(status)); - return 1; + return_code = 1; + goto end; } printf("sss_ssh_authorizedkeys exited for another reason\n"); - return 2; + return_code = 2; +end: + poptFreeContext(pc); + return return_code; } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/common/sss_tools.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/common/sss_tools.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/common/sss_tools.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/common/sss_tools.c 2024-10-01 18:30:01.000000000 +0000 @@ -88,17 +88,10 @@ } -static errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, - struct confdb_ctx **_confdb) +errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, struct confdb_ctx **_confdb) { - struct confdb_ctx *confdb; - char *path; + static const char *path = DB_PATH"/"CONFDB_FILE; errno_t ret; struct stat statbuf; - path = talloc_asprintf(mem_ctx, "%s/%s", DB_PATH, CONFDB_FILE); - if (path == NULL) { - return ENOMEM; - } - ret = stat(path, &statbuf); if (ret != 0) { @@ -109,6 +102,5 @@ } - ret = confdb_init(mem_ctx, &confdb, path); - talloc_zfree(path); + ret = confdb_init(mem_ctx, _confdb, path); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to connect to config DB [%d]: %s\n", @@ -117,8 +109,4 @@ } - if (_confdb != NULL) { - *_confdb = confdb; - } - return EOK; } @@ -208,14 +196,4 @@ } -static bool sss_tools_handles_init_error(struct sss_route_cmd *command, - errno_t init_err) -{ - if (init_err == EOK) { - return true; - } - - return command->handles_init_err == init_err; -} - static size_t sss_tool_max_length(struct sss_route_cmd *commands) { @@ -318,6 +296,5 @@ static errno_t sss_tool_route(int argc, const char **argv, struct sss_tool_ctx *tool_ctx, - struct sss_route_cmd *commands, - void *pvt) + struct sss_route_cmd *commands) { struct sss_cmdline cmdline; @@ -350,8 +327,7 @@ if (!tool_ctx->print_help) { ret = tool_cmd_init(tool_ctx, &commands[i]); - - if (!sss_tools_handles_init_error(&commands[i], ret)) { + if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, - "Command %s does not handle initialization error [%d] %s\n", + "Initialization of command %s failed [%d] %s\n", cmdline.command, ret, sss_strerror(ret)); return ret; @@ -359,5 +335,5 @@ } - return commands[i].fn(&cmdline, tool_ctx, pvt); + return commands[i].fn(&cmdline, tool_ctx); } } @@ -539,6 +515,5 @@ int sss_tool_main(int argc, const char **argv, - struct sss_route_cmd *commands, - void *pvt) + struct sss_route_cmd *commands) { struct sss_tool_ctx *tool_ctx; @@ -551,5 +526,5 @@ } - ret = sss_tool_route(argc, argv, tool_ctx, commands, pvt); + ret = sss_tool_route(argc, argv, tool_ctx, commands); SYSDB_VERSION_ERROR(ret); talloc_free(tool_ctx); @@ -600,24 +575,2 @@ return ret; } - -errno_t sss_tool_connect_to_confdb(TALLOC_CTX *ctx, struct confdb_ctx **cdb_ctx) -{ - int ret; - char *confdb_path = NULL; - - confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); - if (confdb_path == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not allocate memory for confdb path\n"); - return ENOMEM; - } - - ret = confdb_init(ctx, cdb_ctx, confdb_path); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not initialize connection to the confdb\n"); - } - - talloc_free(confdb_path); - return ret; -} diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/common/sss_tools.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/common/sss_tools.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/common/sss_tools.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/common/sss_tools.h 2024-10-01 18:30:01.000000000 +0000 @@ -44,14 +44,13 @@ typedef errno_t (*sss_route_fn)(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); -#define SSS_TOOL_COMMAND_FLAGS(cmd, msg, err, fn, flags) \ - {cmd, _(msg), err, fn, flags} -#define SSS_TOOL_COMMAND(cmd, msg, err, fn) \ - {cmd, _(msg), err, fn, 0} -#define SSS_TOOL_COMMAND_NOMSG(cmd, err, fn) {cmd, NULL, err, fn, 0} -#define SSS_TOOL_DELIMITER(message) {"", _(message), 0, NULL, 0} -#define SSS_TOOL_LAST {NULL, NULL, 0, NULL, 0} +#define SSS_TOOL_COMMAND_FLAGS(cmd, msg, fn, flags) \ + {cmd, _(msg), fn, flags} +#define SSS_TOOL_COMMAND(cmd, msg, fn) \ + {cmd, _(msg), fn, 0} +#define SSS_TOOL_COMMAND_NOMSG(cmd, fn) {cmd, NULL, fn, 0} +#define SSS_TOOL_DELIMITER(message) {"", _(message), NULL, 0} +#define SSS_TOOL_LAST {NULL, NULL, NULL, 0} #define SSS_TOOL_FLAG_SKIP_CMD_INIT 0x01 @@ -61,5 +60,4 @@ const char *command; const char *description; - errno_t handles_init_err; sss_route_fn fn; int flags; @@ -92,6 +90,5 @@ int sss_tool_main(int argc, const char **argv, - struct sss_route_cmd *commands, - void *pvt); + struct sss_route_cmd *commands); errno_t sss_tool_parse_name(TALLOC_CTX *mem_ctx, @@ -102,5 +99,5 @@ -errno_t sss_tool_connect_to_confdb(TALLOC_CTX *ctx, struct confdb_ctx **cdb_ctx); +errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, struct confdb_ctx **_confdb); #endif /* SRC_TOOLS_COMMON_SSS_TOOLS_H_ */ diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_cache.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_cache.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_cache.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_cache.c 2024-10-01 18:30:01.000000000 +0000 @@ -28,4 +28,5 @@ #include "util/util.h" #include "tools/tools_util.h" +#include "tools/common/sss_tools.h" #include "db/sysdb.h" #include "db/sysdb_services.h" @@ -148,21 +149,4 @@ struct sss_domain_info *dinfo; - /* If systemd is in offline mode, - * there's not going to be a sssd instance - * running. This occurs for both e.g. yum --installroot - * as well as rpm-ostree offline updates. - * - * So let's just quickly do nothing. (Though note today - * yum --installroot doesn't set this variable, rpm-ostree - * does) - * - * For more information on the variable, see: - * https://github.com/systemd/systemd/pull/7631 - */ - const char *systemd_offline = getenv ("SYSTEMD_OFFLINE"); - if (systemd_offline && strcmp (systemd_offline, "1") == 0) { - return 0; - } - ret = init_context(argc, argv, &tctx); if (ret == ERR_NO_DOMAIN_ENABLED) { @@ -662,20 +646,11 @@ const char *domain) { - char *confdb_path; int ret; struct sss_domain_info *dinfo; - confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); - if (confdb_path == NULL) { - return ENOMEM; - } - - /* Connect to the conf db */ - ret = confdb_init(ctx, &ctx->confdb, confdb_path); - talloc_free(confdb_path); + ret = sss_tool_confdb_init(ctx, &ctx->confdb); if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not initialize connection to the confdb\n"); - return ret; + ERROR("Can't find configuration db, was SSSD configured and run?\n"); + return ERR_NO_DOMAIN_ENABLED; } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_override.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_override.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_override.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_override.c 2024-10-01 18:30:01.000000000 +0000 @@ -1411,6 +1411,5 @@ static int override_user_add(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct override_user user = {NULL}; @@ -1442,6 +1441,5 @@ static int override_user_del(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct override_user user = {NULL}; @@ -1474,6 +1472,5 @@ static int override_user_find(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sss_domain_info *dom; @@ -1504,6 +1501,5 @@ static int override_user_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx; @@ -1575,6 +1571,5 @@ static int override_user_import(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx; @@ -1658,6 +1653,5 @@ static int override_user_export(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { const char *filename = NULL; @@ -1685,6 +1679,5 @@ static int override_group_add(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct override_group group = {NULL}; @@ -1716,6 +1709,5 @@ static int override_group_del(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct override_group group = {NULL}; @@ -1749,6 +1741,5 @@ static int override_group_find(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sss_domain_info *dom; @@ -1779,6 +1770,5 @@ static int override_group_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx; @@ -1850,6 +1840,5 @@ static int override_group_import(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx; @@ -1928,6 +1917,5 @@ static int override_group_export(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { const char *filename = NULL; @@ -1957,19 +1945,19 @@ { struct sss_route_cmd commands[] = { - SSS_TOOL_COMMAND_NOMSG("user-add", 0, override_user_add), - SSS_TOOL_COMMAND_NOMSG("user-del", 0, override_user_del), - SSS_TOOL_COMMAND_NOMSG("user-find", 0, override_user_find), - SSS_TOOL_COMMAND_NOMSG("user-show", 0, override_user_show), - SSS_TOOL_COMMAND_NOMSG("user-import", 0, override_user_import), - SSS_TOOL_COMMAND_NOMSG("user-export", 0, override_user_export), - SSS_TOOL_COMMAND_NOMSG("group-add", 0, override_group_add), - SSS_TOOL_COMMAND_NOMSG("group-del", 0, override_group_del), - SSS_TOOL_COMMAND_NOMSG("group-find", 0, override_group_find), - SSS_TOOL_COMMAND_NOMSG("group-show", 0, override_group_show), - SSS_TOOL_COMMAND_NOMSG("group-import", 0, override_group_import), - SSS_TOOL_COMMAND_NOMSG("group-export", 0, override_group_export), + SSS_TOOL_COMMAND_NOMSG("user-add", override_user_add), + SSS_TOOL_COMMAND_NOMSG("user-del", override_user_del), + SSS_TOOL_COMMAND_NOMSG("user-find", override_user_find), + SSS_TOOL_COMMAND_NOMSG("user-show", override_user_show), + SSS_TOOL_COMMAND_NOMSG("user-import", override_user_import), + SSS_TOOL_COMMAND_NOMSG("user-export", override_user_export), + SSS_TOOL_COMMAND_NOMSG("group-add", override_group_add), + SSS_TOOL_COMMAND_NOMSG("group-del", override_group_del), + SSS_TOOL_COMMAND_NOMSG("group-find", override_group_find), + SSS_TOOL_COMMAND_NOMSG("group-show", override_group_show), + SSS_TOOL_COMMAND_NOMSG("group-import", override_group_import), + SSS_TOOL_COMMAND_NOMSG("group-export", override_group_export), SSS_TOOL_LAST }; - return sss_tool_main(argc, argv, commands, NULL); + return sss_tool_main(argc, argv, commands); } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_seed.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_seed.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sss_seed.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sss_seed.c 2024-10-01 18:30:01.000000000 +0000 @@ -34,4 +34,5 @@ #include "db/sysdb.h" #include "tools/tools_util.h" +#include "tools/common/sss_tools.h" #include "confdb/confdb.h" @@ -629,5 +630,4 @@ { TALLOC_CTX *tmp_ctx = NULL; - char *confdb_path = NULL; struct confdb_ctx *confdb = NULL; struct sss_domain_info *domain = NULL; @@ -640,12 +640,5 @@ } - /* setup confdb */ - confdb_path = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, CONFDB_FILE); - if (confdb_path == NULL) { - ret = ENOMEM; - goto done; - } - - ret = confdb_init(tmp_ctx, &confdb, confdb_path); + ret = sss_tool_confdb_init(tmp_ctx, &confdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.c 2024-10-01 18:30:01.000000000 +0000 @@ -100,18 +100,23 @@ errno_t sssctl_wrap_command(const char *command, const char *subcommand, - struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_cmdline *cmdline) { + TALLOC_CTX *tmp_ctx; errno_t ret; + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + if (subcommand != NULL) { cmdline->argc++; } - const char **args = talloc_array_size(tool_ctx, + const char **args = talloc_array_size(tmp_ctx, sizeof(char *), cmdline->argc + 2); if (!args) { + talloc_free(tmp_ctx); return ENOMEM; } @@ -130,5 +135,5 @@ ret = sssctl_run_command(args); - talloc_free(args); + talloc_free(tmp_ctx); return ret; @@ -316,41 +321,41 @@ struct sss_route_cmd commands[] = { SSS_TOOL_DELIMITER("SSSD Status:"), - SSS_TOOL_COMMAND("domain-list", "List available domains", 0, sssctl_domain_list), - SSS_TOOL_COMMAND("domain-status", "Print information about domain", 0, sssctl_domain_status), - SSS_TOOL_COMMAND_FLAGS("user-checks", "Print information about a user and check authentication", 0, sssctl_user_checks, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), - SSS_TOOL_COMMAND("access-report", "Generate access report for a domain", 0, sssctl_access_report), + SSS_TOOL_COMMAND("domain-list", "List available domains", sssctl_domain_list), + SSS_TOOL_COMMAND("domain-status", "Print information about domain", sssctl_domain_status), + SSS_TOOL_COMMAND_FLAGS("user-checks", "Print information about a user and check authentication", sssctl_user_checks, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND("access-report", "Generate access report for a domain", sssctl_access_report), SSS_TOOL_DELIMITER("Information about cached content:"), - SSS_TOOL_COMMAND("user-show", "Information about cached user", 0, sssctl_user_show), - SSS_TOOL_COMMAND("group-show", "Information about cached group", 0, sssctl_group_show), - SSS_TOOL_COMMAND("netgroup-show", "Information about cached netgroup", 0, sssctl_netgroup_show), + SSS_TOOL_COMMAND("user-show", "Information about cached user", sssctl_user_show), + SSS_TOOL_COMMAND("group-show", "Information about cached group", sssctl_group_show), + SSS_TOOL_COMMAND("netgroup-show", "Information about cached netgroup", sssctl_netgroup_show), SSS_TOOL_DELIMITER("Local data tools:"), - SSS_TOOL_COMMAND("client-data-backup", "Backup local data", 0, sssctl_client_data_backup), - SSS_TOOL_COMMAND("client-data-restore", "Restore local data from backup", 0, sssctl_client_data_restore), - SSS_TOOL_COMMAND("cache-remove", "Backup local data and remove cached content", 0, sssctl_cache_remove), - SSS_TOOL_COMMAND("cache-expire", "Invalidate cached objects", 0, sssctl_cache_expire), - SSS_TOOL_COMMAND("cache-index", "Manage cache indexes", 0, sssctl_cache_index), + SSS_TOOL_COMMAND_FLAGS("client-data-backup", "Backup local data", sssctl_client_data_backup, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND_FLAGS("client-data-restore", "Restore local data from backup", sssctl_client_data_restore, SSS_TOOL_FLAG_SKIP_CMD_INIT), + SSS_TOOL_COMMAND_FLAGS("cache-remove", "Backup local data and remove cached content", sssctl_cache_remove, SSS_TOOL_FLAG_SKIP_CMD_INIT), + SSS_TOOL_COMMAND_FLAGS("cache-expire", "Invalidate cached objects", sssctl_cache_expire, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND_FLAGS("cache-index", "Manage cache indexes", sssctl_cache_index, SSS_TOOL_FLAG_SKIP_CMD_INIT), SSS_TOOL_DELIMITER("Log files tools:"), - SSS_TOOL_COMMAND("logs-remove", "Remove existing SSSD log files", 0, sssctl_logs_remove), - SSS_TOOL_COMMAND("logs-fetch", "Archive SSSD log files in tarball", 0, sssctl_logs_fetch), - SSS_TOOL_COMMAND("debug-level", "Change or print information about SSSD debug level", 0, sssctl_debug_level), - SSS_TOOL_COMMAND_FLAGS("analyze", "Analyze logged data", 0, sssctl_analyze, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND_FLAGS("logs-remove", "Remove existing SSSD log files", sssctl_logs_remove, SSS_TOOL_FLAG_SKIP_CMD_INIT), + SSS_TOOL_COMMAND_FLAGS("logs-fetch", "Archive SSSD log files in tarball", sssctl_logs_fetch, SSS_TOOL_FLAG_SKIP_CMD_INIT), + SSS_TOOL_COMMAND("debug-level", "Change or print information about SSSD debug level", sssctl_debug_level), + SSS_TOOL_COMMAND_FLAGS("analyze", "Analyze logged data", sssctl_analyze, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), SSS_TOOL_DELIMITER("Configuration files tools:"), - SSS_TOOL_COMMAND_FLAGS("config-check", "Perform static analysis of SSSD configuration", 0, sssctl_config_check, SSS_TOOL_FLAG_SKIP_CMD_INIT), + SSS_TOOL_COMMAND_FLAGS("config-check", "Perform static analysis of SSSD configuration", sssctl_config_check, SSS_TOOL_FLAG_SKIP_CMD_INIT), SSS_TOOL_DELIMITER("Certificate related tools:"), - SSS_TOOL_COMMAND_FLAGS("cert-show", "Print information about the certificate", 0, sssctl_cert_show, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), - SSS_TOOL_COMMAND("cert-map", "Show users mapped to the certificate", 0, sssctl_cert_map), - SSS_TOOL_COMMAND_FLAGS("cert-eval-rule", "Check mapping and matching rule with a certificate", 0, sssctl_cert_eval_rule, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND_FLAGS("cert-show", "Print information about the certificate", sssctl_cert_show, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND("cert-map", "Show users mapped to the certificate", sssctl_cert_map), + SSS_TOOL_COMMAND_FLAGS("cert-eval-rule", "Check mapping and matching rule with a certificate", sssctl_cert_eval_rule, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), SSS_TOOL_DELIMITER("GPOs related tools:"), - SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", 0, sssctl_gpo_show), - SSS_TOOL_COMMAND("gpo-list", "Enumerate cached GPOs", 0, sssctl_gpo_list), - SSS_TOOL_COMMAND("gpo-remove", "Remove cached GPO", 0, sssctl_gpo_remove), - SSS_TOOL_COMMAND("gpo-purge", "Remove all cached GPOs", 0, sssctl_gpo_purge), + SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", sssctl_gpo_show), + SSS_TOOL_COMMAND("gpo-list", "Enumerate cached GPOs", sssctl_gpo_list), + SSS_TOOL_COMMAND("gpo-remove", "Remove cached GPO", sssctl_gpo_remove), + SSS_TOOL_COMMAND("gpo-purge", "Remove all cached GPOs", sssctl_gpo_purge), #ifdef BUILD_PASSKEY SSS_TOOL_DELIMITER("Passkey related tools:"), - SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", 0, sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), #endif SSS_TOOL_LAST }; - return sss_tool_main(argc, argv, commands, NULL); + return sss_tool_main(argc, argv, commands); } diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl.h 2024-10-01 18:30:01.000000000 +0000 @@ -50,7 +50,5 @@ errno_t sssctl_wrap_command(const char *command, const char *subcommand, - struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_cmdline *cmdline); errno_t sssctl_run_command(const char *const argv[]); /* argv[0] - command */ bool sssctl_start_sssd(bool force); @@ -63,103 +61,78 @@ errno_t sssctl_domain_list(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_domain_status(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_client_data_backup(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_client_data_restore(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_cache_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_cache_expire(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_cache_index(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_debug_level(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_analyze(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_user_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_group_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_netgroup_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_config_check(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_user_checks(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_access_report(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_cert_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_cert_map(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); #ifdef BUILD_PASSKEY errno_t sssctl_passkey_register(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); #endif /* BUILD_PASSKEY */ errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); errno_t sssctl_gpo_purge(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); + struct sss_tool_ctx *tool_ctx); #endif /* _SSSCTL_H_ */ diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_access_report.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_access_report.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_access_report.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_access_report.c 2024-10-01 18:30:01.000000000 +0000 @@ -384,6 +384,5 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { errno_t ret; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cache.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cache.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cache.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cache.c 2024-10-01 18:30:01.000000000 +0000 @@ -642,6 +642,5 @@ errno_t sssctl_user_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sssctl_cache_opts opts = {0}; @@ -690,6 +689,5 @@ errno_t sssctl_group_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sssctl_cache_opts opts = {0}; @@ -737,6 +735,5 @@ errno_t sssctl_netgroup_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sssctl_cache_opts opts = {0}; @@ -768,6 +765,5 @@ errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { struct sssctl_cache_opts opts = {0}; @@ -954,6 +950,5 @@ errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; @@ -1122,6 +1117,5 @@ errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; @@ -1234,6 +1228,5 @@ errno_t sssctl_gpo_purge(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cert.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cert.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cert.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_cert.c 2024-10-01 18:30:01.000000000 +0000 @@ -36,6 +36,5 @@ errno_t sssctl_cert_show(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; @@ -93,6 +92,5 @@ errno_t sssctl_cert_map(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; @@ -195,6 +193,5 @@ errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_config.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_config.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_config.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_config.c 2024-10-01 18:30:01.000000000 +0000 @@ -57,6 +57,5 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { errno_t ret; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_data.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_data.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_data.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_data.c 2024-10-01 18:30:01.000000000 +0000 @@ -126,6 +126,5 @@ errno_t sssctl_client_data_backup(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { struct sssctl_data_opts opts = {0}; @@ -169,5 +168,5 @@ } - if (sssctl_backup_file_exists(SSS_BACKUP_USER_OVERRIDES)) { + if (sssctl_backup_file_exists(SSS_BACKUP_GROUP_OVERRIDES)) { ret = sssctl_run_command((const char *[]){"sss_override", "group-import", SSS_BACKUP_GROUP_OVERRIDES, NULL}); @@ -186,6 +185,5 @@ errno_t sssctl_client_data_restore(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { struct sssctl_data_opts opts = {0}; @@ -209,6 +207,5 @@ errno_t sssctl_cache_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { struct sssctl_data_opts opts = {0}; @@ -261,6 +258,5 @@ errno_t sssctl_cache_expire(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { errno_t ret; @@ -282,6 +278,6 @@ } -errno_t get_confdb_domains(TALLOC_CTX *ctx, struct confdb_ctx *confdb, - char ***_domains) +static errno_t get_confdb_domains(TALLOC_CTX *ctx, struct confdb_ctx *confdb, + char ***_domains) { int ret; @@ -363,5 +359,5 @@ if (domains == NULL) { /* If the user selected no domain, act on all of them */ - ret = sss_tool_connect_to_confdb(tmp_ctx, &confdb); + ret = sss_tool_confdb_init(tmp_ctx, &confdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, @@ -418,6 +414,5 @@ errno_t sssctl_cache_index(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { const char *attr = NULL; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_domains.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_domains.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_domains.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_domains.c 2024-10-01 18:30:01.000000000 +0000 @@ -65,6 +65,5 @@ errno_t sssctl_domain_list(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx; @@ -311,6 +310,5 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { TALLOC_CTX *tmp_ctx = NULL; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_logs.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_logs.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_logs.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_logs.c 2024-10-01 18:30:01.000000000 +0000 @@ -38,5 +38,4 @@ #include "tools/common/sss_process.h" #include "tools/sssctl/sssctl.h" -#include "tools/tools_util.h" #include "confdb/confdb.h" #include "sss_iface/sss_iface_sync.h" @@ -420,6 +419,5 @@ errno_t sssctl_logs_remove(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { struct sssctl_logs_opts opts = {0}; @@ -473,6 +471,5 @@ errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { const char *file = NULL; @@ -514,6 +511,5 @@ errno_t sssctl_debug_level(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { int ret; @@ -557,6 +553,4 @@ } - CHECK_ROOT(ret, debug_prg_name); - if (debug_as_string != NULL) { debug_to_set = (uint32_t) parse_debug_level(debug_as_string); @@ -568,5 +562,5 @@ CHECK(targets == NULL, fini, "Could not allocate memory."); - ret = sss_tool_connect_to_confdb(ctx, &ctx->confdb); + ret = sss_tool_confdb_init(ctx, &ctx->confdb); CHECK(ret != EOK, fini, "Could not connect to configuration database."); @@ -594,6 +588,5 @@ errno_t sssctl_analyze(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { #ifndef BUILD_CHAIN_ID @@ -603,5 +596,5 @@ errno_t ret; - ret = sssctl_wrap_command(SSS_ANALYZE, NULL, cmdline, tool_ctx, pvt); + ret = sssctl_wrap_command(SSS_ANALYZE, NULL, cmdline); return ret; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_passkey.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_passkey.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_passkey.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_passkey.c 2024-10-01 18:30:01.000000000 +0000 @@ -32,10 +32,9 @@ errno_t sssctl_passkey_register(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *) { errno_t ret; - ret = sssctl_wrap_command(SSS_PASSKEY_CHILD, "--register", cmdline, tool_ctx, pvt); + ret = sssctl_wrap_command(SSS_PASSKEY_CHILD, "--register", cmdline); return ret; diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_user_checks.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_user_checks.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_user_checks.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/tools/sssctl/sssctl_user_checks.c 2024-10-01 18:30:01.000000000 +0000 @@ -217,6 +217,5 @@ errno_t sssctl_user_checks(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt) + struct sss_tool_ctx *tool_ctx) { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/cert/libcrypto/cert.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/cert/libcrypto/cert.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/cert/libcrypto/cert.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/cert/libcrypto/cert.c 2024-10-01 18:30:01.000000000 +0000 @@ -21,4 +21,5 @@ #include #include +#include #include "util/util.h" @@ -177,4 +178,92 @@ #define IDENTIFIER_NISTP521 "nistp521" +static int sss_ec_get_key(BN_CTX *bn_ctx, const EVP_PKEY *cert_pub_key, + EC_GROUP **_ec_group, EC_POINT **_ec_public_key) +{ + EC_GROUP *ec_group = NULL; + EC_POINT *ec_public_key = NULL; + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int ret; + static char curve_name[4096]; + static unsigned char pubkey[4096]; + size_t len; + + ret = EVP_PKEY_get_utf8_string_param(cert_pub_key, + OSSL_PKEY_PARAM_GROUP_NAME, + curve_name, sizeof(curve_name), NULL); + if (ret != 1) { + ret = EINVAL; + goto done; + } + + ec_group = EC_GROUP_new_by_curve_name(OBJ_sn2nid(curve_name)); + if (ec_group == NULL) { + ret = EINVAL; + goto done; + } + + ret = EVP_PKEY_get_octet_string_param(cert_pub_key, + OSSL_PKEY_PARAM_PUB_KEY, + pubkey, sizeof(pubkey), &len); + if (ret != 1) { + EC_GROUP_free(ec_group); + ret = EINVAL; + goto done; + } + + ec_public_key = EC_POINT_new(ec_group); + if (ec_public_key == NULL) { + EC_GROUP_free(ec_group); + ret = EINVAL; + goto done; + } + + ret = EC_POINT_oct2point(ec_group, ec_public_key, pubkey, len, bn_ctx); + if (ret != 1) { + EC_GROUP_free(ec_group); + EC_POINT_free(ec_public_key); + ret = EINVAL; + goto done; + } + +#else + EC_KEY *ec_key = NULL; + const EC_GROUP *gr; + const EC_POINT *pk; + + ec_key = EVP_PKEY_get0_EC_KEY(cert_pub_key); + if (ec_key == NULL) { + ret = ENOMEM; + goto done; + } + + gr = EC_KEY_get0_group(ec_key); + + pk = EC_KEY_get0_public_key(ec_key); + + ec_group = EC_GROUP_dup(gr); + if (*_ec_group == NULL) { + ret = ENOMEM; + goto done; + } + + ec_public_key = EC_POINT_dup(pk, gr); + if (ec_public_key == NULL) { + EC_GROUP_free(ec_group); + ret = ENOMEM; + goto done; + } +#endif + + *_ec_group = ec_group; + *_ec_public_key = ec_public_key; + + ret = EOK; + +done: + return ret; +} + static errno_t ec_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key, uint8_t **key_blob, size_t *key_size) @@ -184,7 +273,6 @@ uint8_t *buf = NULL; size_t buf_len; - EC_KEY *ec_key = NULL; - const EC_GROUP *ec_group = NULL; - const EC_POINT *ec_public_key = NULL; + EC_GROUP *ec_group = NULL; + EC_POINT *ec_public_key = NULL; BN_CTX *bn_ctx = NULL; int key_len; @@ -194,11 +282,16 @@ int header_len; - ec_key = EVP_PKEY_get1_EC_KEY(cert_pub_key); - if (ec_key == NULL) { + bn_ctx = BN_CTX_new(); + if (bn_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "BN_CTX_new failed.\n"); ret = ENOMEM; goto done; } - ec_group = EC_KEY_get0_group(ec_key); + ret = sss_ec_get_key(bn_ctx, cert_pub_key, &ec_group, &ec_public_key); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to get curve details.\n"); + goto done; + } switch(EC_GROUP_get_curve_name(ec_group)) { @@ -225,13 +318,4 @@ identifier_len = strlen(identifier); - ec_public_key = EC_KEY_get0_public_key(ec_key); - - bn_ctx = BN_CTX_new(); - if (bn_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "BN_CTX_new failed.\n"); - ret = ENOMEM; - goto done; - } - key_len = EC_POINT_point2oct(ec_group, ec_public_key, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx); @@ -280,5 +364,6 @@ BN_CTX_free(bn_ctx); - EC_KEY_free(ec_key); + EC_GROUP_free(ec_group); + EC_POINT_free(ec_public_key); return ret; @@ -289,4 +374,61 @@ #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) +static int sss_rsa_get_key(const EVP_PKEY *cert_pub_key, + BIGNUM **_n, BIGNUM **_e) +{ + int ret; + BIGNUM *n = NULL; + BIGNUM *e = NULL; +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + ret = EVP_PKEY_get_bn_param(cert_pub_key, OSSL_PKEY_PARAM_RSA_N, &n); + if (ret != 1) { + ret = EINVAL; + goto done; + } + + ret = EVP_PKEY_get_bn_param(cert_pub_key, OSSL_PKEY_PARAM_RSA_E, &e); + if (ret != 1) { + BN_clear_free(n); + ret = EINVAL; + goto done; + } + +#else + + const BIGNUM *tmp_n; + const BIGNUM *tmp_e: + const RSA *rsa_pub_key = NULL; + rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key); + if (rsa_pub_key == NULL) { + ret = ENOMEM; + goto done; + } + + RSA_get0_key(rsa_pub_key, tmp_n, tmp_e, NULL); + + *n = BN_dup(tmp_n); + if (*n == NULL) { + ret = ENOMEM; + goto done; + } + + *e = BN_dup(tmp_e); + if (*e == NULL) { + BN_clear_free(n); + ret = ENOME; + goto done; + } + +#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + + *_e = e; + *_n = n; + + ret = EOK; + +done: + return ret; +} + static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key, uint8_t **key_blob, size_t *key_size) @@ -296,6 +438,6 @@ size_t size; uint8_t *buf = NULL; - const BIGNUM *n; - const BIGNUM *e; + BIGNUM *n = NULL; + BIGNUM *e = NULL; int modulus_len; unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8]; @@ -303,17 +445,9 @@ unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8]; -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - const RSA *rsa_pub_key = NULL; - rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key); - if (rsa_pub_key == NULL) { - ret = ENOMEM; + ret = sss_rsa_get_key(cert_pub_key, &n, &e); + if (ret != EOK) { goto done; } - RSA_get0_key(rsa_pub_key, &n, &e, NULL); -#else - n = cert_pub_key->pkey.rsa->n; - e = cert_pub_key->pkey.rsa->e; -#endif modulus_len = BN_bn2bin(n, modulus); exponent_len = BN_bn2bin(e, exponent); @@ -359,4 +493,7 @@ done: + BN_clear_free(n); + BN_clear_free(e); + if (ret != EOK) { talloc_free(buf); diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/crypto/libcrypto/crypto_sha512crypt.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/crypto/libcrypto/crypto_sha512crypt.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/crypto/libcrypto/crypto_sha512crypt.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/crypto/libcrypto/crypto_sha512crypt.c 2024-10-01 18:30:01.000000000 +0000 @@ -30,6 +30,4 @@ #include -#include "sss_openssl.h" - /* Define our magic string to mark salt for SHA512 "encryption" replacement. */ Only in /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/crypto/libcrypto: sss_openssl.h diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/memory.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/memory.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/memory.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/memory.c 2024-10-01 18:30:01.000000000 +0000 @@ -24,22 +24,4 @@ -#ifdef HAVE_EXPLICIT_BZERO - -#include - -#else - -typedef void *(*_sss_memset_t)(void *, int, size_t); - -static volatile _sss_memset_t memset_func = memset; - -static void explicit_bzero(void *s, size_t n) -{ - memset_func(s, 0, n); -} - -#endif - - void sss_erase_krb5_data_securely(krb5_data *data) { @@ -73,13 +55,4 @@ } -void sss_erase_mem_securely(void *p, size_t size) -{ - if ((p == NULL) || (size == 0)) { - return; - } - - explicit_bzero(p, size); -} - struct mem_holder { Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util: memory_erase.c Only in /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util: memory_erase.h diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/sss_ssh.c /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/sss_ssh.c --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/sss_ssh.c 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/sss_ssh.c 2024-10-01 18:30:01.000000000 +0000 @@ -19,4 +19,7 @@ */ +#define _GNU_SOURCE + +#include #include @@ -26,4 +29,41 @@ #include "util/sss_ssh.h" + +/* Check if the key_line we received from the backend includes the hostname or + * it is just the keytype and the key. + * + * Key lines have this format: + * marker (optional), hostnames, keytype, base64-encoded key, comment (optional) + * + * This is a very simplistic method based on looking for the provided hostname + * into the provided keyline, at the right position (the hostname could also + * be present in the comment at the end). + */ +static bool +sss_ssh_key_has_host_name(const char *key_line, const char *hostname) +{ + const char *current = key_line; + const char *end; + + /* Skip spaces */ + while (*current == ' ') { + current++; + }; + if (*current == '@') { + /* If the optional marker is present, we assume the host name is present too */ + return true; + } + + /* We are supposed to be here at the beginning of the hostnames. Are we? + * Look for the next space, which is a separator. If the hostname list + * is present, it must happen before that space and include the expected + * hostname. + */ + end = strchrnul(current, ' '); + current = memmem(current, end - current, hostname, strlen(hostname)); + return (current != NULL); +} + + errno_t sss_ssh_make_ent(TALLOC_CTX *mem_ctx, @@ -219,6 +259,17 @@ } +/* + * Print the public key in the expected format. + * + * pubkey: The structure storing the public key. + * keyhost: The hostname that will be added in front of the textual key, + * if needed. + * needlehost: The hostname that will be looked for into the textual key to + * know whether the hostname is present. Ignored if keyhost is NULL; + * cannot be NULL otherwise. + */ errno_t -sss_ssh_print_pubkey(struct sss_ssh_pubkey *pubkey, const char *keyhost) +sss_ssh_print_pubkey(struct sss_ssh_pubkey *pubkey, const char *keyhost, + const char *needlehost) { TALLOC_CTX *tmp_ctx; @@ -241,6 +292,8 @@ } - /* OpenSSH expects a linebreak after each key */ - if (keyhost == NULL) { + /* Check if the host name part is included with the key. + * OpenSSH expects a linebreak after each key. */ + if (keyhost == NULL || needlehost == NULL + || sss_ssh_key_has_host_name(repr, needlehost)) { repr_break = talloc_asprintf(tmp_ctx, "%s\n", repr); } else { diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/sss_ssh.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/sss_ssh.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/sss_ssh.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/sss_ssh.h 2024-10-01 18:30:01.000000000 +0000 @@ -53,5 +53,6 @@ errno_t sss_ssh_print_pubkey(struct sss_ssh_pubkey *pubkey, - const char *keyhost); + const char *keyhost, + const char *needlehost); #endif /* _SSS_SSH_H_ */ diff -U2 -r /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/util.h /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/util.h --- /var/lib/copr-rpmbuild/results/sssd/upstream-unpacked/Source0/sssd-2.10.0-beta2/src/util/util.h 2024-06-26 09:11:39.000000000 +0000 +++ /var/lib/copr-rpmbuild/results/sssd/srpm-unpacked/sssd-2.10.0-beta2.tar.gz-extract/sssd-2.10.0-beta2/src/util/util.h 2024-10-01 18:30:01.000000000 +0000 @@ -50,4 +50,5 @@ #include "util/sss_regexp.h" #include "util/debug.h" +#include "util/memory_erase.h" /* name of the monitor server instance */ @@ -238,5 +239,4 @@ */ int sss_erase_talloc_mem_securely(void *p); -void sss_erase_mem_securely(void *p, size_t size); void sss_erase_krb5_data_securely(krb5_data *data); void sss_erase_krb5_creds_securely(krb5_creds *cred);