From 64d6d95e08a5966c8fe19eb7aad2b84cd75d34b6 Mon Sep 17 00:00:00 2001 From: "deepin-community-bot[bot]" <156989552+deepin-community-bot[bot]@users.noreply.github.com> Date: Mon, 3 Aug 2026 09:23:02 +0000 Subject: [PATCH] feat: update sudo to 1.9.16p2-3+deb13u2 --- debian/changelog | 21 +++-- ...roup-as-well-as-uid-when-running-th.patch} | 63 ++++++------- ...not-perform-path-expansion-on-files-.patch | 34 +++++++ debian/patches/amd64-ibt.diff | 28 ++++++ debian/patches/developer-mode-verify.patch | 87 ------------------ debian/patches/series | 5 +- debian/tests/01-getroot | 4 +- debian/tests/02-1003969-audit-no-resolve | 26 ++++-- debian/tests/03-1126085-sudoersd | 32 +++++++ .../03/10_dsa::util::sudo[dfsg-team-role] | 1 + debian/tests/03/root | 1 + .../10_dsa::util::sudo[dfsg-team-role] | 1 + debian/tests/03/sudoersd/root | 1 + debian/tests/04-getroot-sssd | 51 ++++++++-- debian/tests/04/ldif/ldap.conf | 2 +- debian/tests/04/ldif/slapd.conf | 22 +++++ debian/tests/04/ldif/sss-ous.ldif | 7 ++ debian/tests/04/ldif/sssd.conf | 2 +- debian/tests/04/ldif/tls.ldif | 26 +++++- debian/tests/control | 9 +- plugins/sudoers/po/zh_CN.mo | Bin 65160 -> 64973 bytes 21 files changed, 263 insertions(+), 160 deletions(-) rename debian/patches/{cve_2026_35535.patch => 0006-exec_mailer-Set-group-as-well-as-uid-when-running-th.patch} (67%) create mode 100644 debian/patches/0008-open_sudoers-Do-not-perform-path-expansion-on-files-.patch create mode 100644 debian/patches/amd64-ibt.diff delete mode 100644 debian/patches/developer-mode-verify.patch create mode 100755 debian/tests/03-1126085-sudoersd create mode 100644 debian/tests/03/10_dsa::util::sudo[dfsg-team-role] create mode 100644 debian/tests/03/root create mode 100644 debian/tests/03/sudoersd/10_dsa::util::sudo[dfsg-team-role] create mode 100644 debian/tests/03/sudoersd/root create mode 100644 debian/tests/04/ldif/slapd.conf diff --git a/debian/changelog b/debian/changelog index 43c8bc9..c92976b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,16 +1,21 @@ -sudo (1.9.16p2-3deepin2) unstable; urgency=medium +sudo (1.9.16p2-3+deb13u2) trixie; urgency=medium - * Fix CVE-2026-35535: exec_mailer: Set group as well as uid when - running the mailer. + * cherry-pick upstream exec_mailer-Set-group-as-well-as-uid. + This is upstream and fixes CVE-2026-35535: + https://github.com/sudo-project/sudo/commit/3e474c2 (Closes: #1130593) - -- deepin-ci-robot Mon, 13 Apr 2026 21:24:10 +0800 + -- Marc Haber Sat, 11 Apr 2026 14:21:02 +0200 -sudo (1.9.16p2-3deepin1) unstable; urgency=medium +sudo (1.9.16p2-3+deb13u1) trixie; urgency=medium - [ zhouzilong ] - * add develper mode verify message. + [ Marc Haber ] + * add upstream patch: Do not perform path expansion + Thanks to Adam D. Barratt" (Closes: #1126085) + * Enable Intel CET on amd64 only. + Thanks to Marcos Del Sol Vives (Closes: #1124339) + * Pull more robust test suite from unstable - -- Tianyu Chen Mon, 30 Jun 2025 23:01:07 +0800 + -- Marc Haber Wed, 11 Feb 2026 20:22:01 +0100 sudo (1.9.16p2-3) unstable; urgency=high diff --git a/debian/patches/cve_2026_35535.patch b/debian/patches/0006-exec_mailer-Set-group-as-well-as-uid-when-running-th.patch similarity index 67% rename from debian/patches/cve_2026_35535.patch rename to debian/patches/0006-exec_mailer-Set-group-as-well-as-uid-when-running-th.patch index 565d20b..7022a44 100644 --- a/debian/patches/cve_2026_35535.patch +++ b/debian/patches/0006-exec_mailer-Set-group-as-well-as-uid-when-running-th.patch @@ -1,10 +1,10 @@ -Description: exec_mailer: Set group as well as uid when running the mailer. - Also make a setuid(), setgid() or setgroups() failure fatal. -Author: Todd C. Miller -Origin: upstream -Bug: https://security-tracker.debian.org/tracker/CVE-2026-35535 -Forwarded: not-needed -Last-Update: 2026-04-13 +From: "Todd C. Miller" +Date: Sat, 8 Nov 2025 15:34:02 -0700 +Subject: exec_mailer: Set group as well as uid when running the mailer + +Also make a setuid(), setgid() or setgroups() failure fatal. + +Found by the ZeroPath AI Security Engineer --- include/sudo_eventlog.h | 3 ++- lib/eventlog/eventlog.c | 21 +++++++++++++++++---- @@ -12,10 +12,11 @@ Last-Update: 2026-04-13 plugins/sudoers/logging.c | 2 +- plugins/sudoers/policy.c | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) -Index: github-sudo-CVE-2026-35535/include/sudo_eventlog.h -=================================================================== ---- github-sudo-CVE-2026-35535.orig/include/sudo_eventlog.h -+++ github-sudo-CVE-2026-35535/include/sudo_eventlog.h + +diff --git a/include/sudo_eventlog.h b/include/sudo_eventlog.h +index eb9f4f4..485d259 100644 +--- a/include/sudo_eventlog.h ++++ b/include/sudo_eventlog.h @@ -80,6 +80,7 @@ struct eventlog_config { int syslog_rejectpri; int syslog_alertpri; @@ -24,7 +25,7 @@ Index: github-sudo-CVE-2026-35535/include/sudo_eventlog.h bool omit_hostname; const char *logpath; const char *time_fmt; -@@ -151,7 +152,7 @@ void eventlog_set_syslog_rejectpri(int p +@@ -151,7 +152,7 @@ void eventlog_set_syslog_rejectpri(int pri); void eventlog_set_syslog_alertpri(int pri); void eventlog_set_syslog_maxlen(size_t len); void eventlog_set_file_maxlen(size_t len); @@ -33,10 +34,10 @@ Index: github-sudo-CVE-2026-35535/include/sudo_eventlog.h void eventlog_set_omit_hostname(bool omit_hostname); void eventlog_set_logpath(const char *path); void eventlog_set_time_fmt(const char *fmt); -Index: github-sudo-CVE-2026-35535/lib/eventlog/eventlog.c -=================================================================== ---- github-sudo-CVE-2026-35535.orig/lib/eventlog/eventlog.c -+++ github-sudo-CVE-2026-35535/lib/eventlog/eventlog.c +diff --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c +index 5a32824..d56c4e4 100644 +--- a/lib/eventlog/eventlog.c ++++ b/lib/eventlog/eventlog.c @@ -304,15 +304,13 @@ exec_mailer(int pipein) syslog(LOG_ERR, _("unable to dup stdin: %m")); // -V618 sudo_debug_printf(SUDO_DEBUG_ERROR, @@ -89,11 +90,11 @@ Index: github-sudo-CVE-2026-35535/lib/eventlog/eventlog.c } /* Send a message to the mailto user */ -Index: github-sudo-CVE-2026-35535/lib/eventlog/eventlog_conf.c -=================================================================== ---- github-sudo-CVE-2026-35535.orig/lib/eventlog/eventlog_conf.c -+++ github-sudo-CVE-2026-35535/lib/eventlog/eventlog_conf.c -@@ -70,6 +70,7 @@ static struct eventlog_config evl_conf = +diff --git a/lib/eventlog/eventlog_conf.c b/lib/eventlog/eventlog_conf.c +index 0663a38..ec3b569 100644 +--- a/lib/eventlog/eventlog_conf.c ++++ b/lib/eventlog/eventlog_conf.c +@@ -70,6 +70,7 @@ static struct eventlog_config evl_conf = { MAXSYSLOGLEN, /* syslog_maxlen */ 0, /* file_maxlen */ ROOT_UID, /* mailuid */ @@ -113,11 +114,11 @@ Index: github-sudo-CVE-2026-35535/lib/eventlog/eventlog_conf.c } void -Index: github-sudo-CVE-2026-35535/plugins/sudoers/logging.c -=================================================================== ---- github-sudo-CVE-2026-35535.orig/plugins/sudoers/logging.c -+++ github-sudo-CVE-2026-35535/plugins/sudoers/logging.c -@@ -1155,7 +1155,7 @@ init_eventlog_config(void) +diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c +index bd4de92..9535289 100644 +--- a/plugins/sudoers/logging.c ++++ b/plugins/sudoers/logging.c +@@ -1157,7 +1157,7 @@ init_eventlog_config(void) eventlog_set_syslog_alertpri(def_syslog_badpri); eventlog_set_syslog_maxlen(def_syslog_maxlen); eventlog_set_file_maxlen(def_loglinelen); @@ -126,11 +127,11 @@ Index: github-sudo-CVE-2026-35535/plugins/sudoers/logging.c eventlog_set_omit_hostname(!def_log_host); eventlog_set_logpath(def_logfile); eventlog_set_time_fmt(def_log_year ? "%h %e %T %Y" : "%h %e %T"); -Index: github-sudo-CVE-2026-35535/plugins/sudoers/policy.c -=================================================================== ---- github-sudo-CVE-2026-35535.orig/plugins/sudoers/policy.c -+++ github-sudo-CVE-2026-35535/plugins/sudoers/policy.c -@@ -639,7 +639,7 @@ sudoers_policy_deserialize_info(struct s +diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c +index f3adfb0..27f6e58 100644 +--- a/plugins/sudoers/policy.c ++++ b/plugins/sudoers/policy.c +@@ -639,7 +639,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, } #ifdef NO_ROOT_MAILER diff --git a/debian/patches/0008-open_sudoers-Do-not-perform-path-expansion-on-files-.patch b/debian/patches/0008-open_sudoers-Do-not-perform-path-expansion-on-files-.patch new file mode 100644 index 0000000..0afe744 --- /dev/null +++ b/debian/patches/0008-open_sudoers-Do-not-perform-path-expansion-on-files-.patch @@ -0,0 +1,34 @@ +From: "Todd C. Miller" +Date: Sat, 24 Jan 2026 11:30:06 -0700 +Subject: open_sudoers: Do not perform path expansion on files in an + includedir + +A file in an includedir containing one or more colons (':') in the +name we was being expanded as a colon-separated path instead of +being opened as-is. This fixes a regression introduced in +sudo 1.9.14. Bug #1085 +--- + plugins/sudoers/sudoers.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c +index 0f75c96..fecd279 100644 +--- a/plugins/sudoers/sudoers.c ++++ b/plugins/sudoers/sudoers.c +@@ -1286,7 +1286,15 @@ open_sudoers(const char *path, char **outfile, bool doedit, bool *keepopen) + int error, fd; + debug_decl(open_sudoers, SUDOERS_DEBUG_PLUGIN); + +- fd = sudo_open_conf_path(path, fname, sizeof(fname), open_file); ++ if (outfile == NULL) { ++ /* Single file, do not treat as a path. */ ++ fd = open_file(path, O_RDONLY|O_NONBLOCK); ++ if (fd != -1) ++ (void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK); ++ } else { ++ /* Could be a colon-separated path of file names. */ ++ fd = sudo_open_conf_path(path, fname, sizeof(fname), open_file); ++ } + if (sudoers_ctx.parser_conf.ignore_perms) { + /* Skip sudoers security checks when ignore_perms is set. */ + if (fd == -1 || fstat(fd, &sb) == -1) diff --git a/debian/patches/amd64-ibt.diff b/debian/patches/amd64-ibt.diff new file mode 100644 index 0000000..0ad20fd --- /dev/null +++ b/debian/patches/amd64-ibt.diff @@ -0,0 +1,28 @@ +From: Marcos Del Sol Vives +Date: Tue, 2 Sep 2025 00:00:35 +0200 +Subject: Enable Intel CET on amd64 only + +--- + m4/hardening.m4 | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/m4/hardening.m4 b/m4/hardening.m4 +index f7d2a8c..cc7ee01 100644 +--- a/m4/hardening.m4 ++++ b/m4/hardening.m4 +@@ -105,6 +105,7 @@ AC_DEFUN([SUDO_CHECK_HARDENING], [ + ]) + fi + ++ if test "$host_cpu" = "x86_64"; then + # Check for control-flow transfer instrumentation (Intel CET). + AX_CHECK_COMPILE_FLAG([-fcf-protection], [ + AX_CHECK_LINK_FLAG([-fcf-protection], [ +@@ -112,6 +113,7 @@ AC_DEFUN([SUDO_CHECK_HARDENING], [ + AX_APPEND_FLAG([-Wc,-fcf-protection], [HARDENING_LDFLAGS]) + ]) + ]) ++ fi + fi + + # Linker-specific hardening flags. diff --git a/debian/patches/developer-mode-verify.patch b/debian/patches/developer-mode-verify.patch deleted file mode 100644 index 8499d78..0000000 --- a/debian/patches/developer-mode-verify.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 69ef2673766f4ea918a5b8290eb30db5db409a3a Mon Sep 17 00:00:00 2001 -From: zhouzilong -Date: Wed, 23 Apr 2025 15:45:55 +0800 -Subject: [PATCH] developer mode verify - ---- - plugins/sudoers/auth/pam.c | 7 +++++++ - plugins/sudoers/po/zh_CN.po | 11 ++++++----- - 2 files changed, 13 insertions(+), 5 deletions(-) - -diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c -index 973d67b..d0cabc8 100644 ---- a/plugins/sudoers/auth/pam.c -+++ b/plugins/sudoers/auth/pam.c -@@ -298,6 +298,7 @@ sudo_pam_verify(const struct sudoers_context *ctx, struct passwd *pw, - const char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback) - { - const char *envccname, *pam_user; -+ const char *pam_item; - int rc, *pam_status = (int *)auth->data; - debug_decl(sudo_pam_verify, SUDOERS_DEBUG_AUTH); - -@@ -355,6 +356,12 @@ sudo_pam_verify(const struct sudoers_context *ctx, struct passwd *pw, - sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, - "pam_authenticate: %d", *pam_status); - debug_return_int(AUTH_FAILURE); -+ case PAM_ABORT: -+ rc = pam_get_item(pamh, PAM_SERVICE, &pam_item); -+ if((rc == PAM_SUCCESS)&&(!strcmp(pam_item, "security-verify"))){ -+ log_warningx(ctx, 0, N_("No root privileges. Please request root access in developer mode in Control Center.")); -+ debug_return_int(AUTH_ERROR); -+ } - default: - log_warningx(ctx, 0, N_("PAM authentication error: %s"), - sudo_pam_strerror(pamh, *pam_status)); -diff --git a/plugins/sudoers/po/zh_CN.po b/plugins/sudoers/po/zh_CN.po -index 00b5214..1194283 100644 ---- a/plugins/sudoers/po/zh_CN.po -+++ b/plugins/sudoers/po/zh_CN.po -@@ -8,7 +8,7 @@ msgstr "" - "Project-Id-Version: sudoers 1.9.16b1\n" - "Report-Msgid-Bugs-To: https://bugzilla.sudo.ws\n" - "POT-Creation-Date: 2024-06-08 09:06-0600\n" --"PO-Revision-Date: 2024-06-17 14:52-0400\n" -+"PO-Revision-Date: 2025-04-23 15:36+0800\n" - "Last-Translator: Boyuan Yang <073plan@gmail.com>\n" - "Language-Team: Chinese (simplified) \n" - "Language: zh_CN\n" -@@ -17,7 +17,7 @@ msgstr "" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=1; plural=0;\n" - "X-Bugs: Report translation errors to the Language-Team address.\n" --"X-Generator: Poedit 3.4.4\n" -+"X-Generator: Poedit 2.2.1\n" - - #: confstr.sh:1 gram.y:1240 plugins/sudoers/logging.c:919 - msgid "syntax error" -@@ -1530,6 +1530,10 @@ msgstr "无法初始化 PAM:%s" - msgid "PAM authentication error: %s" - msgstr "PAM 认证出错:%s" - -+#: plugins/sudoers/auth/pam.c:362 -+msgid "No root privileges. Please request root access in developer mode in Control Center." -+msgstr "无root权限,如想获得root权限可以在控制中心选择进入开发者模式" -+ - #: plugins/sudoers/auth/pam.c:369 - msgid "account validation failure, is your account locked?" - msgstr "账户验证失败,您的账户是不是上锁了?" -@@ -3891,15 +3895,12 @@ msgstr "将忽略包含“.”字符的文件名" - msgid "too many levels of includes" - msgstr "include 嵌套层数过多" - --#, c-format - #~ msgid "%s must be owned by uid %d" - #~ msgstr "%s 必须属于用户 ID %d" - --#, c-format - #~ msgid "%s must only be writable by owner" - #~ msgstr "%s 必须只对所有者可写" - --#, c-format - #~ msgid "timestamp owner (%s): No such user" - #~ msgstr "时间戳所有者(%s):无此用户" - --- -2.20.1 - diff --git a/debian/patches/series b/debian/patches/series index f9a9455..21e0e90 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -5,5 +5,6 @@ sudo-ldap-docs.patch X11R6.patch 0007-upstream-patch-for-CVE-2025-32463.patch 0008-upstream-patch-for-CVE-2025-32462.patch -developer-mode-verify.patch -cve_2026_35535.patch +0008-open_sudoers-Do-not-perform-path-expansion-on-files-.patch +amd64-ibt.diff +0006-exec_mailer-Set-group-as-well-as-uid-when-running-th.patch diff --git a/debian/tests/01-getroot b/debian/tests/01-getroot index 4edef3e..bae4096 100755 --- a/debian/tests/01-getroot +++ b/debian/tests/01-getroot @@ -9,7 +9,7 @@ passwd1=$(echo "$passwd" |cut -c1) # Note: we do need the 'xfoo' syntax here, since POSIX special-cases # the $passwd value '!' as negation. if [ "x$passwd" = "x*" ] || [ "x$passwd1" = "x!" ]; then - echo "root:rootpassword" | chpasswd + echo "root:riegh@oh4ahR" | chpasswd fi TESTNR="01" @@ -19,7 +19,7 @@ DIR="${BASEDIR}/${TESTNR}" PATH="/bin:/usr/bin:/sbin:/usr/sbin" ACCTA="test${TESTNR}a" ACCTB="test${TESTNR}b" -PASSWD="test${TESTNR}23456" +PASSWD="test${TESTNR}Terah9ien7e" HOMEDIRA="/home/${ACCTA}" HOMEDIRB="/home/${ACCTB}" LDIFDIR="${DIR}/ldif" diff --git a/debian/tests/02-1003969-audit-no-resolve b/debian/tests/02-1003969-audit-no-resolve index 3fc32aa..11d2aaf 100755 --- a/debian/tests/02-1003969-audit-no-resolve +++ b/debian/tests/02-1003969-audit-no-resolve @@ -7,21 +7,29 @@ BASEDIR="$(pwd)/debian/tests" COMMONDIR="${BASEDIR}/common" DIR="${BASEDIR}/${TESTNR}" PATH="/bin:/usr/bin:/sbin:/usr/sbin" -ACCTA="test${TESTNR}a" -ACCTB="test${TESTNR}b" -PASSWD="test${TESTNR}23456" HOMEDIRA="/root" -LDIFDIR="${DIR}/ldif" trap ' printf "\ntrap handler\n" - mv /etc/resolv.conf.disabled /etc/resolv.conf || true - mv /etc/hosts.disabled /etc/hosts || true + if [ -e /etc/resolv.conf.disabled ]; then + cp /etc/resolv.conf.disabled /etc/resolv.conf || true + rm -f /etc/resolv.conf.disabled || true + fi + if [ -e /etc/hosts.disabled ]; then + cp /etc/hosts.disabled /etc/hosts || true + rm -f /etc/hosts.disabled || true + fi ' 0 INT QUIT ABRT PIPE TERM printf "========= test %s\.1: sudo to nobody\n" "${TESTNR}" -mv /etc/resolv.conf /etc/resolv.conf.disabled -mv /etc/hosts /etc/hosts.disabled +if [ -e /etc/resolv.conf ]; then + cp /etc/resolv.conf /etc/resolv.conf.disabled + : >/etc/resolv.conf +fi +if [ -e /etc/hosts ]; then + cp /etc/hosts /etc/hosts.disabled + : >/etc/hosts +fi RET=0 printf "trying sudo to nobody\n" cd "${HOMEDIRA}" @@ -35,7 +43,7 @@ if [ "${STDERRLENGTH}" != "0" ]; then printf >&2 "stderr:\n" cat >&2 ${HOMEDIRA}/stderr printf >&2 "exit code %s\n" "${RET}" - printf >&2 "exit 1\n" "${RET}" + printf >&2 "exit 1\n" exit 1 fi diff --git a/debian/tests/03-1126085-sudoersd b/debian/tests/03-1126085-sudoersd new file mode 100755 index 0000000..119157a --- /dev/null +++ b/debian/tests/03-1126085-sudoersd @@ -0,0 +1,32 @@ +#!/bin/sh + +set -e + +TESTNR="03" +BASEDIR="$(pwd)/debian/tests" +COMMONDIR="${BASEDIR}/common" +DIR="${BASEDIR}/${TESTNR}" +PATH="/bin:/usr/bin:/sbin:/usr/sbin" +FILES="$(find $DIR/sudoersd/ -type f)" +echo $FILES +DSTFILES="$(echo $FILES | sed "s|${DIR}/sudoersd|/etc/sudoers.d|g")" +echo $DSTFILES + +trap ' + true +' 0 INT QUIT ABRT PIPE TERM + +printf "copy files to sudoers ... " +cp $FILES /etc/sudoers.d/ +printf "collect sudo -l output ... " +OUTPUT="$(sudo -l | grep -- ----marker----)" +EXPECTED=" (ALL : ALL) /usr/bin/----marker----/this-is-the-sudoersd-10_dsa\:\:util\:\:sudo[dfsg-team-role]-file + (ALL : ALL) /usr/bin/----marker----/this-is-the-sudoersd-root-file" +if [ "$OUTPUT" != "$EXPECTED" ]; then + printf "sudo -l output not as expected, Test failed\n" + exit 1 +fi + +printf "test series sucessful, exit 0\n" +exit 0 + diff --git a/debian/tests/03/10_dsa::util::sudo[dfsg-team-role] b/debian/tests/03/10_dsa::util::sudo[dfsg-team-role] new file mode 100644 index 0000000..0a77cf3 --- /dev/null +++ b/debian/tests/03/10_dsa::util::sudo[dfsg-team-role] @@ -0,0 +1 @@ +root ALL=(ALL:ALL) /usr/bin/----marker----/this-is-the-sudoersd-10_dsa\:\:util\:\:sudo[dfsg-team-role]-file diff --git a/debian/tests/03/root b/debian/tests/03/root new file mode 100644 index 0000000..12a03fd --- /dev/null +++ b/debian/tests/03/root @@ -0,0 +1 @@ +root ALL=(ALL:ALL) /usr/bin/----marker----/this-is-the-sudoersd-root-file diff --git a/debian/tests/03/sudoersd/10_dsa::util::sudo[dfsg-team-role] b/debian/tests/03/sudoersd/10_dsa::util::sudo[dfsg-team-role] new file mode 100644 index 0000000..0a77cf3 --- /dev/null +++ b/debian/tests/03/sudoersd/10_dsa::util::sudo[dfsg-team-role] @@ -0,0 +1 @@ +root ALL=(ALL:ALL) /usr/bin/----marker----/this-is-the-sudoersd-10_dsa\:\:util\:\:sudo[dfsg-team-role]-file diff --git a/debian/tests/03/sudoersd/root b/debian/tests/03/sudoersd/root new file mode 100644 index 0000000..12a03fd --- /dev/null +++ b/debian/tests/03/sudoersd/root @@ -0,0 +1 @@ +root ALL=(ALL:ALL) /usr/bin/----marker----/this-is-the-sudoersd-root-file diff --git a/debian/tests/04-getroot-sssd b/debian/tests/04-getroot-sssd index bcafaf8..5b08018 100755 --- a/debian/tests/04-getroot-sssd +++ b/debian/tests/04-getroot-sssd @@ -17,58 +17,89 @@ HOMEDIRA="/home/${ACCTA}" HOMEDIRB="/home/${ACCTB}" LDIFDIR="${DIR}/ldif" SSSDCONF="/etc/sssd/sssd.conf" +RUNDIR="/run/slapd" +VARRUNDIR="/var/run/slapd" trap ' kill $(pidof slapd) 2>/dev/null || true kill $(pidof sssd) 2>/dev/null || true + kill $(pidof socat) 2>/dev/null || true + rm -f /dev/log || true ' 0 INT QUIT ABRT PIPE TERM # openssl req -x509 -days 365 -nodes -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem --subj "/C=DE/CN=emptysid86.zugschlus.de" +printf "make and chown dirs ... " +mkdir -p "${RUNDIR}" "${VARRUNDIR}" +chown openldap "${VARRUNDIR}" < ${LDIFDIR}/debconf debconf-set-selections + printf "clean up ldap database ... " rm -rf /var/lib/ldap/*.mdb + printf "move configuration in place ... " mkdir -p /etc/ldap /etc/sssd cp ${LDIFDIR}/server_*.pem /etc/ldap/ cp ${LDIFDIR}/ldap.conf /etc/ldap/ chown openldap:openldap /etc/ldap/server_*.pem chmod 600 /etc/ldap/server_key.pem +# slapd.conf is only needed for OpenLDAP 2.4 on bullseye +# but since it's already there now, use it for OpenLDAP 2.5+ as well +# this is a testsuite. If you want /etc/ldap/slapd.d to be used (again), +# please submit a patch that will also work on bullseye. +cp ${LDIFDIR}/slapd.conf /etc/ldap/ cp ${LDIFDIR}/sssd.conf /etc/sssd chown root:root /etc/sssd/sssd.conf chmod 600 /etc/sssd/sssd.conf cp ${LDIFDIR}/slapd-default /etc/default/slapd echo "slapd: [::1]" >> /etc/hosts.allow + printf "reconfigure slapd ... " DEBIAN_FRONTEND=noninteractive dpkg-reconfigure -pcritical slapd 2>/dev/null kill $(pidof slapd) 2>/dev/null || true sleep 1 + +if ! [ -S /dev/log ]; then + echo "starting fake syslog socket on /dev/log" + + # remove stale file if present + [ -e /dev/log ] && rm -f /dev/log + + socat -u UNIX-RECV:/dev/log,mode=666 STDOUT >/dev/null 2>/dev/null & +fi + printf "start slapd ... " -slapd -h "ldaps:/// ldapi:///" -g openldap -u openldap -F /etc/ldap/slapd.d +slapd -f /etc/ldap/slapd.conf -h "ldaps://:1636/ ldapi:///" -g openldap -u openldap + +printf "check slapd running .... " +pgrep -a slapd # ldapsearch -x -LLL -s base -b "" namingContexts should work here -printf "set LDAP passwords" -ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/tls.ldif 2>/dev/null -ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/adminpw.ldif 2>/dev/null -ldapmodify -Y external -H ldapi:/// -f ${LDIFDIR}/adminpw-example-com.ldif 2>/dev/null -printf "add users and groups OUs ..." -ldapadd -x -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/sss-ous.ldif 2>/dev/null -printf "add users ..." + +printf "add users and groups OUs ...\n" +ldapadd -x -c -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/sss-ous.ldif 2>/dev/null || true printf "sssd.conf ...\n" cp ${LDIFDIR}/sssd.conf "${SSSDCONF}" -printf "sudoers file ...\n"A +printf "sudoers file ...\n" mkdir -p /etc/sudoers.d/ -mv ${LDIFDIR}/ldapsudoers /etc/sudoers.d/ +cp ${LDIFDIR}/ldapsudoers /etc/sudoers.d/ chown root:root "${SSSDCONF}" /etc/sudoers.d/ /etc/sudoers.d/* chmod 755 /etc/sudoers.d/ chmod 600 "${SSSDCONF}" /etc/sudoers.d/* + +printf "start sssd ..." kill $(pidof sssd) 2>/dev/null || true sleep 1 sssd --logger=files -D +printf "check sssd running .... " +pgrep -a sssd + +printf "add users ..." for user in testuser1 testuser2; do ldapadd -x -D "cn=admin,dc=example,dc=com" -w ldappw -f ${LDIFDIR}/${user}.ldif 2>/dev/null + getent passwd ${user} mkdir -p /home/${user} chown ${user}:nogroup /home/${user} done diff --git a/debian/tests/04/ldif/ldap.conf b/debian/tests/04/ldif/ldap.conf index 3f3000a..b3b3022 100644 --- a/debian/tests/04/ldif/ldap.conf +++ b/debian/tests/04/ldif/ldap.conf @@ -1,5 +1,5 @@ BASE dc=example,dc=com -URI ldaps://[::1]:636/ +URI ldaps://[::1]:1636/ TLS_CACERT /etc/ldap/server_cert.pem TLS_REQCERT allow SASL_NOCANON on diff --git a/debian/tests/04/ldif/slapd.conf b/debian/tests/04/ldif/slapd.conf new file mode 100644 index 0000000..9fe0727 --- /dev/null +++ b/debian/tests/04/ldif/slapd.conf @@ -0,0 +1,22 @@ +# OpenLDAP 2.4 (bullseye) only +modulepath /usr/lib/ldap +moduleload back_mdb +include /etc/ldap/schema/core.schema +include /etc/ldap/schema/cosine.schema +include /etc/ldap/schema/nis.schema +include /etc/ldap/schema/inetorgperson.schema + +database mdb +maxsize 1073741824 +directory /var/lib/ldap + +# Suffix and root DN must come in this order +suffix "dc=example,dc=com" +rootdn "cn=admin,dc=example,dc=com" +rootpw ldappw + +# TLS optional +TLSCertificateFile /etc/ldap/server_cert.pem +TLSCertificateKeyFile /etc/ldap/server_key.pem +TLSCACertificateFile /etc/ldap/server_cert.pem + diff --git a/debian/tests/04/ldif/sss-ous.ldif b/debian/tests/04/ldif/sss-ous.ldif index 5ba018c..144b2fa 100644 --- a/debian/tests/04/ldif/sss-ous.ldif +++ b/debian/tests/04/ldif/sss-ous.ldif @@ -1,3 +1,10 @@ +dn: dc=example,dc=com +objectClass: top +objectClass: dcObject +objectClass: organization +o: Example Organization +dc: example + dn: ou=users,dc=example,dc=com objectClass: top objectClass: organizationalUnit diff --git a/debian/tests/04/ldif/sssd.conf b/debian/tests/04/ldif/sssd.conf index ee06ef5..b0b4796 100755 --- a/debian/tests/04/ldif/sssd.conf +++ b/debian/tests/04/ldif/sssd.conf @@ -7,7 +7,7 @@ debug_level = 0x01ff id_provider = ldap auth_provider = ldap -ldap_uri = ldaps://[::1]:636/ +ldap_uri = ldaps://[::1]:1636/ ldap_search_base = dc=example,dc=com ldap_tls_cacert = /etc/ldap/server_cert.pem diff --git a/debian/tests/04/ldif/tls.ldif b/debian/tests/04/ldif/tls.ldif index 012adf2..a84b4c1 100644 --- a/debian/tests/04/ldif/tls.ldif +++ b/debian/tests/04/ldif/tls.ldif @@ -1,10 +1,32 @@ +dn: cn=config +changetype: modify +delete: olcTLSCACertificateFile +- + +dn: cn=config +changetype: modify +delete: olcTLSCertificateFile +- + +dn: cn=config +changetype: modify +delete: olcTLSCertificateKeyFile +- + dn: cn=config changetype: modify add: olcTLSCACertificateFile olcTLSCACertificateFile: /etc/ldap/server_cert.pem - + +dn: cn=config +changetype: modify +add: olcTLSCertificateFile +olcTLSCertificateFile: /etc/ldap/server_cert.pem +- + +dn: cn=config +changetype: modify add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/server_key.pem - -add: olcTLSCertificateFile -olcTLSCertificateFile: /etc/ldap/server_cert.pem diff --git a/debian/tests/control b/debian/tests/control index abea94c..dcb8429 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,16 +1,11 @@ Tests: 01-getroot -Depends: sudo, adduser +Depends: adduser, sudo, cracklib-runtime Restrictions: needs-root Tests: 02-1003969-audit-no-resolve Depends: sudo Restrictions: needs-root -Tests: 03-getroot-ldap -Depends: sudo-ldap, adduser, slapd, ldap-utils, cron -Restrictions: needs-root - Tests: 04-getroot-sssd -Depends: sudo, adduser, slapd, ldap-utils, sssd-common, sssd-ldap, cron +Depends: adduser, cron, ldap-utils, procps, slapd, sssd-common, sssd-ldap, sudo, socat, libnss-sss, libpam-sss Restrictions: needs-root - diff --git a/plugins/sudoers/po/zh_CN.mo b/plugins/sudoers/po/zh_CN.mo index de42b0f6e9fa9a9d12867b0412a0108b18161123..ee28ea377eb7f4e95f891ab5ba196275bd17d381 100644 GIT binary patch delta 14032 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 SGjcYq&EB_g=ek1?b^Z@BYFnZJ