diff options
Diffstat (limited to 'debian/patches')
-rw-r--r-- | debian/patches/0001-gpasswd-1-Fix-password-leak.patch | 137 | ||||
-rw-r--r-- | debian/patches/0002-Added-control-character-check.patch | 45 | ||||
-rw-r--r-- | debian/patches/0003-Overhaul-valid_field.patch | 61 | ||||
-rw-r--r-- | debian/patches/008_login_log_failure_in_FTMP | 51 | ||||
-rw-r--r-- | debian/patches/401_cppw_src.dpatch | 276 | ||||
-rw-r--r-- | debian/patches/402_cppw_selinux | 64 | ||||
-rw-r--r-- | debian/patches/429_login_FAILLOG_ENAB | 84 | ||||
-rw-r--r-- | debian/patches/463_login_delay_obeys_to_PAM | 97 | ||||
-rw-r--r-- | debian/patches/501_commonio_group_shadow | 60 | ||||
-rw-r--r-- | debian/patches/502_debian_useradd_defaults | 41 | ||||
-rw-r--r-- | debian/patches/503_shadowconfig.8 | 201 | ||||
-rw-r--r-- | debian/patches/505_useradd_recommend_adduser | 36 | ||||
-rw-r--r-- | debian/patches/506_relaxed_usernames | 111 | ||||
-rw-r--r-- | debian/patches/542_useradd-O_option | 40 | ||||
-rw-r--r-- | debian/patches/900_testsuite_groupmems | 81 | ||||
-rw-r--r-- | debian/patches/901_testsuite_gcov | 76 | ||||
-rw-r--r-- | debian/patches/README.patches | 22 | ||||
-rw-r--r-- | debian/patches/series | 23 |
18 files changed, 1506 insertions, 0 deletions
diff --git a/debian/patches/0001-gpasswd-1-Fix-password-leak.patch b/debian/patches/0001-gpasswd-1-Fix-password-leak.patch new file mode 100644 index 0000000..1596b2d --- /dev/null +++ b/debian/patches/0001-gpasswd-1-Fix-password-leak.patch @@ -0,0 +1,137 @@ +From 65c88a43a23c2391dcc90c0abda3e839e9c57904 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar <alx@kernel.org> +Date: Sat, 10 Jun 2023 16:20:05 +0200 +Subject: [PATCH] gpasswd(1): Fix password leak + +How to trigger this password leak? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When gpasswd(1) asks for the new password, it asks twice (as is usual +for confirming the new password). Each of those 2 password prompts +uses agetpass() to get the password. If the second agetpass() fails, +the first password, which has been copied into the 'static' buffer +'pass' via STRFCPY(), wasn't being zeroed. + +agetpass() is defined in <./libmisc/agetpass.c> (around line 91), and +can fail for any of the following reasons: + +- malloc(3) or readpassphrase(3) failure. + + These are going to be difficult to trigger. Maybe getting the system + to the limits of memory utilization at that exact point, so that the + next malloc(3) gets ENOMEM, and possibly even the OOM is triggered. + About readpassphrase(3), ENFILE and EINTR seem the only plausible + ones, and EINTR probably requires privilege or being the same user; + but I wouldn't discard ENFILE so easily, if a process starts opening + files. + +- The password is longer than PASS_MAX. + + The is plausible with physical access. However, at that point, a + keylogger will be a much simpler attack. + +And, the attacker must be able to know when the second password is being +introduced, which is not going to be easy. + +How to read the password after the leak? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Provoking the leak yourself at the right point by entering a very long +password is easy, and inspecting the process stack at that point should +be doable. Try to find some consistent patterns. + +Then, search for those patterns in free memory, right after the victim +leaks their password. + +Once you get the leak, a program should read all the free memory +searching for patterns that gpasswd(1) leaves nearby the leaked +password. + +On 6/10/23 03:14, Seth Arnold wrote: +> An attacker process wouldn't be able to use malloc(3) for this task. +> There's a handful of tools available for userspace to allocate memory: +> +> - brk / sbrk +> - mmap MAP_ANONYMOUS +> - mmap /dev/zero +> - mmap some other file +> - shm_open +> - shmget +> +> Most of these return only pages of zeros to a process. Using mmap of an +> existing file, you can get some of the contents of the file demand-loaded +> into the memory space on the first use. +> +> The MAP_UNINITIALIZED flag only works if the kernel was compiled with +> CONFIG_MMAP_ALLOW_UNINITIALIZED. This is rare. +> +> malloc(3) doesn't zero memory, to our collective frustration, but all the +> garbage in the allocations is from previous allocations in the current +> process. It isn't leftover from other processes. +> +> The avenues available for reading the memory: +> - /dev/mem and /dev/kmem (requires root, not available with Secure Boot) +> - /proc/pid/mem (requires ptrace privileges, mediated by YAMA) +> - ptrace (requires ptrace privileges, mediated by YAMA) +> - causing memory to be swapped to disk, and then inspecting the swap +> +> These all require a certain amount of privileges. + +How to fix it? +~~~~~~~~~~~~~~ + +memzero(), which internally calls explicit_bzero(3), or whatever +alternative the system provides with a slightly different name, will +make sure that the buffer is zeroed in memory, and optimizations are not +allowed to impede this zeroing. + +This is not really 100% effective, since compilers may place copies of +the string somewhere hidden in the stack. Those copies won't get zeroed +by explicit_bzero(3). However, that's arguably a compiler bug, since +compilers should make everything possible to avoid optimizing strings +that are later passed to explicit_bzero(3). But we all know that +sometimes it's impossible to have perfect knowledge in the compiler, so +this is plausible. Nevertheless, there's nothing we can do against such +issues, except minimizing the time such passwords are stored in plain +text. + +Security concerns +~~~~~~~~~~~~~~~~~ + +We believe this isn't easy to exploit. Nevertheless, and since the fix +is trivial, this fix should probably be applied soon, and backported to +all supported distributions, to prevent someone else having more +imagination than us to find a way. + +Affected versions +~~~~~~~~~~~~~~~~~ + +All. Bug introduced in shadow 19990709. That's the second commit in +the git history. + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Reported-by: Alejandro Colomar <alx@kernel.org> +Cc: Serge Hallyn <serge@hallyn.com> +Cc: Iker Pedrosa <ipedrosa@redhat.com> +Cc: Seth Arnold <seth.arnold@canonical.com> +Cc: Christian Brauner <christian@brauner.io> +Cc: Balint Reczey <rbalint@debian.org> +Cc: Sam James <sam@gentoo.org> +Cc: David Runge <dvzrv@archlinux.org> +Cc: Andreas Jaeger <aj@suse.de> +Cc: <~hallyn/shadow@lists.sr.ht> +Signed-off-by: Alejandro Colomar <alx@kernel.org> +--- + src/gpasswd.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -896,6 +896,7 @@ + strzero (cp); + cp = getpass (_("Re-enter new password: ")); + if (NULL == cp) { ++ memzero (pass, sizeof pass); + exit (1); + } + diff --git a/debian/patches/0002-Added-control-character-check.patch b/debian/patches/0002-Added-control-character-check.patch new file mode 100644 index 0000000..29adce1 --- /dev/null +++ b/debian/patches/0002-Added-control-character-check.patch @@ -0,0 +1,45 @@ +From e5905c4b84d4fb90aefcd96ee618411ebfac663d Mon Sep 17 00:00:00 2001 +From: tomspiderlabs <128755403+tomspiderlabs@users.noreply.github.com> +Date: Thu, 23 Mar 2023 23:39:38 +0000 +Subject: [PATCH] Added control character check + +Added control character check, returning -1 (to "err") if control characters are present. +--- + lib/fields.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/lib/fields.c b/lib/fields.c +index 640be931..fb51b582 100644 +--- a/lib/fields.c ++++ b/lib/fields.c +@@ -21,9 +21,9 @@ + * + * The supplied field is scanned for non-printable and other illegal + * characters. +- * + -1 is returned if an illegal character is present. +- * + 1 is returned if no illegal characters are present, but the field +- * contains a non-printable character. ++ * + -1 is returned if an illegal or control character is present. ++ * + 1 is returned if no illegal or control characters are present, ++ * but the field contains a non-printable character. + * + 0 is returned otherwise. + */ + int valid_field (const char *field, const char *illegal) +@@ -45,10 +45,13 @@ int valid_field (const char *field, const char *illegal) + } + + if (0 == err) { +- /* Search if there are some non-printable characters */ ++ /* Search if there are non-printable or control characters */ + for (cp = field; '\0' != *cp; cp++) { + if (!isprint (*cp)) { + err = 1; ++ } ++ if (!iscntrl (*cp)) { ++ err = -1; + break; + } + } +-- +2.34.1 + diff --git a/debian/patches/0003-Overhaul-valid_field.patch b/debian/patches/0003-Overhaul-valid_field.patch new file mode 100644 index 0000000..b7a8428 --- /dev/null +++ b/debian/patches/0003-Overhaul-valid_field.patch @@ -0,0 +1,61 @@ +From 2eaea70111f65b16d55998386e4ceb4273c19eb4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com> +Date: Fri, 31 Mar 2023 14:46:50 +0200 +Subject: [PATCH] Overhaul valid_field() + +e5905c4b ("Added control character check") introduced checking for +control characters but had the logic inverted, so it rejects all +characters that are not control ones. + +Cast the character to `unsigned char` before passing to the character +checking functions to avoid UB. + +Use strpbrk(3) for the illegal character test and return early. +--- + lib/fields.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/lib/fields.c b/lib/fields.c +index fb51b582..53929248 100644 +--- a/lib/fields.c ++++ b/lib/fields.c +@@ -37,26 +37,22 @@ int valid_field (const char *field, const char *illegal) + + /* For each character of field, search if it appears in the list + * of illegal characters. */ ++ if (illegal && NULL != strpbrk (field, illegal)) { ++ return -1; ++ } ++ ++ /* Search if there are non-printable or control characters */ + for (cp = field; '\0' != *cp; cp++) { +- if (strchr (illegal, *cp) != NULL) { ++ unsigned char c = *cp; ++ if (!isprint (c)) { ++ err = 1; ++ } ++ if (iscntrl (c)) { + err = -1; + break; + } + } + +- if (0 == err) { +- /* Search if there are non-printable or control characters */ +- for (cp = field; '\0' != *cp; cp++) { +- if (!isprint (*cp)) { +- err = 1; +- } +- if (!iscntrl (*cp)) { +- err = -1; +- break; +- } +- } +- } +- + return err; + } + +-- +2.34.1 + diff --git a/debian/patches/008_login_log_failure_in_FTMP b/debian/patches/008_login_log_failure_in_FTMP new file mode 100644 index 0000000..0946ca0 --- /dev/null +++ b/debian/patches/008_login_log_failure_in_FTMP @@ -0,0 +1,51 @@ +Goal: Log login failures to the btmp file + +Notes: + * I'm not sure login should add an entry in the FTMP file when PAM is used. + (but nothing in /etc/login.defs indicates that the failure is not logged) + +--- a/src/login.c ++++ b/src/login.c +@@ -827,6 +827,24 @@ + (void) puts (""); + (void) puts (_("Login incorrect")); + ++ if (getdef_str("FTMP_FILE") != NULL) { ++#ifdef USE_UTMPX ++ struct utmpx *failent = ++ prepare_utmpx (failent_user, ++ tty, ++ /* FIXME: or fromhost? */hostname, ++ utent); ++#else /* !USE_UTMPX */ ++ struct utmp *failent = ++ prepare_utmp (failent_user, ++ tty, ++ hostname, ++ utent); ++#endif /* !USE_UTMPX */ ++ failtmp (failent_user, failent); ++ free (failent); ++ } ++ + if (failcount >= retries) { + SYSLOG ((LOG_NOTICE, + "TOO MANY LOGIN TRIES (%u)%s FOR '%s'", +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -38,7 +38,6 @@ + {"ENVIRON_FILE", NULL}, \ + {"ENV_TZ", NULL}, \ + {"FAILLOG_ENAB", NULL}, \ +- {"FTMP_FILE", NULL}, \ + {"HMAC_CRYPTO_ALGO", NULL}, \ + {"ISSUE_FILE", NULL}, \ + {"LASTLOG_ENAB", NULL}, \ +@@ -80,6 +79,7 @@ + {"ERASECHAR", NULL}, + {"FAIL_DELAY", NULL}, + {"FAKE_SHELL", NULL}, ++ {"FTMP_FILE", NULL}, + {"GID_MAX", NULL}, + {"GID_MIN", NULL}, + {"HOME_MODE", NULL}, diff --git a/debian/patches/401_cppw_src.dpatch b/debian/patches/401_cppw_src.dpatch new file mode 100644 index 0000000..5244702 --- /dev/null +++ b/debian/patches/401_cppw_src.dpatch @@ -0,0 +1,276 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 401_cppw_src.dpatch by Nicolas FRANCOIS <nicolas.francois@centraliens.net> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: Add cppw / cpgr + +@DPATCH@ +--- /dev/null ++++ b/src/cppw.c +@@ -0,0 +1,238 @@ ++/* ++ cppw, cpgr copy with locking given file over the password or group file ++ with -s will copy with locking given file over shadow or gshadow file ++ ++ Copyright (C) 1999 Stephen Frost <sfrost@snowman.net> ++ ++ Based on vipw, vigr by: ++ Copyright (C) 1997 Guy Maor <maor@ece.utexas.edu> ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++ */ ++ ++#include <config.h> ++#include "defines.h" ++ ++#include <errno.h> ++#include <sys/stat.h> ++#include <unistd.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <sys/types.h> ++#include <signal.h> ++#include <utime.h> ++#include "exitcodes.h" ++#include "prototypes.h" ++#include "pwio.h" ++#include "shadowio.h" ++#include "groupio.h" ++#include "sgroupio.h" ++ ++ ++const char *Prog; ++ ++const char *filename, *filenewname; ++static bool filelocked = false; ++static int (*unlock) (void); ++ ++/* local function prototypes */ ++static int create_copy (FILE *fp, const char *dest, struct stat *sb); ++static void cppwexit (const char *msg, int syserr, int ret); ++static void cppwcopy (const char *file, ++ const char *in_file, ++ int (*file_lock) (void), ++ int (*file_unlock) (void)); ++ ++static int create_copy (FILE *fp, const char *dest, struct stat *sb) ++{ ++ struct utimbuf ub; ++ FILE *bkfp; ++ int c; ++ mode_t mask; ++ ++ mask = umask (077); ++ bkfp = fopen (dest, "w"); ++ (void) umask (mask); ++ if (NULL == bkfp) { ++ return -1; ++ } ++ ++ rewind (fp); ++ while ((c = getc (fp)) != EOF) { ++ if (putc (c, bkfp) == EOF) { ++ break; ++ } ++ } ++ ++ if ( (c != EOF) ++ || (fflush (bkfp) != 0)) { ++ (void) fclose (bkfp); ++ (void) unlink (dest); ++ return -1; ++ } ++ if ( (fsync (fileno (bkfp)) != 0) ++ || (fclose (bkfp) != 0)) { ++ (void) unlink (dest); ++ return -1; ++ } ++ ++ ub.actime = sb->st_atime; ++ ub.modtime = sb->st_mtime; ++ if ( (utime (dest, &ub) != 0) ++ || (chmod (dest, sb->st_mode) != 0) ++ || (chown (dest, sb->st_uid, sb->st_gid) != 0)) { ++ (void) unlink (dest); ++ return -1; ++ } ++ return 0; ++} ++ ++static void cppwexit (const char *msg, int syserr, int ret) ++{ ++ int err = errno; ++ if (filelocked) { ++ (*unlock) (); ++ } ++ if (NULL != msg) { ++ fprintf (stderr, "%s: %s", Prog, msg); ++ if (0 != syserr) { ++ fprintf (stderr, ": %s", strerror (err)); ++ } ++ (void) fputs ("\n", stderr); ++ } ++ if (NULL != filename) { ++ fprintf (stderr, _("%s: %s is unchanged\n"), Prog, filename); ++ } else { ++ fprintf (stderr, _("%s: no changes\n"), Prog); ++ } ++ ++ exit (ret); ++} ++ ++static void cppwcopy (const char *file, ++ const char *in_file, ++ int (*file_lock) (void), ++ int (*file_unlock) (void)) ++{ ++ struct stat st1; ++ FILE *f; ++ char filenew[1024]; ++ ++ snprintf (filenew, sizeof filenew, "%s.new", file); ++ unlock = file_unlock; ++ filename = file; ++ filenewname = filenew; ++ ++ if (access (file, F_OK) != 0) { ++ cppwexit (file, 1, 1); ++ } ++ if (file_lock () == 0) { ++ cppwexit (_("Couldn't lock file"), 0, 5); ++ } ++ filelocked = true; ++ ++ /* file to copy has same owners, perm */ ++ if (stat (file, &st1) != 0) { ++ cppwexit (file, 1, 1); ++ } ++ f = fopen (in_file, "r"); ++ if (NULL == f) { ++ cppwexit (in_file, 1, 1); ++ } ++ if (create_copy (f, filenew, &st1) != 0) { ++ cppwexit (_("Couldn't make copy"), errno, 1); ++ } ++ ++ /* XXX - here we should check filenew for errors; if there are any, ++ * fail w/ an appropriate error code and let the user manually fix ++ * it. Use pwck or grpck to do the check. - Stephen (Shamelessly ++ * stolen from '--marekm's comment) */ ++ ++ if (rename (filenew, file) != 0) { ++ fprintf (stderr, _("%s: can't copy %s: %s)\n"), ++ Prog, filenew, strerror (errno)); ++ cppwexit (NULL,0,1); ++ } ++ ++ (*file_unlock) (); ++} ++ ++int main (int argc, char **argv) ++{ ++ int flag; ++ bool cpshadow = false; ++ char *in_file; ++ int e = E_USAGE; ++ bool do_cppw = true; ++ ++ (void) setlocale (LC_ALL, ""); ++ (void) bindtextdomain (PACKAGE, LOCALEDIR); ++ (void) textdomain (PACKAGE); ++ ++ Prog = Basename (argv[0]); ++ if (strcmp (Prog, "cpgr") == 0) { ++ do_cppw = false; ++ } ++ ++ while ((flag = getopt (argc, argv, "ghps")) != EOF) { ++ switch (flag) { ++ case 'p': ++ do_cppw = true; ++ break; ++ case 'g': ++ do_cppw = false; ++ break; ++ case 's': ++ cpshadow = true; ++ break; ++ case 'h': ++ e = E_SUCCESS; ++ /*pass through*/ ++ default: ++ (void) fputs (_("Usage:\n\ ++`cppw <file>' copys over /etc/passwd `cppw -s <file>' copys over /etc/shadow\n\ ++`cpgr <file>' copys over /etc/group `cpgr -s <file>' copys over /etc/gshadow\n\ ++"), (E_SUCCESS != e) ? stderr : stdout); ++ exit (e); ++ } ++ } ++ ++ if (argc != optind + 1) { ++ cppwexit (_("wrong number of arguments, -h for usage"),0,1); ++ } ++ ++ in_file = argv[optind]; ++ ++ if (do_cppw) { ++ if (cpshadow) { ++ cppwcopy (SHADOW_FILE, in_file, spw_lock, spw_unlock); ++ } else { ++ cppwcopy (PASSWD_FILE, in_file, pw_lock, pw_unlock); ++ } ++ } else { ++#ifdef SHADOWGRP ++ if (cpshadow) { ++ cppwcopy (SGROUP_FILE, in_file, sgr_lock, sgr_unlock); ++ } else ++#endif /* SHADOWGRP */ ++ { ++ cppwcopy (GROUP_FILE, in_file, gr_lock, gr_unlock); ++ } ++ } ++ ++ return 0; ++} ++ +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -34,6 +34,7 @@ + bin_PROGRAMS += su + endif + usbin_PROGRAMS = \ ++ cppw \ + chgpasswd \ + chpasswd \ + groupadd \ +@@ -102,6 +103,7 @@ + chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) ++cppw_LDADD = $(LDADD) $(LIBSELINUX) $(LIBAUDIT) + expiry_LDADD = $(LDADD) $(LIBECONF) + gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -91,6 +91,7 @@ + src/chgpasswd.c + src/chpasswd.c + src/chsh.c ++src/cppw.c + src/expiry.c + src/faillog.c + src/gpasswd.c diff --git a/debian/patches/402_cppw_selinux b/debian/patches/402_cppw_selinux new file mode 100644 index 0000000..5f2da1b --- /dev/null +++ b/debian/patches/402_cppw_selinux @@ -0,0 +1,64 @@ +Goal: Add selinux support to cppw + +Fix: + +Status wrt upstream: cppw is not available upstream. + The patch was made based on the + 302_vim_selinux_support patch. It needs to be + reviewed by an SE-Linux aware person. + +Depends on 401_cppw_src.dpatch + +Index: git/src/cppw.c +=================================================================== +--- git.orig/src/cppw.c ++++ git/src/cppw.c +@@ -34,6 +34,9 @@ + #include <sys/types.h> + #include <signal.h> + #include <utime.h> ++#ifdef WITH_SELINUX ++#include <selinux/selinux.h> ++#endif /* WITH_SELINUX */ + #include "exitcodes.h" + #include "prototypes.h" + #include "pwio.h" +@@ -139,6 +142,22 @@ + if (access (file, F_OK) != 0) { + cppwexit (file, 1, 1); + } ++#ifdef WITH_SELINUX ++ /* if SE Linux is enabled then set the context of all new files ++ * to be the context of the file we are editing */ ++ if (is_selinux_enabled () > 0) { ++ security_context_t passwd_context=NULL; ++ int ret = 0; ++ if (getfilecon (file, &passwd_context) < 0) { ++ cppwexit (_("Couldn't get file context"), errno, 1); ++ } ++ ret = setfscreatecon (passwd_context); ++ freecon (passwd_context); ++ if (0 != ret) { ++ cppwexit (_("setfscreatecon () failed"), errno, 1); ++ } ++ } ++#endif /* WITH_SELINUX */ + if (file_lock () == 0) { + cppwexit (_("Couldn't lock file"), 0, 5); + } +@@ -167,6 +186,15 @@ + cppwexit (NULL,0,1); + } + ++#ifdef WITH_SELINUX ++ /* unset the fscreatecon */ ++ if (is_selinux_enabled () > 0) { ++ if (setfscreatecon (NULL)) { ++ cppwexit (_("setfscreatecon() failed"), errno, 1); ++ } ++ } ++#endif /* WITH_SELINUX */ ++ + (*file_unlock) (); + } + diff --git a/debian/patches/429_login_FAILLOG_ENAB b/debian/patches/429_login_FAILLOG_ENAB new file mode 100644 index 0000000..d8e6034 --- /dev/null +++ b/debian/patches/429_login_FAILLOG_ENAB @@ -0,0 +1,84 @@ +Goal: Re-enable logging and displaying failures on login when login is + compiled with PAM and when FAILLOG_ENAB is set to yes. And create the + faillog file if it does not exist on postinst (as on Woody). +Depends: 008_login_more_LOG_UNKFAIL_ENAB +Fixes: #192849 + +Note: It could be removed if pam_tally could report the number of failures + preceding a successful login. + +--- a/src/login.c ++++ b/src/login.c +@@ -114,9 +114,9 @@ + #endif + ); + +-#ifndef USE_PAM + static struct faillog faillog; + ++#ifndef USE_PAM + static void bad_time_notify (void); + static void check_nologin (bool login_to_root); + #else +@@ -787,6 +787,9 @@ + SYSLOG ((LOG_NOTICE, + "TOO MANY LOGIN TRIES (%u)%s FOR '%s'", + failcount, fromhost, failent_user)); ++ if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) { ++ failure (pwd->pw_uid, tty, &faillog); ++ } + fprintf (stderr, + _("Maximum number of tries exceeded (%u)\n"), + failcount); +@@ -804,6 +807,14 @@ + pam_strerror (pamh, retcode))); + failed = true; + } ++ if ( (NULL != pwd) ++ && getdef_bool("FAILLOG_ENAB") ++ && ! failcheck (pwd->pw_uid, &faillog, failed)) { ++ SYSLOG((LOG_CRIT, ++ "exceeded failure limit for `%s' %s", ++ failent_user, fromhost)); ++ failed = 1; ++ } + + if (!failed) { + break; +@@ -827,6 +838,10 @@ + (void) puts (""); + (void) puts (_("Login incorrect")); + ++ if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) { ++ failure (pwd->pw_uid, tty, &faillog); ++ } ++ + if (getdef_str("FTMP_FILE") != NULL) { + #ifdef USE_UTMPX + struct utmpx *failent = +@@ -1295,6 +1310,7 @@ + */ + #ifndef USE_PAM + motd (); /* print the message of the day */ ++#endif + if ( getdef_bool ("FAILLOG_ENAB") + && (0 != faillog.fail_cnt)) { + failprint (&faillog); +@@ -1307,6 +1323,7 @@ + username, (int) faillog.fail_cnt)); + } + } ++#ifndef USE_PAM + if ( getdef_bool ("LASTLOG_ENAB") + && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL) + && (ll.ll_time != 0)) { +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -78,6 +78,7 @@ + {"ENV_SUPATH", NULL}, + {"ERASECHAR", NULL}, + {"FAIL_DELAY", NULL}, ++ {"FAILLOG_ENAB", NULL}, + {"FAKE_SHELL", NULL}, + {"FTMP_FILE", NULL}, + {"GID_MAX", NULL}, diff --git a/debian/patches/463_login_delay_obeys_to_PAM b/debian/patches/463_login_delay_obeys_to_PAM new file mode 100644 index 0000000..ab32c2a --- /dev/null +++ b/debian/patches/463_login_delay_obeys_to_PAM @@ -0,0 +1,97 @@ +Goal: Do not hardcode pam_fail_delay and let pam_unix do its + job to set a delay...or not + +Fixes: #87648 + +Status wrt upstream: Forwarded but not applied yet + +Note: If removed, FAIL_DELAY must be re-added to /etc/login.defs + +--- a/src/login.c ++++ b/src/login.c +@@ -512,7 +512,6 @@ + #if !defined(USE_PAM) + char ptime[80]; + #endif +- unsigned int delay; + unsigned int retries; + bool subroot = false; + #ifndef USE_PAM +@@ -537,6 +536,7 @@ + pid_t child; + char *pam_user = NULL; + #else ++ unsigned int delay; + struct spwd *spwd = NULL; + #endif + /* +@@ -701,7 +701,6 @@ + } + + environ = newenvp; /* make new environment active */ +- delay = getdef_unum ("FAIL_DELAY", 1); + retries = getdef_unum ("LOGIN_RETRIES", RETRIES); + + #ifdef USE_PAM +@@ -717,8 +716,7 @@ + + /* + * hostname & tty are either set to NULL or their correct values, +- * depending on how much we know. We also set PAM's fail delay to +- * ours. ++ * depending on how much we know. + * + * PAM_RHOST and PAM_TTY are used for authentication, only use + * information coming from login or from the caller (e.g. no utmp) +@@ -727,10 +725,6 @@ + PAM_FAIL_CHECK; + retcode = pam_set_item (pamh, PAM_TTY, tty); + PAM_FAIL_CHECK; +-#ifdef HAS_PAM_FAIL_DELAY +- retcode = pam_fail_delay (pamh, 1000000 * delay); +- PAM_FAIL_CHECK; +-#endif + /* if fflg, then the user has already been authenticated */ + if (!fflg) { + unsigned int failcount = 0; +@@ -771,12 +765,6 @@ + bool failed = false; + + failcount++; +-#ifdef HAS_PAM_FAIL_DELAY +- if (delay > 0) { +- retcode = pam_fail_delay(pamh, 1000000*delay); +- PAM_FAIL_CHECK; +- } +-#endif + + retcode = pam_authenticate (pamh, 0); + +@@ -1110,14 +1098,17 @@ + free (username); + username = NULL; + ++#ifndef USE_PAM + /* + * Wait a while (a la SVR4 /usr/bin/login) before attempting + * to login the user again. If the earlier alarm occurs + * before the sleep() below completes, login will exit. + */ ++ delay = getdef_unum ("FAIL_DELAY", 1); + if (delay > 0) { + (void) sleep (delay); + } ++#endif + + (void) puts (_("Login incorrect")); + +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -77,7 +77,6 @@ + {"ENV_PATH", NULL}, + {"ENV_SUPATH", NULL}, + {"ERASECHAR", NULL}, +- {"FAIL_DELAY", NULL}, + {"FAILLOG_ENAB", NULL}, + {"FAKE_SHELL", NULL}, + {"FTMP_FILE", NULL}, diff --git a/debian/patches/501_commonio_group_shadow b/debian/patches/501_commonio_group_shadow new file mode 100644 index 0000000..cfdf10c --- /dev/null +++ b/debian/patches/501_commonio_group_shadow @@ -0,0 +1,60 @@ +Goal: save the [g]shadow files with the 'shadow' group and mode 0440 + +Fixes: #166793 + +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -21,6 +21,7 @@ + #include <errno.h> + #include <stdio.h> + #include <signal.h> ++#include <grp.h> + #include "nscd.h" + #include "sssd.h" + #ifdef WITH_TCB +@@ -970,12 +971,23 @@ + goto fail; + } + } else { ++ struct group *grp; + /* + * Default permissions for new [g]shadow files. + */ + sb.st_mode = db->st_mode; + sb.st_uid = db->st_uid; + sb.st_gid = db->st_gid; ++ ++ /* ++ * Try to retrieve the shadow's GID, and fall back to GID 0. ++ */ ++ if (sb.st_gid == 0) { ++ if ((grp = getgrnam("shadow")) != NULL) ++ sb.st_gid = grp->gr_gid; ++ else ++ sb.st_gid = 0; ++ } + } + + snprintf (buf, sizeof buf, "%s+", db->filename); +--- a/lib/sgroupio.c ++++ b/lib/sgroupio.c +@@ -206,7 +206,7 @@ + #ifdef WITH_SELINUX + NULL, /* scontext */ + #endif +- 0400, /* st_mode */ ++ 0440, /* st_mode */ + 0, /* st_uid */ + 0, /* st_gid */ + NULL, /* head */ +--- a/lib/shadowio.c ++++ b/lib/shadowio.c +@@ -84,7 +84,7 @@ + #ifdef WITH_SELINUX + NULL, /* scontext */ + #endif /* WITH_SELINUX */ +- 0400, /* st_mode */ ++ 0440, /* st_mode */ + 0, /* st_uid */ + 0, /* st_gid */ + NULL, /* head */ diff --git a/debian/patches/502_debian_useradd_defaults b/debian/patches/502_debian_useradd_defaults new file mode 100644 index 0000000..6317ed6 --- /dev/null +++ b/debian/patches/502_debian_useradd_defaults @@ -0,0 +1,41 @@ +From: Balint Reczey <balint@balintreczey.hu> +Description: Keep using Debian's adduser defaults + Upstream's bbf4b79bc49fd1826eb41f6629669ef0b647267b commit + in 4.9 merged those values from upstream's default configuration file + which is not shipped in Debian. + This patch keeps the program's compiled in defaults in sync with the + configuration files shipped in Debian (debian/default/useradd). +Bug: https://github.com/shadow-maint/shadow/issues/501 +Bug-Debian: https://bugs.debian.org/1004710 +Forwarded: not-needed + +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -79,12 +79,12 @@ + /* + * These defaults are used if there is no defaults file. + */ +-static gid_t def_group = 1000; ++static gid_t def_group = 100; + static const char *def_gname = "other"; + static const char *def_home = "/home"; + static const char *def_shell = "/bin/bash"; + static const char *def_template = SKEL_DIR; +-static const char *def_create_mail_spool = "yes"; ++static const char *def_create_mail_spool = "no"; + static const char *def_log_init = "yes"; + + static long def_inactive = -1; +diff --git a/man/useradd.8.xml b/man/useradd.8.xml +index af02a23f..c7f95b47 100644 +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -248,7 +248,7 @@ + command line), useradd will set the primary group of the new + user to the value specified by the <option>GROUP</option> + variable in <filename>/etc/default/useradd</filename>, or +- 1000 by default. ++ 100 by default. + </para> + </listitem> + </varlistentry> diff --git a/debian/patches/503_shadowconfig.8 b/debian/patches/503_shadowconfig.8 new file mode 100644 index 0000000..0f0d339 --- /dev/null +++ b/debian/patches/503_shadowconfig.8 @@ -0,0 +1,201 @@ +Goal: Document the shadowconfig utility + +Status wrt upstream: The shadowconfig utility is debian specific. + Its man page also (but it used to be distributed) + +Index: git/man/shadowconfig.8 +=================================================================== +--- /dev/null ++++ git/man/shadowconfig.8 +@@ -0,0 +1,41 @@ ++.\"Generated by db2man.xsl. Don't modify this, modify the source. ++.de Sh \" Subsection ++.br ++.if t .Sp ++.ne 5 ++.PP ++\fB\\$1\fR ++.PP ++.. ++.de Sp \" Vertical space (when we can't use .PP) ++.if t .sp .5v ++.if n .sp ++.. ++.de Ip \" List item ++.br ++.ie \\n(.$>=3 .ne \\$3 ++.el .ne 3 ++.IP "\\$1" \\$2 ++.. ++.TH "SHADOWCONFIG" 8 "19 Apr 1997" "" "" ++.SH NAME ++shadowconfig \- toggle shadow passwords on and off ++.SH "SYNOPSIS" ++.ad l ++.hy 0 ++.HP 13 ++\fBshadowconfig\fR \fB\fIon\fR\fR | \fB\fIoff\fR\fR ++.ad ++.hy ++ ++.SH "DESCRIPTION" ++ ++.PP ++\fBshadowconfig\fR on will turn shadow passwords on; \fIshadowconfig off\fR will turn shadow passwords off\&. \fBshadowconfig\fR will print an error message and exit with a nonzero code if it finds anything awry\&. If that happens, you should correct the error and run it again\&. Turning shadow passwords on when they are already on, or off when they are already off, is harmless\&. ++ ++.PP ++Read \fI/usr/share/doc/passwd/README\&.Debian\fR for a brief introduction to shadow passwords and related features\&. ++ ++.PP ++Note that turning shadow passwords off and on again will lose all password aging information\&. ++ +Index: git/man/shadowconfig.8.xml +=================================================================== +--- /dev/null ++++ git/man/shadowconfig.8.xml +@@ -0,0 +1,52 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" ++ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> ++<refentry id='shadowconfig.8'> ++ <!-- $Id: shadowconfig.8.xml,v 1.6 2005/06/15 12:39:27 kloczek Exp $ --> ++ <refentryinfo> ++ <date>19 Apr 1997</date> ++ </refentryinfo> ++ <refmeta> ++ <refentrytitle>shadowconfig</refentrytitle> ++ <manvolnum>8</manvolnum> ++ <refmiscinfo class='date'>19 Apr 1997</refmiscinfo> ++ <refmiscinfo class='source'>Debian GNU/Linux</refmiscinfo> ++ </refmeta> ++ <refnamediv id='name'> ++ <refname>shadowconfig</refname> ++ <refpurpose>toggle shadow passwords on and off</refpurpose> ++ </refnamediv> ++ ++ <refsynopsisdiv id='synopsis'> ++ <cmdsynopsis> ++ <command>shadowconfig</command> ++ <group choice='plain'> ++ <arg choice='plain'><replaceable>on</replaceable></arg> ++ <arg choice='plain'><replaceable>off</replaceable></arg> ++ </group> ++ </cmdsynopsis> ++ </refsynopsisdiv> ++ ++ <refsect1 id='description'> ++ <title>DESCRIPTION</title> ++ <para><command>shadowconfig</command> on will turn shadow passwords on; ++ <emphasis remap='B'>shadowconfig off</emphasis> will turn shadow ++ passwords off. <command>shadowconfig</command> will print an error ++ message and exit with a nonzero code if it finds anything awry. If ++ that happens, you should correct the error and run it again. Turning ++ shadow passwords on when they are already on, or off when they are ++ already off, is harmless. ++ </para> ++ ++ <para> ++ Read <filename>/usr/share/doc/passwd/README.Debian</filename> for a ++ brief introduction ++ to shadow passwords and related features. ++ </para> ++ ++ <para>Note that turning shadow passwords off and on again will lose all ++ password ++ aging information. ++ </para> ++ </refsect1> ++</refentry> +Index: git/man/fr/shadowconfig.8 +=================================================================== +--- /dev/null ++++ git/man/fr/shadowconfig.8 +@@ -0,0 +1,26 @@ ++.\" This file was generated with po4a. Translate the source file. ++.\" ++.\"$Id: shadowconfig.8,v 1.4 2001/08/23 23:10:48 kloczek Exp $ ++.TH SHADOWCONFIG 8 "19 avril 1997" "Debian GNU/Linux" ++.SH NOM ++shadowconfig \- active ou désactive les mots de passe cachés ++.SH SYNOPSIS ++\fBshadowconfig\fP \fIon\fP | \fIoff\fP ++.SH DESCRIPTION ++.PP ++\fBshadowconfig on\fP active les mots de passe cachés («\ shadow passwords\ »)\ ; \fBshadowconfig off\fP les désactive. \fBShadowconfig\fP affiche un message ++d'erreur et quitte avec une valeur de retour non nulle s'il rencontre ++quelque chose d'inattendu. Dans ce cas, vous devrez corriger l'erreur avant ++de recommencer. ++ ++Activer les mots de passe cachés lorsqu'ils sont déjà activés, ou les ++désactiver lorsqu'ils ne sont pas actifs est sans effet. ++ ++Lisez \fI/usr/share/doc/passwd/README.Debian\fP pour une brève introduction aux ++mots de passe cachés et à leurs fonctionnalités. ++ ++Notez que désactiver puis réactiver les mots de passe cachés aura pour ++conséquence la perte des informations d'âge sur les mots de passe. ++.SH TRADUCTION ++Nicolas FRANÇOIS, 2004. ++Veuillez signaler toute erreur à <\fIdebian\-l10\-french@lists.debian.org\fR>. +Index: git/man/ja/shadowconfig.8 +=================================================================== +--- /dev/null ++++ git/man/ja/shadowconfig.8 +@@ -0,0 +1,25 @@ ++.\" all right reserved, ++.\" Translated Tue Oct 30 11:59:11 JST 2001 ++.\" by Maki KURODA <mkuroda@aisys-jp.com> ++.\" ++.TH SHADOWCONFIG 8 "19 Apr 1997" "Debian GNU/Linux" ++.SH 名前 ++shadowconfig \- shadow パスワードの設定をオン及びオフに切替える ++.SH 書式 ++.B "shadowconfig" ++.IR on " | " off ++.SH 説明 ++.PP ++.B shadowconfig on ++は shadow パスワードを有効にする。 ++.B shadowconfig off ++は shadow パスワードを無効にする。 ++.B shadowconfig ++は何らかの間違いがあると、エラーメッセージを表示し、 ++ゼロではない返り値を返す。 ++もしそのようなことが起こった場合、エラーを修正し、再度実行しなければならない。 ++shadow パスワードの設定がすでにオンの場合にオンに設定したり、 ++すでにオフの場合にオフに設定しても、何の影響もない。 ++ ++.I /usr/share/doc/passwd/README.debian.gz ++には shadow パスワードとそれに関する特徴の簡単な紹介が書かれている。 +Index: git/man/pl/shadowconfig.8 +=================================================================== +--- /dev/null ++++ git/man/pl/shadowconfig.8 +@@ -0,0 +1,27 @@ ++.\" $Id: shadowconfig.8,v 1.3 2001/08/23 23:10:51 kloczek Exp $ ++.\" {PTM/WK/1999-09-14} ++.TH SHADOWCONFIG 8 "19 kwietnia 1997" "Debian GNU/Linux" ++.SH NAZWA ++shadowconfig - przełącza ochronę haseł i grup przez pliki shadow ++.SH SKŁADNIA ++.B "shadowconfig" ++.IR on " | " off ++.SH OPIS ++.PP ++.B shadowconfig on ++włącza ochronę haseł i grup przez dodatkowe, przesłaniane pliki (shadow); ++.B shadowconfig off ++wyłącza dodatkowe pliki haseł i grup. ++.B shadowconfig ++wyświetla komunikat o błędzie i kończy pracę z niezerowym kodem jeśli ++znajdzie coś nieprawidłowego. W takim wypadku powinieneś poprawić błąd ++.\" if it finds anything awry. ++i uruchomić program ponownie. ++ ++Włączenie ochrony haseł, gdy jest ona już włączona lub jej wyłączenie, ++gdy jest wyłączona jest nieszkodliwe. ++ ++Przeczytaj ++.IR /usr/share/doc/passwd/README.debian.gz , ++gdzie znajdziesz krótkie wprowadzenie do ochrony haseł z użyciem dodatkowych ++plików haseł przesłanianych (shadow passwords) i związanych tematów. diff --git a/debian/patches/505_useradd_recommend_adduser b/debian/patches/505_useradd_recommend_adduser new file mode 100644 index 0000000..9fb3fe3 --- /dev/null +++ b/debian/patches/505_useradd_recommend_adduser @@ -0,0 +1,36 @@ +Goal: Recommend using adduser and deluser. + +Fixes: #406046 + +Status wrt upstream: Debian specific patch. + +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -83,6 +83,12 @@ + <refsect1 id='description'> + <title>DESCRIPTION</title> + <para> ++ <command>useradd</command> is a low level utility for adding ++ users. On Debian, administrators should usually use ++ <citerefentry><refentrytitle>adduser</refentrytitle> ++ <manvolnum>8</manvolnum></citerefentry> instead. ++ </para> ++ <para> + When invoked without the <option>-D</option> option, the + <command>useradd</command> command creates a new user account using + the values specified on the command line plus the default values from +--- a/man/userdel.8.xml ++++ b/man/userdel.8.xml +@@ -59,6 +59,12 @@ + <refsect1 id='description'> + <title>DESCRIPTION</title> + <para> ++ <command>userdel</command> is a low level utility for removing ++ users. On Debian, administrators should usually use ++ <citerefentry><refentrytitle>deluser</refentrytitle> ++ <manvolnum>8</manvolnum></citerefentry> instead. ++ </para> ++ <para> + The <command>userdel</command> command modifies the system account + files, deleting all entries that refer to the user name <emphasis + remap='I'>LOGIN</emphasis>. The named user must exist. diff --git a/debian/patches/506_relaxed_usernames b/debian/patches/506_relaxed_usernames new file mode 100644 index 0000000..0e066d9 --- /dev/null +++ b/debian/patches/506_relaxed_usernames @@ -0,0 +1,111 @@ +Goal: Relaxed usernames/groupnames checking patch. + +Status wrt upstream: Debian specific. Not to be used upstream + +Details: + Allows any non-empty user/grounames that don't contain ':', ',' or '\n' + characters and don't start with '-', '+', or '~'. This patch is more + restrictive than original Karl's version. closes: #264879 + Also closes: #377844 + + Comments from Karl Ramm (shadow 1:4.0.3-9, 20 Aug 2003 02:06:50 -0400): + + I can't come up with a good justification as to why characters other + than ':'s and '\0's should be disallowed in group and usernames (other + than '-' as the leading character). Thus, the maintenance tools don't + anymore. closes: #79682, #166798, #171179 + +--- a/libmisc/chkname.c ++++ b/libmisc/chkname.c +@@ -32,44 +32,26 @@ + } + + /* +- * User/group names must match gnu e-regex: +- * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]? +- * +- * as a non-POSIX, extension, allow "$" as the last char for +- * sake of Samba 3.x "add machine script" +- * +- * Also do not allow fully numeric names or just "." or "..". +- */ +- int numeric; +- +- if ('\0' == *name || +- ('.' == *name && (('.' == name[1] && '\0' == name[2]) || +- '\0' == name[1])) || +- !((*name >= 'a' && *name <= 'z') || +- (*name >= 'A' && *name <= 'Z') || +- (*name >= '0' && *name <= '9') || +- *name == '_' || +- *name == '.')) { ++ * POSIX indicate that usernames are composed of characters from the ++ * portable filename character set [A-Za-z0-9._-], and that the hyphen ++ * should not be used as the first character of a portable user name. ++ * ++ * Allow more relaxed user/group names in Debian -- ^[^-~+:,\s][^:,\s]*$ ++ */ ++ if ( ('\0' == *name) ++ || ('-' == *name) ++ || ('~' == *name) ++ || ('+' == *name)) { + return false; + } +- +- numeric = isdigit(*name); +- +- while ('\0' != *++name) { +- if (!((*name >= 'a' && *name <= 'z') || +- (*name >= 'A' && *name <= 'Z') || +- (*name >= '0' && *name <= '9') || +- *name == '_' || +- *name == '.' || +- *name == '-' || +- (*name == '$' && name[1] == '\0') +- )) { ++ do { ++ if ((':' == *name) || (',' == *name) || isspace(*name)) { + return false; + } +- numeric &= isdigit(*name); +- } ++ name++; ++ } while ('\0' != *name); + +- return !numeric; ++ return true; + } + + bool is_valid_user_name (const char *name) +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -708,6 +708,14 @@ + the <command>ls</command> output. + </para> + <para> ++ On Debian, the only constraints are that usernames must neither start ++ with a dash ('-') nor plus ('+') nor tilde ('~') nor contain a ++ colon (':'), a comma (','), or a whitespace (space: ' ', ++ end of line: '\n', tabulation: '\t', etc.). Note that using a slash ++ ('/') may break the default algorithm for the definition of the ++ user's home directory. ++ </para> ++ <para> + Usernames may only be up to 32 characters long. + </para> + </refsect1> +--- a/man/groupadd.8.xml ++++ b/man/groupadd.8.xml +@@ -72,6 +72,12 @@ + also disallowed. + </para> + <para> ++ On Debian, the only constraints are that groupnames must neither start ++ with a dash ('-') nor plus ('+') nor tilde ('~') nor contain a ++ colon (':'), a comma (','), or a whitespace (space:' ', ++ end of line: '\n', tabulation: '\t', etc.). ++ </para> ++ <para> + Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. + </para> + </refsect1> diff --git a/debian/patches/542_useradd-O_option b/debian/patches/542_useradd-O_option new file mode 100644 index 0000000..3745826 --- /dev/null +++ b/debian/patches/542_useradd-O_option @@ -0,0 +1,40 @@ +Goal: accepts the -O flag for backward compatibility. (was used by adduser?) + +Note: useradd.8 needs to be regenerated. + +Status wrt upstream: not included as this is just specific + backward compatibility for Debian + +--- a/man/useradd.8.xml ++++ b/man/useradd.8.xml +@@ -326,6 +326,11 @@ + =<replaceable>100</replaceable> <option>-K</option> + <replaceable>UID_MAX</replaceable>=<replaceable>499</replaceable> + </para> ++ <para> ++ For the compatibility with previous Debian's ++ <command>useradd</command>, the <option>-O</option> option is ++ also supported. ++ </para> + <!--para> + Note: <option>-K</option> <replaceable>UID_MIN</replaceable>=<replaceable>10</replaceable>,<replaceable>UID_MAX</replaceable>=<replaceable>499</replaceable> + doesn't work yet. +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1227,7 +1227,7 @@ + {NULL, 0, NULL, '\0'} + }; + while ((c = getopt_long (argc, argv, +- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U" ++ "b:c:d:De:f:g:G:hk:O:K:lmMNop:rR:P:s:u:U" + #ifdef WITH_SELINUX + "Z:" + #endif /* WITH_SELINUX */ +@@ -1367,6 +1367,7 @@ + kflg = true; + break; + case 'K': ++ case 'O': /* compatibility with previous Debian useradd */ + /* + * override login.defs defaults (-K name=value) + * example: -K UID_MIN=100 -K UID_MAX=499 diff --git a/debian/patches/900_testsuite_groupmems b/debian/patches/900_testsuite_groupmems new file mode 100644 index 0000000..6bdc497 --- /dev/null +++ b/debian/patches/900_testsuite_groupmems @@ -0,0 +1,81 @@ +--- a/debian/passwd.install ++++ b/debian/passwd.install +@@ -9,6 +9,7 @@ + usr/sbin/cppw + usr/sbin/groupadd + usr/sbin/groupdel ++usr/sbin/groupmems + usr/sbin/groupmod + usr/sbin/grpck + usr/sbin/grpconv +@@ -33,6 +34,7 @@ + usr/share/man/*/man8/chpasswd.8 + usr/share/man/*/man8/groupadd.8 + usr/share/man/*/man8/groupdel.8 ++usr/share/man/*/man8/groupmems.8 + usr/share/man/*/man8/groupmod.8 + usr/share/man/*/man8/grpck.8 + usr/share/man/*/man8/grpconv.8 +@@ -59,6 +61,7 @@ + usr/share/man/man8/chpasswd.8 + usr/share/man/man8/groupadd.8 + usr/share/man/man8/groupdel.8 ++usr/share/man/man8/groupmems.8 + usr/share/man/man8/groupmod.8 + usr/share/man/man8/grpck.8 + usr/share/man/man8/grpconv.8 +--- a/debian/passwd.postinst ++++ b/debian/passwd.postinst +@@ -31,6 +31,24 @@ + exit 1 + ) + fi ++ if ! getent group groupmems | grep -q '^groupmems:[^:]*:99' ++ then ++ groupadd -g 99 groupmems || ( ++ cat <<EOF ++************************ TESTSUITE ***************************** ++Group ID 99 has been allocated for the groupmems group. You have either ++used 99 yourself or created a groupmems group with a different ID. ++Please correct this problem and reconfigure with ``dpkg --configure passwd''. ++ ++Note that both user and group IDs in the range 0-99 are globally ++allocated by the Debian project and must be the same on every Debian ++system. ++EOF ++ exit 1 ++ ) ++# FIXME ++ chgrp groupmems /usr/sbin/groupmems ++ fi + ;; + esac + +--- a/debian/rules ++++ b/debian/rules +@@ -60,6 +60,7 @@ + dh_installpam -p passwd --name=chsh + dh_installpam -p passwd --name=chpasswd + dh_installpam -p passwd --name=newusers ++ dh_installpam -p passwd --name=groupmems + ifeq ($(DEB_HOST_ARCH_OS),hurd) + # login is not built on The Hurd, but some utilities of passwd depends on + # /etc/login.defs. +@@ -87,3 +88,6 @@ + chgrp shadow debian/passwd/usr/bin/expiry + chmod g+s debian/passwd/usr/bin/chage + chmod g+s debian/passwd/usr/bin/expiry ++ chgrp groupmems debian/passwd/usr/sbin/groupmems ++ chmod u+s debian/passwd/usr/sbin/groupmems ++ chmod o-x debian/passwd/usr/sbin/groupmems +--- /dev/null ++++ b/debian/passwd.groupmems.pam +@@ -0,0 +1,8 @@ ++# The PAM configuration file for the Shadow 'groupmod' service ++# ++ ++# This allows root to modify groups without being prompted for a password ++auth sufficient pam_rootok.so ++ ++@include common-auth ++@include common-account diff --git a/debian/patches/901_testsuite_gcov b/debian/patches/901_testsuite_gcov new file mode 100644 index 0000000..717ccca --- /dev/null +++ b/debian/patches/901_testsuite_gcov @@ -0,0 +1,76 @@ +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -1,6 +1,8 @@ + + AUTOMAKE_OPTIONS = 1.0 foreign + ++CFLAGS += -fprofile-arcs -ftest-coverage ++ + DEFS = + + noinst_LTLIBRARIES = libshadow.la +--- a/libmisc/Makefile.am ++++ b/libmisc/Makefile.am +@@ -1,6 +1,8 @@ + + EXTRA_DIST = .indent.pro xgetXXbyYY.c + ++CFLAGS += -fprofile-arcs -ftest-coverage ++ + INCLUDES = -I$(top_srcdir)/lib + + noinst_LIBRARIES = libmisc.a +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -7,6 +7,8 @@ + suidperms = 4755 + sgidperms = 2755 + ++CFLAGS += -fprofile-arcs -ftest-coverage ++ + INCLUDES = \ + -I${top_srcdir}/lib \ + -I$(top_srcdir)/libmisc +--- a/debian/rules ++++ b/debian/rules +@@ -40,6 +40,12 @@ + endif + export CFLAGS + ++clean:: clean_gcov ++ ++clean_gcov: ++ find . -name "*.gcda" -delete ++ find . -name "*.gcno" -delete ++ + # Add extras to the install process: + binary-install/login:: + dh_installpam -p login +--- a/lib/defines.h ++++ b/lib/defines.h +@@ -174,23 +174,9 @@ + trust the formatted time received from the unix domain (or worse, + UDP) socket. -MM */ + /* Avoid translated PAM error messages: Set LC_ALL to "C". ++ * This is disabled for coverage testing + * --Nekral */ +-#define SYSLOG(x) \ +- do { \ +- char *old_locale = setlocale (LC_ALL, NULL); \ +- char *saved_locale = NULL; \ +- if (NULL != old_locale) { \ +- saved_locale = strdup (old_locale); \ +- } \ +- if (NULL != saved_locale) { \ +- (void) setlocale (LC_ALL, "C"); \ +- } \ +- syslog x ; \ +- if (NULL != saved_locale) { \ +- (void) setlocale (LC_ALL, saved_locale); \ +- free (saved_locale); \ +- } \ +- } while (false) ++#define SYSLOG(x) syslog x + #else /* !ENABLE_NLS */ + #define SYSLOG(x) syslog x + #endif /* !ENABLE_NLS */ diff --git a/debian/patches/README.patches b/debian/patches/README.patches new file mode 100644 index 0000000..a804fe3 --- /dev/null +++ b/debian/patches/README.patches @@ -0,0 +1,22 @@ +Small intro to the system for numbering the patches here... + +-The 00xx-... patches are forwarded to upstream's git repository + +-The 0xx_... series of patches are patches isolated from the latest + version of the shadow Debian package not using quilt in order to + separate upstream from Debian-specific stuff. + + NO MORE PATCHES SHOULD BE ADDED IN THESE SERIES + +-The 4xx series are patches which have been applied to Debian's shadow + and have NOT been accepted and/or applied upstream. These patches MUST be kept + even after resynced with upstream + +-The 5xx series are patches which are applied to Debian's shadow + and will never be proposed upstream because they're too specific + This list SHOULD BE AS SHORT AS POSSIBLE + +In short, while we are working towards synchronisation with upstream, +our goal is to make 0xx patches disappear by moving them either to 3xx +series (things already implemented upstream) or to 4xx series +(Debian-specific patches). diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..ba058e0 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,23 @@ +# CVE-2023-4641 +0001-gpasswd-1-Fix-password-leak.patch + +# CVE-2023-29383 +0002-Added-control-character-check.patch +0003-Overhaul-valid_field.patch + +# These patches are only for the testsuite: +#900_testsuite_groupmems +#901_testsuite_gcov + +008_login_log_failure_in_FTMP +401_cppw_src.dpatch +# 402 should be merged in 401, but should be reviewed by SE Linux experts first +402_cppw_selinux +429_login_FAILLOG_ENAB +463_login_delay_obeys_to_PAM +501_commonio_group_shadow +502_debian_useradd_defaults +503_shadowconfig.8 +505_useradd_recommend_adduser +506_relaxed_usernames +542_useradd-O_option |