Releases: shadow-maint/shadow
4.19.0: Herve
Release 4.19.0
Breaking changes:
-
Remove support for escaped newlines in configuration files.
It never worked correctly.
b0a7ce5 (2025-12-05; "lib/, po/: Remove fgetsx() and fputsx()") -
Some user names and group names are too dangerous and are rejected,
even with --badname.
25aea74 (2025-12-25; "lib/chkname.c, src/: Strictly disallow really bad names")
Future breaking changes:
- SHA512 and SHA256 will be supported unconditionally in the next
release. The build-time flag '--with-sha-crypt' will be removed.
See #1452.
Support:
-
Several years ago, there were talks about deprecating su(1) and
login(1), back when this project was maintained as part of Debian.
However, nothing was clearly stated, and there were doubts about the
status of these programs. Let's clarify them now.Our implementations of su(1) and login(1) are fully supported, and we
don't have any plans to remove them. They are NOT deprecated.
See #464.
Deprecations:
-
groupmems(8)
The program will be removed in a future release.
See #1343. -
logoutd(8)
The program will be removed in the next release.
See #999,
and #1344. -
DES
This hashing algorithm has been deprecated for a long time,
and support for it will be removed in a future release.
See #1456 -
MD5
This hashing algorithm has been deprecated for a long time,
and support for it will be removed in a future release.
See #1457 -
login.defs(5): MD_CRYPT_ENAB
This feature had been deprecated for decades. It will be
removed in a future release.
The command-line equivalents (-m, --md5) of this feature in
chpasswd(8) and chgpasswd(8) will also be removed in a future
release.
See #1455. -
login.defs(5): PASS_MAX_LEN
This feature is ignored except for DES. Once DES is removed,
it makes no sense keeping it. It may be removed in a future
release. -
Password aging
Scientific research shows that periodic password expiration
leads to predictable password patterns, and that even in a
theoretical scenario where that wouldn't happen the gains in
security are mathematically negligible.
https://people.scs.carleton.ca/~paulv/papers/expiration-authorcopy.pdfModern security standards, such as NIST SP 800-63B-4 in the USA,
prohibit periodic password expiration.
https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver
https://pages.nist.gov/800-63-FAQ/#q-b05
https://www.ncsc.gov.uk/collection/passwords/updating-your-approach#PasswordGuidance:UpdatingYourApproach-Don'tenforceregularpasswordexpiryTo align with these, we're deprecating the ability to
periodically expire passwords. The specifics and long-term
roadmap are currently being discussed, and we invite feedback
from users, particularly from those in regulated environments.
See #1432.This deprecation includes the following programs and features:
expiry(1) chage(1): -I,--inactive (also the interactive version) -m,--mindays (also the interactive version) -M,--maxdays (also the interactive version) -W,--warndays (also the interactive version) passwd(1): -k,--keep-tokens -n,--mindays -x,--maxdays -i,--inactive -w,--warndays useradd(8): -f,--inactive usermod(8): -f,--inactive login.defs(5): PASS_MIN_DAYS PASS_MAX_DAYS PASS_WARN_AGE /etc/default/useradd: INACTIVE shadow(5): sp_lstchg: Restrict to just the values 0 and empty. sp_min sp_max sp_warn sp_inactWe recognize that many users operate in environments with
regulatory or contractual requirements that still mandate
password aging. To minimize disruption, these features will
remain functional for a significant period. However, we
encourage administrators to review their internal policies,
talk to their regulators if appropriate, and participate in the
roadmap discussion linked above.
herve rc1
What's Changed
- tests/unit/test_xaprintf.c: Fix test by using streq() instead of strcmp(3) by @alejandro-colomar in #1280
- login: fixed PID matching when PAM (and forking) used by @Karlson2k in #1282
- */: Fix including <config.h> as system header by @Karlson2k in #1294
- lib/shadow/grp/: agetgroups(): Fix possible buffer overrun on non-Linux systems by @alejandro-colomar in #1295
- lib/utmp.c: Fixed generated strings for "ut_id" by @Karlson2k in #1301
- Fix fprintf(3)-related issues. by @alejandro-colomar in #1299
- lib/utmp.c: align generated "ut_id" with other software by @Karlson2k in #1293
- Fixes related to use of forked PID by @Karlson2k in #1305
- fixes for configure and autotools by @Karlson2k in #1287
- chpasswd: Check hash before write when using -e by @mmpx12 in #1285
- Disable building subids support on systems that don't have the prctl by @sthibaul in #1269
- Make sure that logind is enabled if requested, make --disable-logind mandatory to disable logind integration by @Karlson2k in #1318
- src/groupmod.c: --help: wfix by @alejandro-colomar in #1316
- Correct finding UTMP entry by @Karlson2k in #1292
- While-loop readability improvements. by @alejandro-colomar in #1303
- lib/agetpass.c: Pass "" instead of NULL as an ignored prompt by @alejandro-colomar in #1321
- Make parsing of gecos field more robust and strict by @alejandro-colomar in #1307
- lib/utmp.c: Fix use of last utmp entry instead of patrial-match entry by @Karlson2k in #1326
- Fixed memory leak in UTMP processing by @Karlson2k in #1332
- share/ansible/: fix Debian 13 build by @ikerexxe in #1337
- lib/subordinateio.c: list_owner_ranges(): Fix duplicate range when username matches ID by @alejandro-colomar in #1345
- man/chsh: remove duplicate paragraph by @tacerus in #1342
- CI: add Python linter by @ikerexxe in #1349
- src/su.c: Fix incorrect (non-matching) parentheses by @alejandro-colomar in #1353
- Subid v3 by @AndersBlomdell in #1351
- Use available libc macros for paths, instead of creating our own. by @alejandro-colomar in #1355
- lib/, src/: Use consistent style using strchr(3) in conditionals by @alejandro-colomar in #1048
- lib/string/README: Add guidelines for using strings by @alejandro-colomar in #1338
- po/nl.po: Update by @alejandro-colomar in #1365
- A couple of patches around SSSD integration by @alexey-tikhonov in #1366
- Move shadow APIs to lib/shadow/ by @alejandro-colomar in #1197
- No news is good news by @alejandro-colomar in #1371
- src/useradd.c: chroot or prefix SELinux file context by @ikerexxe in #1258
- lib/commonio.c: Rename structure members that look like libc APIs by @alejandro-colomar in #1324
- Add STRNEQ(), and use it instead of its pattern by @alejandro-colomar in #1336
- X by @alejandro-colomar in #1263
- lib/utmp.c: is_my_tty(): Simplify by @alejandro-colomar in #1376
- Add strerrno(), and use it instead of its pattern by @alejandro-colomar in #1375
- [dd] Remove dead code by @alejandro-colomar in #1271
- tests/unit/test_exit_if_null.c: Test through XMALLOC() instead of xaprintf() by @alejandro-colomar in #1384
- clarify -U option in groupadd help output by @ashgit23 in #1389
- useradd: Do not automatically add supplements groups for system users by @SgAkErRu in #1156
- a2i(): Maximal minimalism by @alejandro-colomar in #1372
- Improve Clang support (regarding attributes) by @alejandro-colomar in #1320
- Rename array macro wrappers with an _a suffix instead of uppercase by @alejandro-colomar in #1373
- lib/string/: strerrno(): Use statement expression to perform lvalue conversion by @alejandro-colomar in #1390
- doc/contributions/: enhance Python test framework by @ikerexxe in #1348
- Minor improvements around fgets(3) calls by @alejandro-colomar in #1386
- tests/unit/: Small improvements by @alejandro-colomar in #1383
- Use a simpler interface for append_range(), based on reallocf(3) by @alejandro-colomar in #1356
- lib/: Use simple assignment instead of memcpy(3) by @alejandro-colomar in #1309
- configure.ac: Propagate ./configure flags to 'distcheck' by @alejandro-colomar in #1319
- src/usermod.c: $user_home: Remove all trailing '/'s by @alejandro-colomar in #1370
- Use const correctly. by @alejandro-colomar in #1393
- useradd: fix uninitialized flags causing aarch64 failure by @ikerexxe in #1396
- Update po and potfiles by @hallyn in #1399
- src/: Fix uninitialized flags, and use const appropriately by @alejandro-colomar in #1400
- Add typeas() and use it by @alejandro-colomar in #1395
- newusers: allow not passing a password by @terceiro in #1341
- Turn some -Wunused-* diagnostics into errors, and solve them by @alejandro-colomar in #1394
- Expand system test framework by @ikerexxe in #1340
- Replace fgetsx() by fgets(3) and fputsx() by fputs(3) by @alejandro-colomar in #1056
- Some improvements to type-safe macros by @alejandro-colomar in #1388
- rmdir_leading() improvements by @alejandro-colomar in #1135
- (pre-)Release 4.19.0-rc1 by @hallyn in #1411
New Contributors
- @Karlson2k made their first contribution in #1282
- @mmpx12 made their first contribution in #1285
- @tacerus made their first contribution in #1342
- @AndersBlomdell made their first contribution in #1351
- @alexey-tikhonov made their first contribution in #1366
- @ashgit23 made their first contribution in #1389
- @terceiro made their first contribution in #1341
Full Changelog: 4.18.0...4.19.0-rc1
4.18.0: Gorgonzola
What's Changed
- CI: purge man-db by @ikerexxe in #1241
- passwd: document exit code when PAM has errored by @hallyn in #1244
- Man patches by @zeha in #1175
- Quick fix: define E_PAM_ERR in lib/pam_pass.c by @hallyn in #1245
- Accept /usr/sbin/nologin as an alternate to /sbin/nologin by @zeha in #1246
- Add LOGIN_ENV_SAFELIST to FOREIGNDEFS by @stanislav-brabec in #1248
- ci: add
gawkas a fedora dependency by @ikerexxe in #1252 - man/useradd.8.xml: fix the CREATE_HOME description by @hallyn in #1251
- lib/getdate.y: Restrict the date formats that we support by @alejandro-colomar in #1238
- newuidmap: better error logging on failure by @matthewhughes934 in #1254
- Extend basic test cases to check shadow and gshadow entries by @ikerexxe in #1237
- lib/sizeof.h: Make sure STRLEN() only accepts string literals by @alejandro-colomar in #1260
- Add strprefix(), and use it instead of its pattern by @alejandro-colomar in #1152
- src/: Simplify, using strpbrk(3) by @alejandro-colomar in #1167
- lib/string/strdup/: STRNDUPA(): Reimplement in terms of strndupa(3) by @alejandro-colomar in #1189
- Remove dead beef by @alejandro-colomar in #1230
- lib/atoi/a2i/: Simplify these macros by calling a2i() by @alejandro-colomar in #1137
- strtolower(): Add API, and use it instead of its pattern by @alejandro-colomar in #1211
- lib/: sget*ent(): Simplify by calling strdup(3) by @alejandro-colomar in #1146
- fields by @alejandro-colomar in #1150
- yacc(1) is a dead language; bury it deep in the ground by @alejandro-colomar in #1217
- Test expiration date by @ikerexxe in #1233
- [scp] Add strcaseprefix(), and use it instead of its pattern by @alejandro-colomar in #1262
- valid_field(): Improve readability by @alejandro-colomar in #1208
- lib/, src/, tests/: Use the standard
countof()instead of ourNITEMS()by @alejandro-colomar in #1259 - lib/fs/mkstemp/, src/: Move fmkomstemp() to separate files under lib/fs/mkstemp/, and split into mkomstemp() by @alejandro-colomar in #1139
- [x][v]aprintf(): Add APIs, and use them instead of [x][v]asprintf(3) by @alejandro-colomar in #1168
- lib/get_pid.c: pid_t is a signed integer by @alejandro-colomar in #1264
- src/newusers.c: Fix off-by-one benign bug in array declaration by @alejandro-colomar in #1266
- Add some wrappers for usual loops around strsep(3) by @alejandro-colomar in #1155
- lib/fs/readlink/areadlink.h: areadlink(): Avoid inconditionally using PATH_MAX by @sthibaul in #1222
- configure: Fix typo by @sthibaul in #1268
- Pre-release 4.18.0-rc1 by @hallyn in #1270
- Update man pages for chage, shadow, passwd by @domiborges in #1243
- contrib/: Burn it all by @alejandro-colomar in #1274
- Pre-release 4.18.0-rc2 by @hallyn in #1275
- Release 4.18.0 by @hallyn in #1277
New Contributors
- @matthewhughes934 made their first contribution in #1254
- @domiborges made their first contribution in #1243
Full Changelog: 4.17.4...4.18.0
4.18.0-rc2
This is a pre-release for last minute testing. 4.18.0-rc1 appeared to go smoothly, so I expect no issues. We expect to release 4.18.0 tomorrow.
What's Changed
- CI: purge man-db by @ikerexxe in #1241
- passwd: document exit code when PAM has errored by @hallyn in #1244
- Man patches by @zeha in #1175
- Quick fix: define E_PAM_ERR in lib/pam_pass.c by @hallyn in #1245
- Accept /usr/sbin/nologin as an alternate to /sbin/nologin by @zeha in #1246
- Add LOGIN_ENV_SAFELIST to FOREIGNDEFS by @stanislav-brabec in #1248
- ci: add
gawkas a fedora dependency by @ikerexxe in #1252 - man/useradd.8.xml: fix the CREATE_HOME description by @hallyn in #1251
- lib/getdate.y: Restrict the date formats that we support by @alejandro-colomar in #1238
- newuidmap: better error logging on failure by @matthewhughes934 in #1254
- Extend basic test cases to check shadow and gshadow entries by @ikerexxe in #1237
- lib/sizeof.h: Make sure STRLEN() only accepts string literals by @alejandro-colomar in #1260
- Add strprefix(), and use it instead of its pattern by @alejandro-colomar in #1152
- src/: Simplify, using strpbrk(3) by @alejandro-colomar in #1167
- lib/string/strdup/: STRNDUPA(): Reimplement in terms of strndupa(3) by @alejandro-colomar in #1189
- Remove dead beef by @alejandro-colomar in #1230
- lib/atoi/a2i/: Simplify these macros by calling a2i() by @alejandro-colomar in #1137
- strtolower(): Add API, and use it instead of its pattern by @alejandro-colomar in #1211
- lib/: sget*ent(): Simplify by calling strdup(3) by @alejandro-colomar in #1146
- fields by @alejandro-colomar in #1150
- yacc(1) is a dead language; bury it deep in the ground by @alejandro-colomar in #1217
- Test expiration date by @ikerexxe in #1233
- [scp] Add strcaseprefix(), and use it instead of its pattern by @alejandro-colomar in #1262
- valid_field(): Improve readability by @alejandro-colomar in #1208
- lib/, src/, tests/: Use the standard
countof()instead of ourNITEMS()by @alejandro-colomar in #1259 - lib/fs/mkstemp/, src/: Move fmkomstemp() to separate files under lib/fs/mkstemp/, and split into mkomstemp() by @alejandro-colomar in #1139
- [x][v]aprintf(): Add APIs, and use them instead of [x][v]asprintf(3) by @alejandro-colomar in #1168
- lib/get_pid.c: pid_t is a signed integer by @alejandro-colomar in #1264
- src/newusers.c: Fix off-by-one benign bug in array declaration by @alejandro-colomar in #1266
- Add some wrappers for usual loops around strsep(3) by @alejandro-colomar in #1155
- lib/fs/readlink/areadlink.h: areadlink(): Avoid inconditionally using PATH_MAX by @sthibaul in #1222
- configure: Fix typo by @sthibaul in #1268
- Pre-release 4.18.0-rc1 by @hallyn in #1270
- Update man pages for chage, shadow, passwd by @domiborges in #1243
- contrib/: Burn it all by @alejandro-colomar in #1274
- Pre-release 4.18.0-rc2 by @hallyn in #1275
New Contributors
- @matthewhughes934 made their first contribution in #1254
- @domiborges made their first contribution in #1243
Full Changelog: 4.17.4...4.18.0-rc2
Pre-release 4.18.0-rc1
This is a pre-release for testing by distributions. New release to follow later this month.
Release 4.17.4
Changes since 4.17.3:
Alejandro Colomar (12):
Revert "lib/, src/: Use local time for human-readable dates"
lib/getdate.y: Ignore time-zone information and use UTC
src/chfn.c: Partially revert "lib/, src/: Use strsep(3) instead of its pattern"
src/chfn.c: Use stpsep() instead of its pattern
src/chfn.c: Add local variable to refer to the separated field
src/chfn.c: copy_field(): Rename local variable
lib/commonio.c: Rely on the POSIX.1-2008 behavior of realpath(3)
lib/fs/readlink/: readlinknul(): Use ssize_t to simplify
autogen.sh: Promote -Wsign-compare to an error
lib/sizeof.h: ssizeof(): Add signed variant of sizeof
src/lastlog.c: Use ssizeof() to avoid a -Wsign-compare diagnostic
tests/unit/test_xasprintf.c: Fix sign-mismatch diagnostic
Chris Hofstaedtler (2):
configure.ac: stop checking for utmp location
configure.ac: be deterministic about passwd location
Iker Pedrosa (3):
lib/, src/: update audit messages
lib/: audit function for groups
src/: update group audit messages
Michael Vetter (1):
doc/: Remove list of distributions
Serge Hallyn (1):
release 4.17.4
4.17.3
4.17.2
What's Changed
- src/login_nopam.c: Fix compiler warnings by @stoeckmann in #1170
- lib/chkname.c: Put limits for LOGIN_NAME_MAX and sysconf(_SC_LOGIN_NAME_MAX) by @alejandro-colomar in #1169
- Use HTTPS in link to Wikipedia article on password strength by @scottdotweb in #1164
- lib/attr.h: use C23 attributes only with gcc >= 10 by @kanavin in #1172
- login: Fix no-pam authorization regression by @stoeckmann in #1174
- man: Add Portuguese translation by @zeha in #1178
- Update French translation by @zeha in #1177
- Add cheap defense mechanisms by @stoeckmann in #1171
- Add Romanian translation by @zeha in #1176
- Release 4.17.2 by @alejandro-colomar in #1179
New Contributors
- @scottdotweb made their first contribution in #1164
Full Changelog: 4.17.1...4.17.2
4.17.1
What's Changed
- su: Fix su - regression by @stoeckmann in #1163
- Release 4.17.1 by @hallyn in #1165
Full Changelog: 4.17.0...4.17.1
4.17.0: Fleuron de Bruges
Alejandro Colomar (182):
lib/csrand.c: Fix the lower part of the domain of csrand_uniform()
tests/unit/test_xasprintf.c: Cosmetic
tests/unit/test_xasprintf.c: Fix use of volatile pointer
Makefile.am: Use 'dist-hook' to clean up <tests/unit/Makefile>
lib/typetraits.h: Add macros that give information about a type
tests/unit/test_typetraits.c: Add tests for typetraits.h macros
src/: Use str2[u]l() instead of atoi(3)
lib/get_gid.c: get_gid(): Reimplement in terms of a2i()
lib/, libsubid/, po/, src/: get_gid(): Move function to "atoi/getnum.h"
lib/: Don't open-code get_gid()
lib/get_pid.c: get_pid(): Reimplement in terms of a2i()
lib/: get_pid(): Move function to "atoi/getnum.h"
lib/atoi/getnum.[ch]: get_fd(): Add function for parsing a file descriptor from a string
lib/get_pid.c: get_pidfd_from_fd(): Don't open-code get_fd()
src/usermod.c: getulong_range(): Reimplement in terms of a2ul()
lib/get_uid.c: get_uid(): Reimplement in terms of a2i()
lib/, po/, src/: get_uid(): Move function to "atoi/getnum.h"
lib/limits.c: setrlimit_value(): Reimplement in terms of a2i()
src/usermod.c: Fix const correctness
src/get_subid_owners.c: Use uid_t for holding UIDs (and GIDs)
lib/string/sprintf/, lib/, src/, tests/: Move all sprintf(3)-like APIs to a subdirectory
lib/string/strcpy/, lib/, src/, tests/: Move all copying APIs to a subdirectory
src/su.c: save_caller_context(): Remove unused parameter
src/logoutd.c: Remove unused variable
src/login.c: Remove dead code
lib/, src/: Reduce scope of local variables
lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
lib/getdate.y: NULL doesn't need a cast
lib/, src/: Always pass NULL to time(2)
lib/failure.c: failprint(): Remove dead code
lib/, src/: Add missing include
lib/: Use REALLOCF() instead of its pattern
lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
lib/, src/: Use strchrnul(3) instead of its pattern
src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
lib/, src/: Use strsep(3) instead of its pattern
lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
src/groupmems.c: Fix number of elements in allocation
src/: Use xasprintf() instead of its pattern
lib/string/strcpy/strncat.[ch]: STRNCAT(): Add macro
lib/string/strdup/: XSTRNDUP(), STRNDUPA(): Add macros
lib/utmp.c: Use XSTRNDUP() instead of its pattern
lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
src/logoutd.c: Use STRNDUPA() instead of its pattern
src/logoutd.c: Use STRNCAT() instead of its pattern
lib/string/strcpy/zustr2stp.[ch], tests/: Remove ZUSTR2STP()
lib/string/strdup/xstrdup.[ch], lib/, src/: Move xstrdup() to its own file
lib/alloc.[ch]: xmalloc(): Remove unused function
lib/alloc/, lib/, src/, tests/: Organize the allocation APIs in a new subdirectory
lib/: Use multi-line macro definitions
lib/: Use [[gnu::alloc_size(...)]] on allocation functions
src/: Remove dead code
lib/gshadow.c: Use XREALLOC() instead of silently continuing on ENOMEM
lib/attr.h: Use C23-style attributes
lib/idmapping.c: Use long constants in prctl(2), and remove 0s
Remove id(1)
Remove groups(1)
lib/getdef.c: getdef_num(): Simplify, by calling a2si() instead of str2sl()
lib/getdef.c: getdef_unum(): Fix wrong limit check
lib/getdef.c: getdef_long(): Simplify, by calling a2sl() instead of str2sl()
lib/limits.c: set_prio(): Simplify, by calling str2si() instead of str2sl()
lib/limits.c: set_umask(): Simplify, by calling str2i(mode_t, ) instead of str2ul()
lib/limits.c: setup_limits(): Simplify, by calling a2si() instead of str2sl()
lib/limits.c: setup_limits(): Simplify, by calling str2si() instead of str2sl()
lib/limits.c: setup_limits(): Simplify, by calling str2i(mode_t, ) instead of str2ul()
lib/sgetspent.c: sgetspent(): Simplify, by calling a2sl() instead of str2sl()
lib/shadow.c: my_sgetspent(): Merge 'else {if}' into 'else if'
lib/shadow.c: my_sgetspent(): Remove dead code
lib/shadow.c: my_sgetspent(): Simplify error handling
src/: Use get_[ug]id() where appropriate
src/useradd.c: Simplify, by calling a2sl() instead of str2sl()
src/passwd.c: Simplify, by calling a2sl() instead of str2sl()
src/usermod.c: Simplify, by calling a2sl() instead of str2sl()
src/faillog.c: Simplify, by calling str2sh() instead of str2sl()
src/chage.c: Simplify, by calling a2sl() instead of str2sl()
lib/string/strchr/: stp[c]spn(), strrspn(), strnul(): Add macros and functions
lib/getdef.c: def_load(): Use stp[c]spn() instead of their patterns
src/login_nopam.c: login_access(): Simplify, calling strchr(3)
lib/sssd.c: Style fixes
lib/, src/: Use strrspn() instead of its pattern
contrib, lib/, src/, tests/: Use stpcpy(3) instead of its pattern
contrib/adduser.c: main(): Use strcpy/cat(3) instead of their pattern
lib/port.c: getttyuser(): Remove dead code
lib/port.c: getttyuser(): Use goto to break out of nested loops
lib/port.c: getportent(): Rename goto label
lib/port.c: getportent(): Remove obvious comments
lib/port.c: getportent(): Make sure there are at least 2 ':' in the line
lib/port.c: getportent(): Make sure the aren't too many fields in the CSV
lib/port.c: getportent(): Use equivalent code to parse equally-formatted fields
lib/port.c: getttyuser(): Use pointer arithmetic to simplify
lib/port.c: getportent(): Align variables
lib/port.c: getportent(): Use strsep(3) instead of its pattern
lib/string/strtok/stpsep.[ch]: stpsep(): Add function
lib/, src/: Use stpsep() instead of its pattern
lib/attr.h: ATTR_STRING(): It only accepts one argument
lib/string/strchr/stpcspn.[ch]: stpcspn(): Remove unused function
src/suauth.c: check_su_auth(): Use stpsep() to simplify
lib/nss.c: nss_init(): Use stpsep() instead of strtok_r(3)
src/useradd.c: Use stpsep() to simplify
src/login_nopam.c: login_access(): Use stpsep() to simplify
lib/limits.c: check_logins(): Report LOGIN_ERROR_LOGIN if str2ul() ERANGE
lib/idmapping.c: get_map_ranges(): Rename local variable
lib/idmapping.c: get_map_ranges(): Move range check to a2ul() calls
lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call
lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call
lib/idmapping.c: get_map_ranges(): Remove dead code
lib/idmapping.c: get_map_ranges(): Simplify iterator variables
lib/idmapping.c: get_map_ranges(): Don't exit() from a library function
src/usermod.c: Rename identifiers ralated to [ug]id's
src/usermod.c: Use id_t for parsing uid_t and gid_t
lib/atoi/, : Split files
lib/atoi/strtoi/, tests/: strto[iu](): 1 is an invalid base
lib/chkname.c: An object cannot expand further than the universe in which it resides
lib/, src/: Use local time for human-readable dates
lib/, src/: Use %F instead of %Y-%m-%d with strftime(3)
src/chage.c: print_day_as_date(): Simplify error handling
src/chage.c: print_day_as_date(): Handle errors from strfime(3)
lib/string/strftime.h: STRFTIME(): Tighten macro definition
po/es.po: wsfix
lib/: Move memzero.[ch] under lib/string/memset/
lib/string/memset/: memzero(), strzero(): Return the pointer
lib/: Chain free(strzero(s))
man/userdel.8.xml: Reword '-f'
lib/chkname.c: is_valid{user,group}_name(): Set errno to distinguish the reasons
src/: Invert logic to improve readability
src/: Recommend --badname only if it is useful
src/useradd.c: Add fmkomstemp() to fix mode of </etc/default/useradd>
src/check_subid_range.c: Remove dead code
lib/, src/: Use stpspn() instead of its pattern
lib/port.c: portcmp(): Use strcmp(3) instead of its pattern
lib/gshadow.c: endsgent(): Remove dead assignment
src/suauth.c: check_su_auth(): Use strspn(3) instead of its pattern
src/suauth.c: check_su_auth(): Use pointers to simplify
doc/contributions/introduction.md: Fix typo in link
lib/alloc/realloc.h: Rename macro parameter
lib/alloc/realloc*.h: Always reallocate at least 1 byte
lib/fields.c: Remove dead code
lib/getdef.c: Remove dead code
lib/loginprompt.c: login_prompt(): Use strtcpy() instead of its pattern
lib/fs/readlink/: readlinknul(): Add function
lib/fs/readlink/readlinknul.h: READLINKNUL(): Add macro
lib/: Use readlinknul() instead of its pattern
lib/: Use READLINKNUL() instead of its pattern
lib/fs/readlink/, lib/: areadlink(): Move and rename function
lib/fs/readlink/areadlink.h: Cosmetic changes
lib/fs/readlink/areadlink.h: areadlink(): Use PATH_MAX instead of a magic value
lib/string/strcmp/: streq(): Add function
lib/string/strchr/: strchrcnt(): Add function
lib/list.c: comma_to_list(): Use strchrcnt() instead of its pattern
lib/gshadow.c: endsgent(): Invert logic to reduce indentation
src/login_nopam.c: Rely on the system's MAXHOSTNAMELEN
lib/shadow.c: my_sgetspent(): There can be only one!
lib/, src/: Use NULL instead of 0 as a null pointer constant
share/container-build.sh: Fix path
src/login_nopam.c: resolve_hostname(): Use NI_MAXHOST instea...