summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--STABLE.md8
-rw-r--r--configure.ac22
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/alloc.h37
-rw-r--r--lib/atoi/a2i.c36
-rw-r--r--lib/atoi/a2i.h276
-rw-r--r--lib/atoi/strtou_noneg.c5
-rw-r--r--lib/atoi/strtou_noneg.h31
-rw-r--r--lib/cast.h8
-rw-r--r--lib/chkname.c35
-rw-r--r--lib/chkname.h9
-rw-r--r--lib/get_gid.c6
-rw-r--r--lib/get_pid.c19
-rw-r--r--lib/get_uid.c6
-rw-r--r--lib/getgr_nam_gid.c6
-rw-r--r--lib/getrange.c29
-rw-r--r--lib/gettime.c56
-rw-r--r--lib/limits.c6
-rw-r--r--lib/nss.c5
-rw-r--r--lib/port.c2
-rw-r--r--lib/prefix_flag.c10
-rw-r--r--lib/prototypes.h17
-rw-r--r--lib/rlogin.c135
-rw-r--r--lib/subordinateio.c10
-rw-r--r--lib/subordinateio.h3
-rw-r--r--libsubid/api.c5
-rw-r--r--libsubid/subid.h.in13
-rw-r--r--man/lastlog.8.xml4
-rw-r--r--man/login.1.xml8
-rw-r--r--man/po/da.po4
-rw-r--r--man/po/de.po4
-rw-r--r--man/po/fr.po4
-rw-r--r--man/po/it.po4
-rw-r--r--man/po/pl.po2
-rw-r--r--man/po/ru.po4
-rw-r--r--man/po/shadow-man-pages.pot2
-rw-r--r--man/po/sv.po2
-rw-r--r--man/po/uk.po4
-rw-r--r--man/po/zh_CN.po4
-rw-r--r--man/useradd.8.xml2
-rw-r--r--po/POTFILES.in1
-rw-r--r--po/nl.po202
-rw-r--r--src/check_subid_range.c8
-rw-r--r--src/getsubids.c1
-rw-r--r--src/groupmod.c2
-rw-r--r--src/login.c86
-rw-r--r--src/useradd.c74
-rw-r--r--src/usermod.c418
-rwxr-xr-xtests/bug332198-test.exp61
-rw-r--r--tests/libsubid/04_nss/libsubid_zzz.c5
-rw-r--r--tests/unit/Makefile.am14
-rw-r--r--tests/unit/test_atoi_strtou_noneg.c76
53 files changed, 799 insertions, 994 deletions
diff --git a/Makefile.am b/Makefile.am
index 8f489073..22bbd561 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,3 +15,4 @@ SUBDIRS += man
endif
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
+EXTRA_DIST = tests/
diff --git a/STABLE.md b/STABLE.md
index 31bbbffb..d49ebfa9 100644
--- a/STABLE.md
+++ b/STABLE.md
@@ -2,10 +2,10 @@
The following stable branches are kindly maintained by trusted volunteers:
-- 4.14.x
+- 4.15.x
- git
- - [main](https://www.alejandro-colomar.es/src/alx/shadow/stable/shadow.git/log/?h=4.14.x)
- - [mirror](https://github.com/shadow-maint/shadow/tree/4.14.x)
+ - [main](https://www.alejandro-colomar.es/src/alx/shadow/stable/shadow.git/log/?h=4.15.x)
+ - [mirror](https://github.com/shadow-maint/shadow/tree/4.15.x)
- tarballs
- - [main](https://www.alejandro-colomar.es/share/dist/shadow/4/4.14/)
+ - [main](https://www.alejandro-colomar.es/share/dist/shadow/4/4.15/)
- [mirror](https://github.com/shadow-maint/shadow/releases/)
diff --git a/configure.ac b/configure.ac
index 9a6103d4..936294f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,12 +1,12 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
-m4_define([libsubid_abi_major], 4)
+m4_define([libsubid_abi_major], 5)
m4_define([libsubid_abi_minor], 0)
m4_define([libsubid_abi_micro], 0)
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
-AC_INIT([shadow], [4.15.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
+AC_INIT([shadow], [4.16.0-rc1], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
-AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
+AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
AC_CONFIG_MACRO_DIRS([m4])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS([config.h])
@@ -159,13 +159,6 @@ fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
-dnl XXX - quick hack, should disappear before anyone notices :).
-dnl XXX - I just read the above message :).
-if test "$ac_cv_func_ruserok" = "yes"; then
- AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
- AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
-fi
-
AC_ARG_ENABLE(shadowgrp,
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[case "${enableval}" in
@@ -274,6 +267,7 @@ AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max grou
AC_SUBST(GROUP_NAME_MAX_LENGTH)
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
+
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
@@ -310,6 +304,10 @@ dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
AC_SEARCH_LIBS(gethostbyname, nsl)
+PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
+ [AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
+AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
+
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
if test -n "$LIBECONF"; then
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
@@ -701,10 +699,6 @@ if test "$with_skey" = "yes"; then
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
fi
-PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
- [AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
-AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
-
AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 22abb978..adcd9fbf 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -119,7 +119,6 @@ libshadow_la_SOURCES = \
pwdcheck.c \
pwmem.c \
remove_tree.c \
- rlogin.c \
root_flag.c \
run_part.h \
run_part.c \
diff --git a/lib/alloc.h b/lib/alloc.h
index 0e048849..39405a56 100644
--- a/lib/alloc.h
+++ b/lib/alloc.h
@@ -1,8 +1,5 @@
-/*
- * SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
+// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
@@ -27,31 +24,19 @@
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
#define REALLOC(ptr, n, type) \
-({ \
- __auto_type p_ = (ptr); \
- \
- static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
- \
- (type *) reallocarray(p_, n, sizeof(type)); \
-})
+( \
+ _Generic(ptr, type *: (type *) reallocarray(ptr, n, sizeof(type))) \
+)
#define REALLOCF(ptr, n, type) \
-({ \
- __auto_type p_ = (ptr); \
- \
- static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
- \
- (type *) reallocarrayf(p_, n, sizeof(type)); \
-})
+( \
+ _Generic(ptr, type *: (type *) reallocarrayf(ptr, n, sizeof(type))) \
+)
#define XREALLOC(ptr, n, type) \
-({ \
- __auto_type p_ = (ptr); \
- \
- static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
- \
- (type *) xreallocarray(p_, n, sizeof(type)); \
-})
+( \
+ _Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
+)
ATTR_MALLOC(free)
diff --git a/lib/atoi/a2i.c b/lib/atoi/a2i.c
index 6dca7e89..a2cf8723 100644
--- a/lib/atoi/a2i.c
+++ b/lib/atoi/a2i.c
@@ -7,20 +7,40 @@
#include "atoi/a2i.h"
-extern inline int a2sh(short *restrict n, const char *s,
+extern inline int a2sh_c(short *restrict n, const char *s,
+ const char **restrict endp, int base, short min, short max);
+extern inline int a2si_c(int *restrict n, const char *s,
+ const char **restrict endp, int base, int min, int max);
+extern inline int a2sl_c(long *restrict n, const char *s,
+ const char **restrict endp, int base, long min, long max);
+extern inline int a2sll_c(long long *restrict n, const char *s,
+ const char **restrict endp, int base, long long min, long long max);
+extern inline int a2uh_c(unsigned short *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned short min,
+ unsigned short max);
+extern inline int a2ui_c(unsigned int *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned int min, unsigned int max);
+extern inline int a2ul_c(unsigned long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long min, unsigned long max);
+extern inline int a2ull_c(unsigned long long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long long min,
+ unsigned long long max);
+
+
+extern inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
-extern inline int a2si(int *restrict n, const char *s,
+extern inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
-extern inline int a2sl(long *restrict n, const char *s,
+extern inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
-extern inline int a2sll(long long *restrict n, const char *s,
+extern inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
-extern inline int a2uh(unsigned short *restrict n, const char *s,
+extern inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
-extern inline int a2ui(unsigned int *restrict n, const char *s,
+extern inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
-extern inline int a2ul(unsigned long *restrict n, const char *s,
+extern inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
-extern inline int a2ull(unsigned long long *restrict n, const char *s,
+extern inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);
diff --git a/lib/atoi/a2i.h b/lib/atoi/a2i.h
index 3935f42d..64f775a9 100644
--- a/lib/atoi/a2i.h
+++ b/lib/atoi/a2i.h
@@ -15,51 +15,255 @@
#include "attr.h"
-#define a2i(TYPE, ...) \
+/*
+ * See the manual of these macros in liba2i's documentation:
+ * <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf>
+ */
+
+
+#define a2i(TYPE, n, s, ...) \
+( \
+ _Generic((void (*)(TYPE, typeof(s))) 0, \
+ void (*)(short, const char *): a2sh_c, \
+ void (*)(short, const void *): a2sh_c, \
+ void (*)(short, char *): a2sh_nc, \
+ void (*)(short, void *): a2sh_nc, \
+ void (*)(int, const char *): a2si_c, \
+ void (*)(int, const void *): a2si_c, \
+ void (*)(int, char *): a2si_nc, \
+ void (*)(int, void *): a2si_nc, \
+ void (*)(long, const char *): a2sl_c, \
+ void (*)(long, const void *): a2sl_c, \
+ void (*)(long, char *): a2sl_nc, \
+ void (*)(long, void *): a2sl_nc, \
+ void (*)(long long, const char *): a2sll_c, \
+ void (*)(long long, const void *): a2sll_c, \
+ void (*)(long long, char *): a2sll_nc, \
+ void (*)(long long, void *): a2sll_nc, \
+ void (*)(unsigned short, const char *): a2uh_c, \
+ void (*)(unsigned short, const void *): a2uh_c, \
+ void (*)(unsigned short, char *): a2uh_nc, \
+ void (*)(unsigned short, void *): a2uh_nc, \
+ void (*)(unsigned int, const char *): a2ui_c, \
+ void (*)(unsigned int, const void *): a2ui_c, \
+ void (*)(unsigned int, char *): a2ui_nc, \
+ void (*)(unsigned int, void *): a2ui_nc, \
+ void (*)(unsigned long, const char *): a2ul_c, \
+ void (*)(unsigned long, const void *): a2ul_c, \
+ void (*)(unsigned long, char *): a2ul_nc, \
+ void (*)(unsigned long, void *): a2ul_nc, \
+ void (*)(unsigned long long, const char *): a2ull_c, \
+ void (*)(unsigned long long, const void *): a2ull_c, \
+ void (*)(unsigned long long, char *): a2ull_nc, \
+ void (*)(unsigned long long, void *): a2ull_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+
+#define a2sh(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2sh_c, \
+ const void *: a2sh_c, \
+ char *: a2sh_nc, \
+ void *: a2sh_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+#define a2si(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2si_c, \
+ const void *: a2si_c, \
+ char *: a2si_nc, \
+ void *: a2si_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+#define a2sl(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2sl_c, \
+ const void *: a2sl_c, \
+ char *: a2sl_nc, \
+ void *: a2sl_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+#define a2sll(n, s, ...) \
( \
- _Generic((TYPE) 0, \
- short: a2sh, \
- int: a2si, \
- long: a2sl, \
- long long: a2sll, \
- unsigned short: a2uh, \
- unsigned int: a2ui, \
- unsigned long: a2ul, \
- unsigned long long: a2ull \
- )(__VA_ARGS__) \
+ _Generic(s, \
+ const char *: a2sll_c, \
+ const void *: a2sll_c, \
+ char *: a2sll_nc, \
+ void *: a2sll_nc \
+ )(n, s, __VA_ARGS__) \
)
+#define a2uh(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2uh_c, \
+ const void *: a2uh_c, \
+ char *: a2uh_nc, \
+ void *: a2uh_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+#define a2ui(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2ui_c, \
+ const void *: a2ui_c, \
+ char *: a2ui_nc, \
+ void *: a2ui_nc \
+ )(n, s, __VA_ARGS__) \
+)
+#define a2ul(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2ul_c, \
+ const void *: a2ul_c, \
+ char *: a2ul_nc, \
+ void *: a2ul_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+#define a2ull(n, s, ...) \
+( \
+ _Generic(s, \
+ const char *: a2ull_c, \
+ const void *: a2ull_c, \
+ char *: a2ull_nc, \
+ void *: a2ull_nc \
+ )(n, s, __VA_ARGS__) \
+)
+
+
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2sh_c(short *restrict n, const char *s,
+ const char **restrict endp, int base, short min, short max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2si_c(int *restrict n, const char *s,
+ const char **restrict endp, int base, int min, int max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2sl_c(long *restrict n, const char *s,
+ const char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2sh(short *restrict n, const char *s,
+inline int a2sll_c(long long *restrict n, const char *s,
+ const char **restrict endp, int base, long long min, long long max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2uh_c(unsigned short *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned short min,
+ unsigned short max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2ui_c(unsigned int *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned int min, unsigned int max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2ul_c(unsigned long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long min, unsigned long max);
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2ull_c(unsigned long long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long long min,
+ unsigned long long max);
+
+ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
+inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2si(int *restrict n, const char *s,
+inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2sl(long *restrict n, const char *s,
+inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2sll(long long *restrict n, const char *s,
+inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2uh(unsigned short *restrict n, const char *s,
+inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2ui(unsigned int *restrict n, const char *s,
+inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2ul(unsigned long *restrict n, const char *s,
+inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
-inline int a2ull(unsigned long long *restrict n, const char *s,
+inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);
inline int
-a2sh(short *restrict n, const char *s, char **restrict endp,
- int base, short min, short max)
+a2sh_c(short *restrict n, const char *s,
+ const char **restrict endp, int base, short min, short max)
+{
+ return a2sh(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2si_c(int *restrict n, const char *s,
+ const char **restrict endp, int base, int min, int max)
+{
+ return a2si(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2sl_c(long *restrict n, const char *s,
+ const char **restrict endp, int base, long min, long max)
+{
+ return a2sl(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2sll_c(long long *restrict n, const char *s,
+ const char **restrict endp, int base, long long min, long long max)
+{
+ return a2sll(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2uh_c(unsigned short *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned short min,
+ unsigned short max)
+{
+ return a2uh(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2ui_c(unsigned int *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned int min, unsigned int max)
+{
+ return a2ui(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2ul_c(unsigned long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long min, unsigned long max)
+{
+ return a2ul(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2ull_c(unsigned long long *restrict n, const char *s,
+ const char **restrict endp, int base, unsigned long long min,
+ unsigned long long max)
+{
+ return a2ull(n, (char *) s, (char **) endp, base, min, max);
+}
+
+
+inline int
+a2sh_nc(short *restrict n, char *s,
+ char **restrict endp, int base, short min, short max)
{
int status;
@@ -73,8 +277,8 @@ a2sh(short *restrict n, const char *s, char **restrict endp,
inline int
-a2si(int *restrict n, const char *s, char **restrict endp,
- int base, int min, int max)
+a2si_nc(int *restrict n, char *s,
+ char **restrict endp, int base, int min, int max)
{
int status;
@@ -88,8 +292,8 @@ a2si(int *restrict n, const char *s, char **restrict endp,
inline int
-a2sl(long *restrict n, const char *s, char **restrict endp,
- int base, long min, long max)
+a2sl_nc(long *restrict n, char *s,
+ char **restrict endp, int base, long min, long max)
{
int status;
@@ -103,8 +307,8 @@ a2sl(long *restrict n, const char *s, char **restrict endp,
inline int
-a2sll(long long *restrict n, const char *s, char **restrict endp,
- int base, long long min, long long max)
+a2sll_nc(long long *restrict n, char *s,
+ char **restrict endp, int base, long long min, long long max)
{
int status;
@@ -118,8 +322,9 @@ a2sll(long long *restrict n, const char *s, char **restrict endp,
inline int
-a2uh(unsigned short *restrict n, const char *s, char **restrict endp,
- int base, unsigned short min, unsigned short max)
+a2uh_nc(unsigned short *restrict n, char *s,
+ char **restrict endp, int base, unsigned short min,
+ unsigned short max)
{
int status;
@@ -133,8 +338,8 @@ a2uh(unsigned short *restrict n, const char *s, char **restrict endp,
inline int
-a2ui(unsigned int *restrict n, const char *s, char **restrict endp,
- int base, unsigned int min, unsigned int max)
+a2ui_nc(unsigned int *restrict n, char *s,
+ char **restrict endp, int base, unsigned int min, unsigned int max)
{
int status;
@@ -148,8 +353,8 @@ a2ui(unsigned int *restrict n, const char *s, char **restrict endp,
inline int
-a2ul(unsigned long *restrict n, const char *s, char **restrict endp,
- int base, unsigned long min, unsigned long max)
+a2ul_nc(unsigned long *restrict n, char *s,
+ char **restrict endp, int base, unsigned long min, unsigned long max)
{
int status;
@@ -163,8 +368,9 @@ a2ul(unsigned long *restrict n, const char *s, char **restrict endp,
inline int
-a2ull(unsigned long long *restrict n, const char *s, char **restrict endp,
- int base, unsigned long long min, unsigned long long max)
+a2ull_nc(unsigned long long *restrict n, char *s,
+ char **restrict endp, int base, unsigned long long min,
+ unsigned long long max)
{
int status;
diff --git a/lib/atoi/strtou_noneg.c b/lib/atoi/strtou_noneg.c
index ec8773d7..71cacbd1 100644
--- a/lib/atoi/strtou_noneg.c
+++ b/lib/atoi/strtou_noneg.c
@@ -11,8 +11,3 @@
extern inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);
-
-extern inline unsigned long strtoul_noneg(const char *s,
- char **restrict endp, int base);
-extern inline unsigned long long strtoull_noneg(const char *s,
- char **restrict endp, int base);
diff --git a/lib/atoi/strtou_noneg.h b/lib/atoi/strtou_noneg.h
index a1d15569..6d77adf5 100644
--- a/lib/atoi/strtou_noneg.h
+++ b/lib/atoi/strtou_noneg.h
@@ -9,8 +9,8 @@
#include <config.h>
#include <errno.h>
+#include <stddef.h>
#include <stdint.h>
-#include <stdlib.h>
#include "atoi/strtoi.h"
#include "attr.h"
@@ -20,13 +20,6 @@ ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);
-ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
-inline unsigned long strtoul_noneg(const char *s,
- char **restrict endp, int base);
-ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
-inline unsigned long long strtoull_noneg(const char *s,
- char **restrict endp, int base);
-
inline uintmax_t
strtou_noneg(const char *s, char **restrict endp, int base,
@@ -43,26 +36,4 @@ strtou_noneg(const char *s, char **restrict endp, int base,
}
-inline unsigned long
-strtoul_noneg(const char *s, char **restrict endp, int base)
-{
- if (strtol(s, endp, base) < 0) {
- errno = ERANGE;
- return 0;
- }
- return strtoul(s, endp, base);
-}
-
-
-inline unsigned long long
-strtoull_noneg(const char *s, char **restrict endp, int base)
-{
- if (strtol(s, endp, base) < 0) {
- errno = ERANGE;
- return 0;
- }
- return strtoull(s, endp, base);
-}
-
-
#endif // include guard
diff --git a/lib/cast.h b/lib/cast.h
index 9229528d..5cbbcf6d 100644
--- a/lib/cast.h
+++ b/lib/cast.h
@@ -8,14 +8,8 @@
#include <config.h>
-#include "must_be.h"
-
-#define const_cast(T, p) \
-({ \
- static_assert(is_same_type(typeof(&*(p)), const T), ""); \
- (T) (p); \
-})
+#define const_cast(T, p) _Generic(p, const T: (T) (p))
#endif // include guard
diff --git a/lib/chkname.c b/lib/chkname.c
index fbd6ba88..995562fa 100644
--- a/lib/chkname.c
+++ b/lib/chkname.c
@@ -5,6 +5,7 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
+
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
@@ -13,6 +14,7 @@
* false - bad name
*/
+
#include <config.h>
#ident "$Id$"
@@ -20,11 +22,31 @@
#include <ctype.h>
#include <errno.h>
#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <unistd.h>
+
#include "defines.h"
#include "chkname.h"
+
int allow_bad_names = false;
+
+size_t
+login_name_max_size(void)
+{
+ long conf;
+
+ errno = 0;
+ conf = sysconf(_SC_LOGIN_NAME_MAX);
+ if (conf == -1 && errno != 0)
+ return LOGIN_NAME_MAX;
+
+ return conf;
+}
+
+
static bool is_valid_name (const char *name)
{
if (allow_bad_names) {
@@ -76,18 +98,7 @@ static bool is_valid_name (const char *name)
bool
is_valid_user_name(const char *name)
{
- long conf;
- size_t maxsize;
-
- errno = 0;
- conf = sysconf(_SC_LOGIN_NAME_MAX);
-
- if (conf == -1 && errno != 0)
- maxsize = LOGIN_NAME_MAX;
- else
- maxsize = conf;
-
- if (strlen(name) >= maxsize)
+ if (strlen(name) >= login_name_max_size())
return false;
return is_valid_name(name);
diff --git a/lib/chkname.h b/lib/chkname.h
index 07713473..4306a8a2 100644
--- a/lib/chkname.h
+++ b/lib/chkname.h
@@ -11,6 +11,7 @@
#ifndef _CHKNAME_H_
#define _CHKNAME_H_
+
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
@@ -19,8 +20,14 @@
* false - bad name
*/
-#include "defines.h"
+#include <config.h>
+
+#include <stdbool.h>
+#include <stddef.h>
+
+
+extern size_t login_name_max_size(void);
extern bool is_valid_user_name (const char *name);
extern bool is_valid_group_name (const char *name);
diff --git a/lib/get_gid.c b/lib/get_gid.c
index 2c5030be..2420137b 100644
--- a/lib/get_gid.c
+++ b/lib/get_gid.c
@@ -16,13 +16,13 @@
int
get_gid(const char *gidstr, gid_t *gid)
{
+ char *end;
long long val;
- char *endptr;
errno = 0;
- val = strtoll(gidstr, &endptr, 10);
+ val = strtoll(gidstr, &end, 10);
if ( ('\0' == *gidstr)
- || ('\0' != *endptr)
+ || ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
return -1;
diff --git a/lib/get_pid.c b/lib/get_pid.c
index 61caa7aa..af3f2f8e 100644
--- a/lib/get_pid.c
+++ b/lib/get_pid.c
@@ -17,15 +17,16 @@
#include "string/sprintf.h"
-int get_pid (const char *pidstr, pid_t *pid)
+int
+get_pid(const char *pidstr, pid_t *pid)
{
+ char *end;
long long val;
- char *endptr;
errno = 0;
- val = strtoll(pidstr, &endptr, 10);
+ val = strtoll(pidstr, &end, 10);
if ( ('\0' == *pidstr)
- || ('\0' != *endptr)
+ || ('\0' != *end)
|| (0 != errno)
|| (val < 1)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
@@ -43,15 +44,15 @@ int get_pid (const char *pidstr, pid_t *pid)
*/
int get_pidfd_from_fd(const char *pidfdstr)
{
- long long val;
- char *endptr;
- struct stat st;
+ char *end;
+ long long val;
+ struct stat st;
dev_t proc_st_dev, proc_st_rdev;
errno = 0;
- val = strtoll(pidfdstr, &endptr, 10);
+ val = strtoll(pidfdstr, &end, 10);
if ( ('\0' == *pidfdstr)
- || ('\0' != *endptr)
+ || ('\0' != *end)
|| (0 != errno)
|| (val < 0)
|| (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {
diff --git a/lib/get_uid.c b/lib/get_uid.c
index d7169325..77fe9660 100644
--- a/lib/get_uid.c
+++ b/lib/get_uid.c
@@ -16,13 +16,13 @@
int
get_uid(const char *uidstr, uid_t *uid)
{
+ char *end;
long long val;
- char *endptr;
errno = 0;
- val = strtoll(uidstr, &endptr, 10);
+ val = strtoll(uidstr, &end, 10);
if ( ('\0' == *uidstr)
- || ('\0' != *endptr)
+ || ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
return -1;
diff --git a/lib/getgr_nam_gid.c b/lib/getgr_nam_gid.c
index 6d625979..fd0c2171 100644
--- a/lib/getgr_nam_gid.c
+++ b/lib/getgr_nam_gid.c
@@ -23,17 +23,17 @@
*/
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname)
{
+ char *end;
long long gid;
- char *endptr;
if (NULL == grname) {
return NULL;
}
errno = 0;
- gid = strtoll(grname, &endptr, 10);
+ gid = strtoll(grname, &end, 10);
if ( ('\0' != *grname)
- && ('\0' == *endptr)
+ && ('\0' == *end)
&& (0 == errno)
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
return xgetgrgid (gid);
diff --git a/lib/getrange.c b/lib/getrange.c
index 8f7acee0..466e9089 100644
--- a/lib/getrange.c
+++ b/lib/getrange.c
@@ -1,8 +1,6 @@
-/*
- * SPDX-FileCopyrightText: 2008 , Nicolas François
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+// SPDX-FileCopyrightText: 2008, Nicolas François
+// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
+// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
@@ -12,7 +10,7 @@
#include <ctype.h>
#include <stdlib.h>
-#include "atoi/strtou_noneg.h"
+#include "atoi/a2i.h"
#include "defines.h"
#include "prototypes.h"
@@ -30,41 +28,38 @@ getrange(const char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max)
{
- char *endptr;
+ const char *end;
if (NULL == range)
return -1;
+ *min = 0;
*has_min = false;
*has_max = false;
if ('-' == range[0]) {
- endptr = range + 1;
+ end = range + 1;
goto parse_max;
}
- errno = 0;
- *min = strtoul_noneg(range, &endptr, 10);
- if (endptr == range || 0 != errno)
+ if (a2ul(min, range, &end, 10, 0, ULONG_MAX) == -1 && errno != ENOTSUP)
return -1;
*has_min = true;
- switch (*endptr++) {
+ switch (*end++) {
case '\0':
*has_max = true;
*max = *min;
return 0; /* <long> */
case '-':
- if ('\0' == *endptr)
+ if ('\0' == *end)
return 0; /* <long>- */
parse_max:
- if (!isdigit(*endptr))
+ if (!isdigit((unsigned char) *end))
return -1;
- errno = 0;
- *max = strtoul_noneg(endptr, &endptr, 10);
- if ('\0' != *endptr || 0 != errno)
+ if (a2ul(max, end, NULL, 10, *min, ULONG_MAX) == -1)
return -1;
*has_max = true;
diff --git a/lib/gettime.c b/lib/gettime.c
index 19ebe4b3..c61c88c3 100644
--- a/lib/gettime.c
+++ b/lib/gettime.c
@@ -1,8 +1,7 @@
-/*
- * SPDX-FileCopyrightText: 2017, Chris Lamb
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
+// SPDX-FileCopyrightText: 2017, Chris Lamb
+// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
+// SPDX-License-Identifier: BSD-3-Clause
+
#include <config.h>
@@ -12,11 +11,12 @@
#include <limits.h>
#include <stdio.h>
-#include "atoi/strtou_noneg.h"
+#include "atoi/a2i.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
+
/*
* gettime() returns the time as the number of seconds since the Epoch
*
@@ -24,13 +24,12 @@
* Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH
* environment variable is exported it will use that instead.
*/
-/*@observer@*/time_t gettime (void)
+/*@observer@*/time_t
+gettime(void)
{
- char *endptr;
- char *source_date_epoch;
- time_t fallback;
- unsigned long long epoch;
- FILE *shadow_logfd = log_get_logfd();
+ char *source_date_epoch;
+ FILE *shadow_logfd = log_get_logfd();
+ time_t fallback, epoch;
fallback = time (NULL);
source_date_epoch = shadow_getenv ("SOURCE_DATE_EPOCH");
@@ -38,32 +37,11 @@
if (!source_date_epoch)
return fallback;
- errno = 0;
- epoch = strtoull_noneg(source_date_epoch, &endptr, 10);
- if (errno != 0) {
- fprintf (shadow_logfd,
- _("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"),
- strerror(errno));
- } else if (endptr == source_date_epoch) {
- fprintf (shadow_logfd,
- _("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"),
- endptr);
- } else if (*endptr != '\0') {
- fprintf (shadow_logfd,
- _("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"),
- endptr);
- } else if (epoch > ULONG_MAX) {
- fprintf (shadow_logfd,
- _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"),
- ULONG_MAX, epoch);
- } else if ((time_t)epoch > fallback) {
- fprintf (shadow_logfd,
- _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"),
- fallback, epoch);
- } else {
- /* Valid */
- return epoch;
+ if (a2i(time_t, &epoch, source_date_epoch, NULL, 10, 0, fallback) == -1) {
+ fprintf(shadow_logfd,
+ _("Environment variable $SOURCE_DATE_EPOCH: a2i(\"%s\"): %s"),
+ source_date_epoch, strerror(errno));
+ return fallback;
}
-
- return fallback;
+ return epoch;
}
diff --git a/lib/limits.c b/lib/limits.c
index 387a972b..813c0821 100644
--- a/lib/limits.c
+++ b/lib/limits.c
@@ -49,7 +49,7 @@ static int setrlimit_value (unsigned int resource,
const char *value,
unsigned int multiplier)
{
- char *endptr;
+ char *end;
long l;
rlim_t limit;
struct rlimit rlim;
@@ -67,9 +67,9 @@ static int setrlimit_value (unsigned int resource,
* work with the limit string parser as is anyway)
*/
errno = 0;
- l = strtol(value, &endptr, 10);
+ l = strtol(value, &end, 10);
- if (value == endptr || errno != 0)
+ if (value == end || errno != 0)
return 0; // FIXME: We could instead throw an error, though.
if (__builtin_mul_overflow(l, multiplier, &limit)) {
diff --git a/lib/nss.c b/lib/nss.c
index 779d8259..dcb8160b 100644
--- a/lib/nss.c
+++ b/lib/nss.c
@@ -131,6 +131,11 @@ void nss_init(const char *nsswitch_path) {
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
goto close_lib;
}
+ subid_nss->free = dlsym(h, "shadow_subid_free");
+ if (!subid_nss->free) {
+ fprintf(shadow_logfd, "%s did not provide @subid_free@\n", libname);
+ goto close_lib;
+ }
subid_nss->handle = h;
goto done;
diff --git a/lib/port.c b/lib/port.c
index 05b95651..60ff8989 100644
--- a/lib/port.c
+++ b/lib/port.c
@@ -168,7 +168,7 @@ again:
}
*cp = '\0';
cp++;
- port.pt_names[j + 1] = NULL;
+ port.pt_names[j] = NULL;
/*
* Get the list of user names. It is the second colon
diff --git a/lib/prefix_flag.c b/lib/prefix_flag.c
index d42657d5..bba7102b 100644
--- a/lib/prefix_flag.c
+++ b/lib/prefix_flag.c
@@ -334,9 +334,9 @@ extern void prefix_endgrent(void)
extern struct group *prefix_getgr_nam_gid(const char *grname)
{
- long long gid;
- char *endptr;
- struct group *g;
+ char *end;
+ long long gid;
+ struct group *g;
if (NULL == grname) {
return NULL;
@@ -346,9 +346,9 @@ extern struct group *prefix_getgr_nam_gid(const char *grname)
return getgr_nam_gid(grname);
errno = 0;
- gid = strtoll(grname, &endptr, 10);
+ gid = strtoll(grname, &end, 10);
if ( ('\0' != *grname)
- && ('\0' == *endptr)
+ && ('\0' == *end)
&& (0 == errno)
&& (gid == (gid_t)gid))
{
diff --git a/lib/prototypes.h b/lib/prototypes.h
index 5c56e77e..91ff368b 100644
--- a/lib/prototypes.h
+++ b/lib/prototypes.h
@@ -284,6 +284,19 @@ struct subid_nss_ops {
*/
enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
+ /*
+ * nss_free: free a memory block allocated by a subid plugin.
+ *
+ * @ptr - a pointer to a memory block to deallocate
+ *
+ * Some routines of subid_nss_ops allocate memory which should be freed by
+ * caller after use. In order to deallocate that memory block, one should
+ * use this routine to release that memory. By default, this function
+ * pointer is set to free(3) for backward compatibility. However, it is
+ * strongly recommended to define this routine explicitly.
+ */
+ void (*free)(void *ptr);
+
/* The dlsym handle to close */
void *handle;
};
@@ -356,10 +369,6 @@ unsigned long csrand_interval (unsigned long min, unsigned long max);
/* remove_tree.c */
extern int remove_tree (const char *root, bool remove_root);
-/* rlogin.c */
-extern int do_rlogin(const char *remote_host, char *name, size_t namesize,
- char *term, size_t termsize);
-
/* root_flag.c */
extern void process_root_flag (const char* short_opt, int argc, char **argv);
diff --git a/lib/rlogin.c b/lib/rlogin.c
deleted file mode 100644
index cbc05dd8..00000000
--- a/lib/rlogin.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
- * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
- * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
- * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <config.h>
-
-#ifdef RLOGIN
-
-#ident "$Id$"
-
-#include "prototypes.h"
-#include "defines.h"
-#include <stdio.h>
-#include <pwd.h>
-#include <netdb.h>
-
-#include "atoi/str2i.h"
-
-
-static struct {
- int spd_name;
- int spd_baud;
-} speed_table[] =
-{
- { B50, 50},
- { B75, 75},
- { B110, 110},
- { B134, 134},
- { B150, 150},
- { B200, 200},
- { B300, 300},
- { B600, 600},
- { B1200, 1200},
- { B1800, 1800},
- { B2400, 2400},
- { B4800, 4800},
- { B9600, 9600},
- { B19200, 19200},
- { B38400, 38400},
- { -1, -1}
-};
-
-
-static void
-get_remote_string(char *buf, size_t size)
-{
- for (;;) {
- if (read (0, buf, 1) != 1) {
- exit (EXIT_FAILURE);
- }
- if ('\0' == *buf) {
- return;
- }
- --size;
- if (size > 0) {
- ++buf;
- }
- }
- /*NOTREACHED*/
-}
-
-
-int
-do_rlogin(const char *remote_host, char *name, size_t namesize, char *term,
- size_t termsize)
-{
- struct passwd *pwd;
- char remote_name[32];
- char *cp;
- unsigned long remote_speed = 9600;
- int speed_name = B9600;
- int i;
- TERMIO termio;
-
- get_remote_string(remote_name, sizeof(remote_name));
- get_remote_string(name, namesize);
- get_remote_string(term, termsize);
-
- cp = strchr (term, '/');
- if (NULL != cp) {
- *cp = '\0';
- cp++;
-
- if (str2ul(&remote_speed, cp) == -1)
- remote_speed = 9600;
- }
- for (i = 0;
- ( (speed_table[i].spd_baud != remote_speed)
- && (speed_table[i].spd_name != -1));
- i++);
-
- if (-1 != speed_table[i].spd_name) {
- speed_name = speed_table[i].spd_name;
- }
-
- /*
- * Put the terminal in cooked mode with echo turned on.
- */
-
- GTTY (0, &termio);
- termio.c_iflag |= ICRNL | IXON;
- termio.c_oflag |= OPOST | ONLCR;
- termio.c_lflag |= ICANON | ECHO | ECHOE;
-#ifdef CBAUD
- termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
-#else
- termio.c_cflag = (termio.c_cflag) | speed_name;
-#endif
- STTY (0, &termio);
-
- pwd = getpwnam (name); /* local, no need for xgetpwnam */
- if (NULL == pwd) {
- return 0;
- }
-
- /*
- * ruserok() returns 0 for success on modern systems, and 1 on
- * older ones. If you are having trouble with people logging
- * in without giving a required password, THIS is the culprit -
- * go fix the #define in config.h.
- */
-
-#ifndef RUSEROK
- return 0;
-#else
- return ruserok (remote_host, pwd->pw_uid == 0,
- remote_name, name) == RUSEROK;
-#endif
-}
-#endif /* RLOGIN */
diff --git a/lib/subordinateio.c b/lib/subordinateio.c
index e7cd4b48..732d1a62 100644
--- a/lib/subordinateio.c
+++ b/lib/subordinateio.c
@@ -1117,6 +1117,16 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
return ret;
}
+void free_subid_pointer(void *ptr)
+{
+ struct subid_nss_ops *h = get_subid_nss_handle();
+ if (h) {
+ h->free(ptr);
+ } else {
+ free(ptr);
+ }
+}
+
#else /* !ENABLE_SUBIDS */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */
diff --git a/lib/subordinateio.h b/lib/subordinateio.h
index d32733de..3d1a0547 100644
--- a/lib/subordinateio.h
+++ b/lib/subordinateio.h
@@ -43,6 +43,9 @@ extern int sub_gid_unlock (void);
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
+
+extern void free_subid_pointer(void *ptr);
+
#endif /* ENABLE_SUBIDS */
#endif
diff --git a/libsubid/api.c b/libsubid/api.c
index 65d20abf..76a9eec4 100644
--- a/libsubid/api.c
+++ b/libsubid/api.c
@@ -42,6 +42,11 @@ bool subid_init(const char *progname, FILE * logfd)
return true;
}
+void subid_free(void *ptr)
+{
+ free_subid_pointer(ptr);
+}
+
static
int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
{
diff --git a/libsubid/subid.h.in b/libsubid/subid.h.in
index 79744eda..7090c6c8 100644
--- a/libsubid/subid.h.in
+++ b/libsubid/subid.h.in
@@ -56,6 +56,19 @@ extern "C" {
bool subid_init(const char *progname, FILE *logfd);
/*
+ * subid_free: free memory allocated in any subid_* function
+ *
+ * @ptr: Pointer to a memory block to release.
+ *
+ * Some functions like @subid_get_uid_ranges allocate memory internally. As
+ * soon as a result is no longer needed, it should be freed with this routine.
+ * Initially, default function `free()` was used. Thus for backward
+ * compatibility this function falls back to `free()` if a plugin does not
+ * explicitly specify routine to free allocated memory.
+ */
+void subid_free(void *ptr);
+
+/*
* subid_get_uid_ranges: return a list of UID ranges for a user
*
* @owner: username being queried
diff --git a/man/lastlog.8.xml b/man/lastlog.8.xml
index 7a4ba967..6700791c 100644
--- a/man/lastlog.8.xml
+++ b/man/lastlog.8.xml
@@ -211,8 +211,8 @@
to hang as it processes entries with UIDs 171-799).
</para>
<para>
- Having high UIDs can create problems when handling the <term><filename>
- /var/log/lastlog</filename></term> with external tools. Although the
+ Having high UIDs can create problems when handling the <filename>
+ /var/log/lastlog</filename> with external tools. Although the
actual file is sparse and does not use too much space, certain
applications are not designed to identify sparse files by default and may
require a specific option to handle them.
diff --git a/man/login.1.xml b/man/login.1.xml
index 0826b1f0..26e6ea44 100644
--- a/man/login.1.xml
+++ b/man/login.1.xml
@@ -215,14 +215,6 @@
<para>Preserve environment.</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>
- <option>-r</option>
- </term>
- <listitem>
- <para>Perform autologin protocol for rlogin.</para>
- </listitem>
- </varlistentry>
</variablelist>
<para>
diff --git a/man/po/da.po b/man/po/da.po
index 08615d16..49b838d8 100644
--- a/man/po/da.po
+++ b/man/po/da.po
@@ -9021,8 +9021,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "Brugernavne må kun være op til 32 tegn lange."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "Brugernavne må kun være op til 256 tegn lange."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789
diff --git a/man/po/de.po b/man/po/de.po
index a5ba94fc..7063b528 100644
--- a/man/po/de.po
+++ b/man/po/de.po
@@ -12462,8 +12462,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "Benutzernamen dürfen nur bis zu 32 Zeichen lang sein."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "Benutzernamen dürfen nur bis zu 256 Zeichen lang sein."
# type: Plain text
#. (itstool) path: listitem/para
diff --git a/man/po/fr.po b/man/po/fr.po
index 393ef92f..6bc183e2 100644
--- a/man/po/fr.po
+++ b/man/po/fr.po
@@ -11888,8 +11888,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "Les noms d'utilisateur sont limités à 32 caractères."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "Les noms d'utilisateur sont limités à 256 caractères."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789
diff --git a/man/po/it.po b/man/po/it.po
index ec5084df..dbf05700 100644
--- a/man/po/it.po
+++ b/man/po/it.po
@@ -12082,8 +12082,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "I nomi utente non possono eccedere i 32 caratteri di lunghezza."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "I nomi utente non possono eccedere i 256 caratteri di lunghezza."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789
diff --git a/man/po/pl.po b/man/po/pl.po
index 2c86af43..219a57c9 100644
--- a/man/po/pl.po
+++ b/man/po/pl.po
@@ -9334,7 +9334,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
+msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para
diff --git a/man/po/ru.po b/man/po/ru.po
index 2a550188..02417b08 100644
--- a/man/po/ru.po
+++ b/man/po/ru.po
@@ -12335,8 +12335,8 @@ msgstr ""
# type: Content of: <refentry><refsect1><para>
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "Имена пользователей могут быть длиной не более 32 знаков."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "Имена пользователей могут быть длиной не более 256 знаков."
# type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
#. (itstool) path: listitem/para
diff --git a/man/po/shadow-man-pages.pot b/man/po/shadow-man-pages.pot
index fc39c1db..e4634bcf 100644
--- a/man/po/shadow-man-pages.pot
+++ b/man/po/shadow-man-pages.pot
@@ -9629,7 +9629,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
+msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para
diff --git a/man/po/sv.po b/man/po/sv.po
index 9dc652f3..818a2966 100644
--- a/man/po/sv.po
+++ b/man/po/sv.po
@@ -9476,7 +9476,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
+msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para
diff --git a/man/po/uk.po b/man/po/uk.po
index 08ab387e..307245f7 100644
--- a/man/po/uk.po
+++ b/man/po/uk.po
@@ -10023,8 +10023,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "Довжина імен користувачів не може перевищувати 32 символи."
+msgid "Usernames may only be up to 256 characters long."
+msgstr "Довжина імен користувачів не може перевищувати 256 символи."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789
diff --git a/man/po/zh_CN.po b/man/po/zh_CN.po
index 9644c519..7160da25 100644
--- a/man/po/zh_CN.po
+++ b/man/po/zh_CN.po
@@ -10474,8 +10474,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
-msgid "Usernames may only be up to 32 characters long."
-msgstr "用户名不能超过 32 个字符长。"
+msgid "Usernames may only be up to 256 characters long."
+msgstr "用户名不能超过 256 个字符长。"
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789
diff --git a/man/useradd.8.xml b/man/useradd.8.xml
index 067440ac..001e7d14 100644
--- a/man/useradd.8.xml
+++ b/man/useradd.8.xml
@@ -727,7 +727,7 @@
the <command>ls</command> output.
</para>
<para>
- Usernames may only be up to 32 characters long.
+ Usernames may only be up to 256 characters long.
</para>
</refsect1>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9ff6100b..6d2c0521 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -53,7 +53,6 @@ lib/pwdcheck.c
lib/pwio.c
lib/pwmem.c
lib/remove_tree.c
-lib/rlogin.c
lib/root_flag.c
lib/salt.c
lib/selinux.c
diff --git a/po/nl.po b/po/nl.po
index 5170d622..1b118f1f 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -1,14 +1,14 @@
# dutch po-file for shadow
# Copyright (C) 2004 Free Software Foundation, Inc.
# Bart Cornelis <cobaco@linux.be>, 2004, 2006.
-# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2014-2022.
+# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2014-2024.
#
msgid ""
msgstr ""
-"Project-Id-Version: shadow 4.12.2\n"
+"Project-Id-Version: shadow 4.15.1\n"
"Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n"
"POT-Creation-Date: 2024-03-14 18:23-0500\n"
-"PO-Revision-Date: 2022-09-27 17:08+0200\n"
+"PO-Revision-Date: 2024-05-09 12:30+0200\n"
"Last-Translator: Frans Spiesschaert <Frans.Spiesschaert@yucom.be>\n"
"Language-Team: Debian Dutch l10n Team <debian-l10n-dutch@lists.debian.org>\n"
"Language: nl\n"
@@ -237,10 +237,9 @@ msgstr "%s: Kon seteuid niet op %d instellen\n"
msgid "%s: Could not set caps\n"
msgstr "%s: Kon hoofdletters niet instellen\n"
-#, fuzzy, c-format
-#| msgid "%s: snprintf failed!\n"
+#, c-format
msgid "%s: stpeprintf failed!\n"
-msgstr "%s: snprintf is mislukt!\n"
+msgstr "%s: stpeprintf is mislukt!\n"
#, c-format
msgid "%s: open of %s failed: %s\n"
@@ -250,10 +249,9 @@ msgstr "%s: openen van %s mislukte: %s\n"
msgid "%s: write to %s failed: %s\n"
msgstr "%s: schrijven naar %s mislukte: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: open of %s failed: %s\n"
+#, c-format
msgid "%s: closing %s failed: %s\n"
-msgstr "%s: openen van %s mislukte: %s\n"
+msgstr "%s: sluiten van %s mislukte: %s\n"
msgid "Too many logins.\n"
msgstr "Te veel aanmeldingen.\n"
@@ -375,10 +373,9 @@ msgstr "%s: krijg geen toegang tot chroot-map %s: %s\n"
msgid "%s: unable to chroot to directory %s: %s\n"
msgstr "%s: chroot naar map %s lukt niet: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: cannot chdir to chroot directory %s: %s\n"
+#, c-format
msgid "%s: cannot chdir in chroot directory %s: %s\n"
-msgstr "%s: kan chdir naar chroot-map %s niet uitvoeren: %s\n"
+msgstr "%s: kan chdir in chroot-map %s niet uitvoeren: %s\n"
#, c-format
msgid ""
@@ -435,10 +432,9 @@ msgstr "Kan de SELinux-transactie niet beginnen\n"
msgid "Could not query seuser for %s\n"
msgstr "Kon de seuser van %s niet opvragen\n"
-#, fuzzy, c-format
-#| msgid "Could not set serange for %s\n"
+#, c-format
msgid "Could not set serange for %s to %s\n"
-msgstr "Kon de serange van %s niet instellen\n"
+msgstr "Kon de serange voor %s niet instellen op %s\n"
#, c-format
msgid "Could not set sename for %s\n"
@@ -517,7 +513,7 @@ msgstr "Kan %s niet uitvoeren"
#, c-format
msgid "Maximum subsystem depth reached\n"
-msgstr ""
+msgstr "Maximale diepte van het subsysteem bereikt\n"
#, c-format
msgid "Invalid root directory '%s'\n"
@@ -680,8 +676,6 @@ msgstr ""
msgid " -R, --root CHROOT_DIR directory to chroot into\n"
msgstr " -R, --root CHROOT_MAP basismap voor chroot\n"
-#, fuzzy
-#| msgid " -P, --prefix PREFIX_DI directory prefix\n"
msgid " -P, --prefix PREFIX_DIR directory prefix\n"
msgstr " -P, --prefix PREFIX_MAP map-prefix\n"
@@ -716,7 +710,7 @@ msgid "never"
msgstr "nooit"
msgid "future"
-msgstr ""
+msgstr "toekomst"
msgid "Last password change\t\t\t\t\t: "
msgstr "Laatste wachtwoordverandering\t\t\t\t: "
@@ -943,10 +937,9 @@ msgstr ""
" -s, --sha-rounds aantal rondes voor de SHA, BCRYPT\n"
" of YESCRYPT encryptie-algoritmes\n"
-#, fuzzy, c-format
-#| msgid "%s: unsupported crypt method: %s\n"
+#, c-format
msgid "%s: no crypt method defined\n"
-msgstr "%s: niet-ondersteunde encryptiemethode: %s\n"
+msgstr "%s: geen encryptiemethode gedefinieerd\n"
#, c-format
msgid "%s: %s flag is only allowed with the %s flag\n"
@@ -1001,15 +994,13 @@ msgstr ""
msgid "Login Shell"
msgstr "Login-shell"
-#, fuzzy, c-format
-#| msgid "%s: Cannot get the size of %s: %s\n"
+#, c-format
msgid "Cannot parse shell files: %s"
-msgstr "%s: kan grootte van %s niet opvragen: %s\n"
+msgstr "Kan shell-bestanden niet ontleden: %s"
-#, fuzzy, c-format
-#| msgid "%s: cannot create new defaults file: %s\n"
+#, c-format
msgid "Cannot evaluate entries in shell files: %s"
-msgstr "%s: kan geen nieuw bestand met standaardwaarden aanmaken: %s\n"
+msgstr "Kan items in shell-bestanden niet evalueren: %s"
#, c-format
msgid "You may not change the shell for '%s'.\n"
@@ -1023,10 +1014,9 @@ msgstr "De login-shell voor %s wordt aangepast\n"
msgid "%s: Invalid entry: %s\n"
msgstr "%s: ongeldig element: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: %s is an invalid shell\n"
+#, c-format
msgid "%s: Warning: %s is an invalid shell\n"
-msgstr "%s: %s is geen geldige shell\n"
+msgstr "%s: Waarschuwing: %s is geen geldige shell\n"
#, c-format
msgid "%s: %s is an invalid shell\n"
@@ -1286,10 +1276,9 @@ msgstr "Ongeldige lid-gebruikersnaam %s\n"
msgid "%s: '%s' is not a valid group name\n"
msgstr "%s: '%s' is geen geldige groepsnaam\n"
-#, fuzzy, c-format
-#| msgid "%s: Cannot open %s: %s\n"
+#, c-format
msgid "%s: cannot open %s: %s\n"
-msgstr "%s: kan bestand %s niet openen: %s\n"
+msgstr "%s: kan %s niet openen: %s\n"
#, c-format
msgid "%s: invalid group ID '%s'\n"
@@ -1566,10 +1555,6 @@ msgid ""
msgstr ""
" -b, --before DAGEN enkel lastlog-items ouder dan DAGEN tonen\n"
-#, fuzzy
-#| msgid ""
-#| " -C, --clear clear lastlog record of an user (usable "
-#| "only with -u)\n"
msgid ""
" -C, --clear clear lastlog record of a user (usable only "
"with -u)\n"
@@ -1742,15 +1727,12 @@ msgstr "Gebruik: logoutd\n"
msgid "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: gid-bereik [%lu-%lu) -> [%lu-%lu) niet toegestaan\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> "
-#| "<count> ] ... \n"
+#, c-format
msgid ""
"usage: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> "
"<count> ] ... \n"
msgstr ""
-"gebruik: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> "
+"gebruik: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> "
"<count> ] ... \n"
#, c-format
@@ -1773,21 +1755,17 @@ msgstr "%s: setgroups opzoeken mislukte: %s\n"
msgid "%s: failed to setgroups %s policy: %s\n"
msgstr "%s: setgroups-beleid %s mislukte: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: Could not stat directory for target %u\n"
+#, c-format
msgid "%s: Could not stat directory for process\n"
-msgstr "%s: Kon status van map voor doel %u niet opvragen\n"
+msgstr "%s: Kon status van map voor proces niet opvragen\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu "
-#| "st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
+#, c-format
msgid ""
"%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:"
"%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
msgstr ""
-"%s: Doelproces %u is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:"
-"%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
+"%s: Doelproces is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:%lu, "
+"gid:%lu pw_gid:%lu st_gid:%lu\n"
msgid "Usage: newgrp [-] [group]\n"
msgstr "Gebruik: newgrp [-] [groep]\n"
@@ -1819,21 +1797,17 @@ msgstr "te veel groepen\n"
msgid "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: uid-bereik [%lu-%lu) -> [%lu-%lu) niet toegestaan\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> "
-#| "<count> ] ... \n"
+#, c-format
msgid ""
"usage: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> "
"<count> ] ... \n"
msgstr ""
-"gebruik: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> "
+"gebruik: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> "
"<count> ] ... \n"
-#, fuzzy, c-format
-#| msgid "%s: Could not stat directory for target %u\n"
+#, c-format
msgid "%s: Could not stat directory for target process\n"
-msgstr "%s: Kon status van map voor doel %u niet opvragen\n"
+msgstr "%s: Kon status van map voor doelproces niet opvragen\n"
msgid " -b, --badname allow bad names\n"
msgstr " -b, --badname slechte namen toestaan\n"
@@ -1855,7 +1829,7 @@ msgstr "%s: ongeldige gebruikersnaam '%s': gebruik --badname om te negeren\n"
#, c-format
msgid "%s: Provide '--crypt-method' before number of rounds\n"
-msgstr ""
+msgstr "%s: Geef '--crypt-method' op vóór het aantal rondes\n"
#, c-format
msgid "%s: line %d: invalid line\n"
@@ -1879,10 +1853,9 @@ msgstr "%s: regel %d: kan de groep niet aanmaken\n"
msgid "%s: line %d: user '%s' does not exist in %s\n"
msgstr "%s: regel %d: gebruiker '%s' bestaat niet in %s\n"
-#, fuzzy, c-format
-#| msgid "%s: unlink: %s: %s\n"
+#, c-format
msgid "%s: line %d: %s\n"
-msgstr "%s: ontkoppelen: %s: %s\n"
+msgstr "%s: regel: %d: %s\n"
#, c-format
msgid "%s: line %d: can't update password\n"
@@ -1992,11 +1965,9 @@ msgstr ""
"wachtwoordwijziging\n"
" instellen op MAX_DAGEN\n"
-#, fuzzy
#| msgid " -l, --list show account aging information\n"
msgid " -s, --stdin read new token from stdin\n"
-msgstr ""
-" -l, --list verouderingsinformatie over accounts tonen\n"
+msgstr " -s, --stdin nieuw token lezen van stdin\n"
msgid "Old password: "
msgstr "Oud wachtwoord: "
@@ -2017,10 +1988,8 @@ msgstr ""
"Voer het nieuwe wachtwoord in (minimaal %d en maximaal %d tekens)\n"
"Gebruik een combinatie van grote en kleine letters en cijfers.\n"
-#, fuzzy
-#| msgid "%s: fields too long\n"
msgid "Password is too long.\n"
-msgstr "%s: velden zijn te lang\n"
+msgstr "Wachtwoord is te lang.\n"
msgid "New password: "
msgstr "Nieuw wachtwoord: "
@@ -2067,10 +2036,9 @@ msgstr ""
msgid "%s: repository %s not supported\n"
msgstr "%s: depot %s wordt niet ondersteund\n"
-#, fuzzy, c-format
-#| msgid "%s: only root can use the -g/--group option\n"
+#, c-format
msgid "%s: only root can use --stdin/-s option\n"
-msgstr "%s: enkel de systeembeheerder kan de optie -g/--group gebruiken\n"
+msgstr "%s: enkel de systeembeheerder kan de optie --stdin/-s gebruiken\n"
#, c-format
msgid "%s: root is not authorized by SELinux to change the password of %s\n"
@@ -2301,10 +2269,9 @@ msgstr "%s: U bent niet gerechtigd om op dat tijdstip 'su' uit te voeren\n"
msgid "No passwd entry for user '%s'\n"
msgstr "Geen wachtwoordregel voor gebruiker '%s'\n"
-#, fuzzy, c-format
-#| msgid "Invalid member username %s\n"
+#, c-format
msgid "Overlong user name '%s'\n"
-msgstr "Ongeldige lid-gebruikersnaam %s\n"
+msgstr "Te lange gebruikersnaam '%s'\n"
#, c-format
msgid "%s: must be run from a terminal\n"
@@ -2351,12 +2318,13 @@ msgstr "%s: %s was aangemaakt, maar kon niet verwijderd worden\n"
msgid "%s: the %s configuration in %s will be ignored\n"
msgstr "%s: de %s-instellingen in %s zullen genegeerd worden\n"
-#, fuzzy, c-format
-#| msgid "%s: the %s configuration in %s will be ignored\n"
+#, c-format
msgid ""
"%s: the '%s' configuration in %s has an invalid group, ignoring the bad "
"group\n"
-msgstr "%s: de %s-instellingen in %s zullen genegeerd worden\n"
+msgstr ""
+"%s: de configuratie van '%s' in %s heeft een ongeldige groep, deze groep "
+"wordt genegeerd\n"
#, c-format
msgid "%s: cannot create new defaults file: %s\n"
@@ -2458,6 +2426,8 @@ msgid ""
" -F, --add-subids-for-system add entries to sub[ud]id even when adding a "
"system user\n"
msgstr ""
+" -F, --add-subids-for-system items toevoegen aan sub[ud]id, zelfs bij het "
+"toevoegen van een systeemgebruiker\n"
msgid ""
" -g, --gid GROUP name or ID of the primary group of the new\n"
@@ -2537,15 +2507,11 @@ msgstr ""
" -Z, --selinux-user SEUSER een specifieke SEUSER gebruiken om de\n"
" gebruikerskoppeling voor SELinux te maken\n"
-#, fuzzy
-#| msgid ""
-#| " -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux "
-#| "user mapping\n"
msgid ""
" --selinux-range SERANGE use a specific MLS range for the SELinux "
"user mapping\n"
msgstr ""
-" -Z, --selinux-user SEUSER een specifieke SEUSER gebruiken om de\n"
+" --selinux-range SERANGE een specifiek MLS-bereik gebruiken om de\n"
" gebruikerskoppeling voor SELinux te maken\n"
#, c-format
@@ -2680,15 +2646,11 @@ msgstr ""
msgid "Setting mailbox file permissions"
msgstr "Bestandsrechten van postvak-bestand worden ingesteld"
-#, fuzzy
-#| msgid "Creating mailbox file"
msgid "Synchronize mailbox file"
-msgstr "Postvak-bestand wordt aangemaakt"
+msgstr "Postvak-bestand synchroniseren"
-#, fuzzy
-#| msgid "Creating mailbox file"
msgid "Closing mailbox file"
-msgstr "Postvak-bestand wordt aangemaakt"
+msgstr "Postvak-bestand wordt gesloten"
#, c-format
msgid "%s warning: %s's uid %d is greater than SYS_UID_MAX %d\n"
@@ -2954,14 +2916,10 @@ msgstr ""
" -Z, --selinux-user SEUSER nieuwe koppeling met SELinux-gebruiker voor\n"
" het gebruikersaccount\n"
-#, fuzzy
-#| msgid ""
-#| " -Z, --selinux-user SEUSER new SELinux user mapping for the user "
-#| "account\n"
msgid ""
" --selinux-range SERANGE new SELinux MLS range for the user account\n"
msgstr ""
-" -Z, --selinux-user SEUSER nieuwe koppeling met SELinux-gebruiker voor\n"
+" --selinux-range SERANGE nieuw SELinux MLS-bereik voor\n"
" het gebruikersaccount\n"
#, c-format
@@ -3045,16 +3003,13 @@ msgstr ""
msgid "%s: cannot rename directory %s to %s\n"
msgstr "%s: kan map %s niet hernoemen naar %s\n"
-#, fuzzy, c-format
-#| msgid ""
-#| "%s: The previous home directory (%s) was not a directory. It is not "
-#| "removed and no home directories are created.\n"
+#, c-format
msgid ""
"%s: The previous home directory (%s) does not exist or is inaccessible. Move "
"cannot be completed.\n"
msgstr ""
-"%s: De vroegere persoonlijke map (%s) was geen map. Ze werd niet verwijderd "
-"en er werden geen persoonlijke mappen aangemaakt.\n"
+"%s: De vroegere persoonlijke map (%s) bestaat niet of is ontoegankelijk. Het "
+"verplaatsen kan niet worden voltooid.\n"
#, c-format
msgid "%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"
@@ -3062,11 +3017,10 @@ msgstr ""
"%s: kopiëren van het lastlog-item van gebruiker %lu naar gebruiker %lu is "
"mislukt: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"
+#, c-format
msgid "%s: failed to copy the lastlog entry of user %ju to user %ju: %s\n"
msgstr ""
-"%s: kopiëren van het lastlog-item van gebruiker %lu naar gebruiker %lu is "
+"%s: kopiëren van het lastlog-item van gebruiker %ju naar gebruiker %ju is "
"mislukt: %s\n"
#, c-format
@@ -3075,11 +3029,10 @@ msgstr ""
"%s: kopiëren van het faillog-item van gebruiker %lu naar gebruiker %lu is "
"mislukt: %s\n"
-#, fuzzy, c-format
-#| msgid "%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"
+#, c-format
msgid "%s: failed to copy the faillog entry of user %ju to user %ju: %s\n"
msgstr ""
-"%s: kopiëren van het faillog-item van gebruiker %lu naar gebruiker %lu is "
+"%s: kopiëren van het faillog-item van gebruiker %ju naar gebruiker %ju is "
"mislukt: %s\n"
#, c-format
@@ -3183,10 +3136,8 @@ msgstr "ontkoppelen van initieel bestand is mislukt"
msgid "failed to stat edited file"
msgstr "opvragen van status van bewerkt bestand is mislukt"
-#, fuzzy
-#| msgid "%s: snprintf failed!\n"
msgid "asprintf(3) failed"
-msgstr "%s: snprintf is mislukt!\n"
+msgstr "asprintf(3) is mislukt"
msgid "failed to create backup file"
msgstr "maken van reservekopie is mislukt"
@@ -3198,34 +3149,3 @@ msgstr "%s: kan %s niet herstellen: %s (uw aanpassingen staan in %s)\n"
#, c-format
msgid "%s: failed to find tcb directory for %s\n"
msgstr "%s: tcb-map van %s vinden is mislukt\n"
-
-#, c-format
-#~ msgid "%s: Not enough arguments to form %u mappings\n"
-#~ msgstr "%s: Onvoldoende argumenten om %u-toewijzingen te vormen\n"
-
-#~ msgid "too simple"
-#~ msgstr "te simpel"
-
-#, c-format
-#~ msgid "Unable to obtain random bytes.\n"
-#~ msgstr "Kan geen willekeurige bytes verkrijgen.\n"
-
-#~ msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
-#~ msgstr ""
-#~ "Er is geen utmp-item. U dient \"login\" uit te voeren vanaf het laagste "
-#~ "niveau \"sh\""
-
-#, c-format
-#~ msgid "%s: Could not open proc directory for target %u\n"
-#~ msgstr "%s: Kon proc-map voor doel %u niet openen\n"
-
-#, c-format
-#~ msgid ""
-#~ "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:"
-#~ "%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
-#~ msgstr ""
-#~ "%s: Doel %u is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:%lu, "
-#~ "gid:%lu pw_gid:%lu st_gid:%lu\n"
-
-#~ msgid "failed to allocate memory"
-#~ msgstr "geheugen toekennen is mislukt"
diff --git a/src/check_subid_range.c b/src/check_subid_range.c
index 5dc0bd7d..68266f55 100644
--- a/src/check_subid_range.c
+++ b/src/check_subid_range.c
@@ -13,7 +13,7 @@
#include <sys/stat.h>
#include <fcntl.h>
-#include "atoi/strtou_noneg.h"
+#include "atoi/str2i.h"
#include "defines.h"
#include "prototypes.h"
#include "subordinateio.h"
@@ -36,11 +36,9 @@ int main(int argc, char **argv)
owner = argv[1];
check_uids = argv[2][0] == 'u';
errno = 0;
- start = strtoul_noneg(argv[3], NULL, 10);
- if (errno != 0)
+ if (str2ul(&start, argv[3]) == -1)
exit(1);
- count = strtoul_noneg(argv[4], NULL, 10);
- if (errno != 0)
+ if (str2ul(&count, argv[4]) == -1)
exit(1);
if (check_uids) {
if (have_sub_uids(owner, start, count))
diff --git a/src/getsubids.c b/src/getsubids.c
index fb645b19..871e850f 100644
--- a/src/getsubids.c
+++ b/src/getsubids.c
@@ -44,5 +44,6 @@ int main(int argc, char *argv[])
printf("%d: %s %lu %lu\n", i, owner,
ranges[i].start, ranges[i].count);
}
+ subid_free(ranges);
return 0;
}
diff --git a/src/groupmod.c b/src/groupmod.c
index a29cf73f..989d7ea3 100644
--- a/src/groupmod.c
+++ b/src/groupmod.c
@@ -250,8 +250,6 @@ static void grp_update (void)
if (!aflg) {
// requested to replace the existing groups
- if (NULL != grp.gr_mem[0])
- gr_free_members(&grp);
grp.gr_mem = XMALLOC(1, char *);
grp.gr_mem[0] = NULL;
} else {
diff --git a/src/login.c b/src/login.c
index a862c6bd..3a302983 100644
--- a/src/login.c
+++ b/src/login.c
@@ -27,6 +27,7 @@
#include "alloc.h"
#include "attr.h"
+#include "chkname.h"
#include "defines.h"
#include "faillog.h"
#include "failure.h"
@@ -84,11 +85,6 @@ static struct lastlog ll;
static bool pflg = false;
static bool fflg = false;
-#ifdef RLOGIN
-static bool rflg = false;
-#else /* RLOGIN */
-#define rflg false
-#endif /* !RLOGIN */
static bool hflg = false;
static bool preauth_flag = false;
@@ -133,7 +129,6 @@ static void exit_handler (int);
* usage - print login command usage and exit
*
* login [ name ]
- * login -r hostname (for rlogind)
* login -h hostname (for telnetd, etc.)
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
*/
@@ -144,9 +139,6 @@ static void usage (void)
exit (1);
}
fprintf (stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
-#ifdef RLOGIN
- fprintf (stderr, _(" %s [-p] -r host\n"), Prog);
-#endif /* RLOGIN */
exit (1);
}
@@ -270,7 +262,7 @@ static void process_flags (int argc, char *const *argv)
/*
* Check the flags for proper form. Every argument starting with
* "-" must be exactly two characters long. This closes all the
- * clever rlogin, telnet, and getty holes.
+ * clever telnet, and getty holes.
*/
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] == '-' && strlen (argv[arg]) > 2) {
@@ -297,13 +289,6 @@ static void process_flags (int argc, char *const *argv)
hostname = optarg;
reason = PW_TELNET;
break;
-#ifdef RLOGIN
- case 'r':
- rflg = true;
- hostname = optarg;
- reason = PW_RLOGIN;
- break;
-#endif /* RLOGIN */
case 'p':
pflg = true;
break;
@@ -312,21 +297,11 @@ static void process_flags (int argc, char *const *argv)
}
}
-#ifdef RLOGIN
- /*
- * Neither -h nor -f should be combined with -r.
- */
-
- if (rflg && (hflg || fflg)) {
- usage ();
- }
-#endif /* RLOGIN */
-
/*
* Allow authentication bypass only if real UID is zero.
*/
- if ((rflg || fflg || hflg) && !amroot) {
+ if ((fflg || hflg) && !amroot) {
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
exit (1);
}
@@ -341,11 +316,6 @@ static void process_flags (int argc, char *const *argv)
++optind;
}
-#ifdef RLOGIN
- if (rflg && (NULL != username)) {
- usage ();
- }
-#endif /* RLOGIN */
if (fflg && (NULL == username)) {
usage ();
}
@@ -473,7 +443,6 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
* the flags which login supports are
*
* -p - preserve the environment
- * -r - perform autologin protocol for rlogin
* -f - do not perform authentication, user is preauthenticated
* -h - the name of the remote host
*/
@@ -505,9 +474,6 @@ int main (int argc, char **argv)
char ptime[80];
# endif
#endif
-#if defined(RLOGIN)
- char term[128] = "";
-#endif
/*
* Some quick initialization.
@@ -558,7 +524,7 @@ int main (int argc, char **argv)
is_console = console (tty);
#endif
- if (rflg || hflg) {
+ if (hflg) {
/*
* Add remote hostname to the environment. I think
* (not sure) I saw it once on Irix. --marekm
@@ -571,22 +537,6 @@ int main (int argc, char **argv)
if (hflg) {
reason = PW_RLOGIN;
}
-#ifdef RLOGIN
- if (rflg) {
- size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
-
- assert (NULL == username);
- username = XMALLOC(max_size, char);
- username[max_size - 1] = '\0';
- if (do_rlogin(hostname, username, max_size, term, sizeof(term)))
- {
- preauth_flag = true;
- } else {
- free (username);
- username = NULL;
- }
- }
-#endif /* RLOGIN */
OPENLOG (Prog);
@@ -621,18 +571,11 @@ int main (int argc, char **argv)
}
}
-#ifdef RLOGIN
- if (term[0] != '\0') {
- addenv ("TERM", term);
- } else
-#endif /* RLOGIN */
- {
- /* preserve TERM from getty */
- if (!pflg) {
- tmp = getenv ("TERM");
- if (NULL != tmp) {
- addenv ("TERM", tmp);
- }
+ /* preserve TERM from getty */
+ if (!pflg) {
+ tmp = getenv ("TERM");
+ if (NULL != tmp) {
+ addenv ("TERM", tmp);
}
}
@@ -642,7 +585,7 @@ int main (int argc, char **argv)
set_env (argc - optind, &argv[optind]);
}
- if (rflg || hflg) {
+ if (hflg) {
cp = hostname;
} else if ((host != NULL) && (host[0] != '\0')) {
cp = host;
@@ -882,8 +825,9 @@ int main (int argc, char **argv)
failed = false; /* haven't failed authentication yet */
if (NULL == username) { /* need to get a login id */
- size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
+ size_t max_size;
+ max_size = login_name_max_size();
if (subroot) {
closelog ();
exit (1);
@@ -951,7 +895,7 @@ int main (int argc, char **argv)
}
/*
- * The -r and -f flags provide a name which has already
+ * The -f flag provides a name which has already
* been authenticated by some server.
*/
if (preauth_flag) {
@@ -1040,8 +984,8 @@ int main (int argc, char **argv)
(void) puts (_("Login incorrect"));
- /* allow only one attempt with -r or -f */
- if (rflg || fflg || (retries <= 0)) {
+ /* allow only one attempt with -f */
+ if (fflg || (retries <= 0)) {
closelog ();
exit (1);
}
diff --git a/src/useradd.c b/src/useradd.c
index ec21814c..347334a6 100644
--- a/src/useradd.c
+++ b/src/useradd.c
@@ -238,6 +238,9 @@ static void create_home (void);
static void create_mail (void);
static void check_uid_range(int rflg, uid_t user_id);
+static FILE *fmkstemp(char *template);
+
+
/*
* fail_exit - undo as much as possible
*/
@@ -524,7 +527,6 @@ static void show_defaults (void)
*/
static int set_defaults (void)
{
- int ofd;
int ret = -1;
bool out_group = false;
bool out_groups = false;
@@ -558,7 +560,7 @@ static int set_defaults (void)
fprintf(stderr,
_("%s: cannot create new defaults file: %s\n"),
Prog, strerror(errno));
- goto setdef_err;
+ goto err_free_new;
}
}
@@ -567,36 +569,27 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: cannot create directory for defaults file\n"),
Prog);
- goto setdef_err;
+ goto err_free_def;
}
ret = mkdir(dirname(new_file_dup), 0755);
+ free(new_file_dup);
if (-1 == ret && EEXIST != errno) {
fprintf (stderr,
_("%s: cannot create directory for defaults file\n"),
Prog);
- free(new_file_dup);
- goto setdef_err;
+ goto err_free_def;
}
- free(new_file_dup);
/*
* Create a temporary file to copy the new output to.
*/
- ofd = mkstemp (new_file);
- if (-1 == ofd) {
- fprintf (stderr,
- _("%s: cannot create new defaults file\n"),
- Prog);
- goto setdef_err;
- }
-
- ofp = fdopen (ofd, "w");
+ ofp = fmkstemp(new_file);
if (NULL == ofp) {
fprintf (stderr,
_("%s: cannot open new defaults file\n"),
Prog);
- goto setdef_err;
+ goto err_free_def;
}
/*
@@ -622,8 +615,9 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: line too long in %s: %s..."),
Prog, default_file, buf);
- (void) fclose (ifp);
- goto setdef_err;
+ fclose(ifp);
+ fclose(ofp);
+ goto err_free_def;
}
}
@@ -702,9 +696,10 @@ static int set_defaults (void)
(void) fflush (ofp);
if ( (ferror (ofp) != 0)
|| (fsync (fileno (ofp)) != 0)
- || (fclose (ofp) != 0)) {
+ || (fclose (ofp) != 0))
+ {
unlink (new_file);
- goto setdef_err;
+ goto err_free_def;
}
/*
@@ -718,7 +713,7 @@ static int set_defaults (void)
_("%s: Cannot create backup file (%s): %s\n"),
Prog, buf, strerror (err));
unlink (new_file);
- goto setdef_err;
+ goto err_free_def;
}
/*
@@ -729,7 +724,7 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: rename: %s: %s\n"),
Prog, new_file, strerror (err));
- goto setdef_err;
+ goto err_free_def;
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USYS_CONFIG, Prog,
@@ -744,11 +739,12 @@ static int set_defaults (void)
def_inactive, def_expire, def_template,
def_create_mail_spool, def_log_init));
ret = 0;
- setdef_err:
- free(new_file);
- if (prefix[0]) {
+
+err_free_def:
+ if (prefix[0])
free(default_file);
- }
+err_free_new:
+ free(new_file);
return ret;
}
@@ -857,14 +853,14 @@ static int get_groups (char *list)
*/
static struct group * get_local_group(char * grp_name)
{
+ char *end;
const struct group *grp;
struct group *result_grp = NULL;
long long gid;
- char *endptr;
- gid = strtoll (grp_name, &endptr, 10);
+ gid = strtoll(grp_name, &end, 10);
if ( ('\0' != *grp_name)
- && ('\0' == *endptr)
+ && ('\0' == *end)
&& (ERANGE != errno)
&& (gid == (gid_t)gid)) {
grp = gr_locate_gid (gid);
@@ -2751,3 +2747,23 @@ int main (int argc, char **argv)
return E_SUCCESS;
}
+
+static FILE *
+fmkstemp(char *template)
+{
+ int fd;
+ FILE *fp;
+
+ fd = mkstemp(template);
+ if (fd == -1)
+ return NULL;
+
+ fp = fdopen(fd, "w");
+ if (fp == NULL) {
+ close(fd);
+ unlink(template);
+ return NULL;
+ }
+
+ return fp;
+}
diff --git a/src/usermod.c b/src/usermod.c
index 0fcf0325..f8896984 100644
--- a/src/usermod.c
+++ b/src/usermod.c
@@ -178,10 +178,12 @@ NORETURN static void usage (int status);
static void new_pwent (struct passwd *);
static void new_spent (struct spwd *);
NORETURN static void fail_exit (int);
-static void update_group (void);
+static void update_group_file(void);
+static void update_group(const struct group *grp);
#ifdef SHADOWGRP
-static void update_gshadow (void);
+static void update_gshadow_file(void);
+static void update_gshadow(const struct sgrp *sgrp);
#endif
static void grp_update (void);
@@ -685,263 +687,277 @@ fail_exit (int code)
}
-static void update_group (void)
+static void
+update_group_file(void)
{
- bool is_member;
- bool was_member;
- bool changed;
- const struct group *grp;
- struct group *ngrp;
-
- changed = false;
+ const struct group *grp;
/*
* Scan through the entire group file looking for the groups that
* the user is a member of.
*/
- while ((grp = gr_next ()) != NULL) {
- /*
- * See if the user specified this group as one of their
- * concurrent groups.
- */
- was_member = is_on_list (grp->gr_mem, user_name);
- is_member = Gflg && ( (was_member && aflg)
- || is_on_list (user_groups, grp->gr_name));
+ while ((grp = gr_next()) != NULL)
+ update_group(grp);
+}
- if (!was_member && !is_member) {
- continue;
- }
- /*
- * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes
- * mentioned groups while leaving the others.
- */
- if (Gflg && rflg) {
- is_member = !is_member;
- }
+static void
+update_group(const struct group *grp)
+{
+ bool changed;
+ bool is_member;
+ bool was_member;
+ struct group *ngrp;
- ngrp = __gr_dup (grp);
- if (NULL == ngrp) {
- fprintf (stderr,
- _("%s: Out of memory. Cannot update %s.\n"),
- Prog, gr_dbname ());
- fail_exit (E_GRP_UPDATE);
- }
+ changed = false;
- if (was_member) {
- if ((!Gflg) || is_member) {
- /* User was a member and is still a member
- * of this group.
- * But the user might have been renamed.
- */
- if (lflg) {
- ngrp->gr_mem = del_list (ngrp->gr_mem,
- user_name);
- ngrp->gr_mem = add_list (ngrp->gr_mem,
- user_newname);
- changed = true;
-#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "changing group member",
- user_newname, AUDIT_NO_ID, 1);
-#endif
- SYSLOG ((LOG_INFO,
- "change '%s' to '%s' in group '%s'",
- user_name, user_newname,
- ngrp->gr_name));
- }
- } else {
- /* User was a member but is no more a
- * member of this group.
- */
- ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+ was_member = is_on_list (grp->gr_mem, user_name);
+ is_member = Gflg && ( (was_member && aflg)
+ || is_on_list (user_groups, grp->gr_name));
+
+ if (!was_member && !is_member)
+ return;
+
+ /*
+ * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes
+ * mentioned groups while leaving the others.
+ */
+ if (Gflg && rflg) {
+ is_member = !is_member;
+ }
+
+ ngrp = __gr_dup (grp);
+ if (NULL == ngrp) {
+ fprintf (stderr,
+ _("%s: Out of memory. Cannot update %s.\n"),
+ Prog, gr_dbname ());
+ fail_exit (E_GRP_UPDATE);
+ }
+
+ if (was_member) {
+ if ((!Gflg) || is_member) {
+ /* User was a member and is still a member
+ * of this group.
+ * But the user might have been renamed.
+ */
+ if (lflg) {
+ ngrp->gr_mem = del_list (ngrp->gr_mem,
+ user_name);
+ ngrp->gr_mem = add_list (ngrp->gr_mem,
+ user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "removing group member",
- user_name, AUDIT_NO_ID, 1);
+ "changing group member",
+ user_newname, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
- "delete '%s' from group '%s'",
- user_name, ngrp->gr_name));
+ "change '%s' to '%s' in group '%s'",
+ user_name, user_newname,
+ ngrp->gr_name));
}
- } else if (is_member) {
- /* User was not a member but is now a member this
- * group.
+ } else {
+ /* User was a member but is no more a
+ * member of this group.
*/
- ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname);
+ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "adding user to group",
- user_name, AUDIT_NO_ID, 1);
+ "removing group member",
+ user_name, AUDIT_NO_ID, 1);
#endif
- SYSLOG ((LOG_INFO, "add '%s' to group '%s'",
- user_newname, ngrp->gr_name));
- }
- if (!changed) {
- continue;
- }
-
- changed = false;
- if (gr_update (ngrp) == 0) {
- fprintf (stderr,
- _("%s: failed to prepare the new %s entry '%s'\n"),
- Prog, gr_dbname (), ngrp->gr_name);
- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name));
- fail_exit (E_GRP_UPDATE);
+ SYSLOG ((LOG_INFO,
+ "delete '%s' from group '%s'",
+ user_name, ngrp->gr_name));
}
+ } else if (is_member) {
+ /* User was not a member but is now a member this
+ * group.
+ */
+ ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname);
+ changed = true;
+#ifdef WITH_AUDIT
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ "adding user to group",
+ user_name, AUDIT_NO_ID, 1);
+#endif
+ SYSLOG ((LOG_INFO, "add '%s' to group '%s'",
+ user_newname, ngrp->gr_name));
+ }
+ if (!changed)
+ goto free_ngrp;
- gr_free(ngrp);
+ if (gr_update (ngrp) == 0) {
+ fprintf (stderr,
+ _("%s: failed to prepare the new %s entry '%s'\n"),
+ Prog, gr_dbname (), ngrp->gr_name);
+ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name));
+ fail_exit (E_GRP_UPDATE);
}
+
+free_ngrp:
+ gr_free(ngrp);
}
+
#ifdef SHADOWGRP
-static void update_gshadow (void)
+static void
+update_gshadow_file(void)
{
- bool is_member;
- bool was_member;
- bool was_admin;
- bool changed;
- const struct sgrp *sgrp;
- struct sgrp *nsgrp;
-
- changed = false;
+ const struct sgrp *sgrp;
/*
* Scan through the entire shadow group file looking for the groups
* that the user is a member of.
*/
- while ((sgrp = sgr_next ()) != NULL) {
+ while ((sgrp = sgr_next()) != NULL)
+ update_gshadow(sgrp);
+}
+#endif /* SHADOWGRP */
- /*
- * See if the user was a member of this group
- */
- was_member = is_on_list (sgrp->sg_mem, user_name);
- /*
- * See if the user was an administrator of this group
- */
- was_admin = is_on_list (sgrp->sg_adm, user_name);
+#ifdef SHADOWGRP
+static void
+update_gshadow(const struct sgrp *sgrp)
+{
+ bool changed;
+ bool is_member;
+ bool was_member;
+ bool was_admin;
+ struct sgrp *nsgrp;
- /*
- * See if the user specified this group as one of their
- * concurrent groups.
- */
- is_member = Gflg && ( (was_member && aflg)
- || is_on_list (user_groups, sgrp->sg_name));
+ changed = false;
- if (!was_member && !was_admin && !is_member) {
- continue;
- }
+ /*
+ * See if the user was a member of this group
+ */
+ was_member = is_on_list (sgrp->sg_mem, user_name);
- /*
- * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted
- * groups while leaving the user apart of groups not mentioned
- */
- if (Gflg && rflg) {
- is_member = !is_member;
- }
+ /*
+ * See if the user was an administrator of this group
+ */
+ was_admin = is_on_list (sgrp->sg_adm, user_name);
- nsgrp = __sgr_dup (sgrp);
- if (NULL == nsgrp) {
- fprintf (stderr,
- _("%s: Out of memory. Cannot update %s.\n"),
- Prog, sgr_dbname ());
- fail_exit (E_GRP_UPDATE);
- }
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
+ is_member = Gflg && ( (was_member && aflg)
+ || is_on_list (user_groups, sgrp->sg_name));
- if (was_admin && lflg) {
- /* User was an admin of this group but the user
- * has been renamed.
- */
- nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
- nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
- changed = true;
-#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "changing admin name in shadow group",
- user_name, AUDIT_NO_ID, 1);
-#endif
- SYSLOG ((LOG_INFO,
- "change admin '%s' to '%s' in shadow group '%s'",
- user_name, user_newname, nsgrp->sg_name));
- }
-
- if (was_member) {
- if ((!Gflg) || is_member) {
- /* User was a member and is still a member
- * of this group.
- * But the user might have been renamed.
- */
- if (lflg) {
- nsgrp->sg_mem = del_list (nsgrp->sg_mem,
- user_name);
- nsgrp->sg_mem = add_list (nsgrp->sg_mem,
- user_newname);
- changed = true;
+ if (!was_member && !was_admin && !is_member)
+ return;
+
+ /*
+ * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted
+ * groups while leaving the user apart of groups not mentioned
+ */
+ if (Gflg && rflg) {
+ is_member = !is_member;
+ }
+
+ nsgrp = __sgr_dup (sgrp);
+ if (NULL == nsgrp) {
+ fprintf (stderr,
+ _("%s: Out of memory. Cannot update %s.\n"),
+ Prog, sgr_dbname ());
+ fail_exit (E_GRP_UPDATE);
+ }
+
+ if (was_admin && lflg) {
+ /* User was an admin of this group but the user
+ * has been renamed.
+ */
+ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
+ nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
+ changed = true;
#ifdef WITH_AUDIT
- audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "changing member in shadow group",
- user_name, AUDIT_NO_ID, 1);
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ "changing admin name in shadow group",
+ user_name, AUDIT_NO_ID, 1);
#endif
- SYSLOG ((LOG_INFO,
- "change '%s' to '%s' in shadow group '%s'",
- user_name, user_newname,
- nsgrp->sg_name));
- }
- } else {
- /* User was a member but is no more a
- * member of this group.
- */
- nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
+ SYSLOG ((LOG_INFO,
+ "change admin '%s' to '%s' in shadow group '%s'",
+ user_name, user_newname, nsgrp->sg_name));
+ }
+
+ if (was_member) {
+ if ((!Gflg) || is_member) {
+ /* User was a member and is still a member
+ * of this group.
+ * But the user might have been renamed.
+ */
+ if (lflg) {
+ nsgrp->sg_mem = del_list (nsgrp->sg_mem,
+ user_name);
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem,
+ user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "removing user from shadow group",
- user_name, AUDIT_NO_ID, 1);
+ "changing member in shadow group",
+ user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
- "delete '%s' from shadow group '%s'",
- user_name, nsgrp->sg_name));
+ "change '%s' to '%s' in shadow group '%s'",
+ user_name, user_newname,
+ nsgrp->sg_name));
}
- } else if (is_member) {
- /* User was not a member but is now a member this
- * group.
+ } else {
+ /* User was a member but is no more a
+ * member of this group.
*/
- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname);
+ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
- "adding user to shadow group",
- user_newname, AUDIT_NO_ID, 1);
+ "removing user from shadow group",
+ user_name, AUDIT_NO_ID, 1);
#endif
- SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'",
- user_newname, nsgrp->sg_name));
- }
- if (!changed) {
- continue;
+ SYSLOG ((LOG_INFO,
+ "delete '%s' from shadow group '%s'",
+ user_name, nsgrp->sg_name));
}
-
- changed = false;
-
- /*
- * Update the group entry to reflect the changes.
+ } else if (is_member) {
+ /* User was not a member but is now a member this
+ * group.
*/
- if (sgr_update (nsgrp) == 0) {
- fprintf (stderr,
- _("%s: failed to prepare the new %s entry '%s'\n"),
- Prog, sgr_dbname (), nsgrp->sg_name);
- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'",
- sgr_dbname (), nsgrp->sg_name));
- fail_exit (E_GRP_UPDATE);
- }
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname);
+ changed = true;
+#ifdef WITH_AUDIT
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
+ "adding user to shadow group",
+ user_newname, AUDIT_NO_ID, 1);
+#endif
+ SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'",
+ user_newname, nsgrp->sg_name));
+ }
+ if (!changed)
+ goto free_nsgrp;
- free (nsgrp);
+ /*
+ * Update the group entry to reflect the changes.
+ */
+ if (sgr_update (nsgrp) == 0) {
+ fprintf (stderr,
+ _("%s: failed to prepare the new %s entry '%s'\n"),
+ Prog, sgr_dbname (), nsgrp->sg_name);
+ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'",
+ sgr_dbname (), nsgrp->sg_name));
+ fail_exit (E_GRP_UPDATE);
}
+
+free_nsgrp:
+ free (nsgrp);
}
#endif /* SHADOWGRP */
+
/*
* grp_update - add user to secondary group set
*
@@ -950,10 +966,10 @@ static void update_gshadow (void)
*/
static void grp_update (void)
{
- update_group ();
+ update_group_file();
#ifdef SHADOWGRP
if (is_shadow_grp) {
- update_gshadow ();
+ update_gshadow_file();
}
#endif
}
diff --git a/tests/bug332198-test.exp b/tests/bug332198-test.exp
deleted file mode 100755
index fd365bb6..00000000
--- a/tests/bug332198-test.exp
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/expect -f
-
-# This is a script for repeatedly logging into the localhost
-# using `rlogin` in order to apparently see a symptoms described
-# in bug #332198.
-# As described in the bug log, sometimes `rlogind` will fail to
-# establish a connection, because it starts "login" process and
-# the latter fails with "unable to determine TTY name, got /dev/pts/1"
-# message.
-#
-# BUGS
-#
-# * the script rlogins to localhost
-# * the script doesn't handle passwdord prompt, because it's intended
-# to use .rhosts auth and expects shell prompt immediately after
-# `rlogin`
-# * the regexp for shell prompt is hardcoded
-
-log_user 0
-match_max 8192
-
-while {1} {
- set rlogin_spawn [spawn rlogin localhost]
- if { $rlogin_spawn == 0 } { exit 1 }
- expect {
- -timeout 10 -re "^.*(Last login\[^\r\n\]*).*\n(\[^\r\n\]*\[#$\] )$" {
- send_error "$expect_out(1,string)\n"
- send_error "$expect_out(2,string)\n"
-# send_error "$expect_out(0,string)\n"
- }
- timeout {
- send_error "TIMEOUT/prompt\n"
- send_error "$expect_out(buffer)\n"
- send_error "RETRYING\n"
- log_user 1
- send "tty /\r"
- expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
- send "tty /\r"
- expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
- send_error "\n"
- exit 2
- }
- }
- send "tty\r"
- expect {
- -timeout 4 -re "tty\r?\n(\[^\r\n\]*)\r?\n(\[^\r\n\]*\[#$\] )$" {
- send_error "$expect_out(2,string)$expect_out(1,string)\n"
-# send_error "$expect_out(0,string)\n"
- }
- timeout { send_error "TIMEOUT/tty\n" ; exit 3 }
- }
- send "exit\r"
- expect {
- -timeout 2 eof {
-# send_error "OK4: EOF\n"
- }
- timeout { send_error "TIMEOUT/eof\n" ; exit 4 }
- }
- wait
-}
-# vi: set sw=4:
diff --git a/tests/libsubid/04_nss/libsubid_zzz.c b/tests/libsubid/04_nss/libsubid_zzz.c
index 1a9de237..5ba3df95 100644
--- a/tests/libsubid/04_nss/libsubid_zzz.c
+++ b/tests/libsubid/04_nss/libsubid_zzz.c
@@ -138,3 +138,8 @@ enum subid_status shadow_subid_list_owner_ranges(const char *owner, enum subid_t
return SUBID_STATUS_SUCCESS;
}
+
+void shadow_subid_free(void *ptr)
+{
+ free(ptr);
+}
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
index 228d8796..d89367a3 100644
--- a/tests/unit/Makefile.am
+++ b/tests/unit/Makefile.am
@@ -6,7 +6,6 @@ TESTS = $(check_PROGRAMS)
check_PROGRAMS = \
test_adds \
test_atoi_strtoi \
- test_atoi_strtou_noneg \
test_chkname \
test_sprintf \
test_strncpy \
@@ -48,19 +47,6 @@ test_atoi_strtoi_LDADD = \
$(CMOCKA_LIBS) \
$(NULL)
-test_atoi_strtou_noneg_SOURCES = \
- ../../lib/atoi/strtou_noneg.c \
- test_atoi_strtou_noneg.c \
- $(NULL)
-test_atoi_strtou_noneg_CFLAGS = \
- $(AM_CFLAGS) \
- $(NULL)
-test_atoi_strtou_noneg_LDFLAGS = \
- $(NULL)
-test_atoi_strtou_noneg_LDADD = \
- $(CMOCKA_LIBS) \
- $(NULL)
-
test_chkname_SOURCES = \
../../lib/chkname.c \
test_chkname.c \
diff --git a/tests/unit/test_atoi_strtou_noneg.c b/tests/unit/test_atoi_strtou_noneg.c
deleted file mode 100644
index 978bc0c4..00000000
--- a/tests/unit/test_atoi_strtou_noneg.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
-// SPDX-License-Identifier: BSD-3-Clause
-
-
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdlib.h>
-
-#include <stdarg.h> // Required by <cmocka.h>
-#include <stddef.h> // Required by <cmocka.h>
-#include <setjmp.h> // Required by <cmocka.h>
-#include <stdint.h> // Required by <cmocka.h>
-#include <cmocka.h>
-
-#include "atoi/strtou_noneg.h"
-
-
-static void test_strtoul_noneg(void **state);
-static void test_strtoull_noneg(void **state);
-
-
-int
-main(void)
-{
- const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_strtoul_noneg),
- cmocka_unit_test(test_strtoull_noneg),
- };
-
- return cmocka_run_group_tests(tests, NULL, NULL);
-}
-
-
-static void
-test_strtoul_noneg(void **state)
-{
- errno = 0;
- assert_true(strtoul_noneg("42", NULL, 0) == 42);
- assert_true(errno == 0);
-
- assert_true(strtoul_noneg("-1", NULL, 0) == 0);
- assert_true(errno == ERANGE);
- errno = 0;
- assert_true(strtoul_noneg("-3", NULL, 0) == 0);
- assert_true(errno == ERANGE);
- errno = 0;
- assert_true(strtoul_noneg("-0xFFFFFFFFFFFFFFFF", NULL, 0) == 0);
- assert_true(errno == ERANGE);
-
- errno = 0;
- assert_true(strtoul_noneg("-0x10000000000000000", NULL, 0) == 0);
- assert_true(errno == ERANGE);
-}
-
-
-static void
-test_strtoull_noneg(void **state)
-{
- errno = 0;
- assert_true(strtoull_noneg("42", NULL, 0) == 42);
- assert_true(errno == 0);
-
- assert_true(strtoull_noneg("-1", NULL, 0) == 0);
- assert_true(errno == ERANGE);
- errno = 0;
- assert_true(strtoull_noneg("-3", NULL, 0) == 0);
- assert_true(errno == ERANGE);
- errno = 0;
- assert_true(strtoull_noneg("-0xFFFFFFFFFFFFFFFF", NULL, 0) == 0);
- assert_true(errno == ERANGE);
-
- errno = 0;
- assert_true(strtoull_noneg("-0x10000000000000000", NULL, 0) == 0);
- assert_true(errno == ERANGE);
-}