Compare commits

...

46 Commits

Author SHA1 Message Date
Hadi Chokr
08f27babeb etc/pam.d/: Remove the old unused PAM configs for setuid account tools
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2026-01-29 19:14:33 +01:00
Hadi Chokr
ed61576cba src/: Disable and remove account-tools-setuid conditionals
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2026-01-29 19:14:33 +01:00
Hadi Chokr
0829017c4c configure.ac: permanently remove setuid account management tools
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2026-01-29 19:14:33 +01:00
Adam Williamson
b702d4c43f lib/chkhash.c: fix escaping in SHA-256 / SHA-512 / MD5 regexes
`\\n` inside square brackets doesn't include or exclude the
newline character. It includes or excludes a literal slash and
the literal character 'n'.

Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e")
Closes: <https://github.com/shadow-maint/shadow/issues/1519>
Signed-off-by: Adam Williamson <awilliam@redhat.com>
2026-01-29 12:32:16 +01:00
Serge Hallyn
6f5a158b06 man/po: copy over login.defs.d/*.xml
When doing update-po, we copy man/*.xml into a tempdir, but
some of those files reference login.defs.d/*.xml, so copy
over those as well.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
Tested-by: Alejandro Colomar <alx@kernel.org>
2026-01-25 20:36:26 -06:00
Alejandro Colomar
6be13b2f84 man/shadow.5.xml: Document "*"
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-23 16:42:06 +01:00
Alejandro Colomar
9a86c515a1 lib/chkhash.c: is_valid_hash(): Comment meaning of !hash and *
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-23 16:42:06 +01:00
Alejandro Colomar
bce404a7a8 lib/chkhash.c: is_valid_hash(): Update comment
This checks the entire shadow(5) 2nd field, which is more than just
a hash.

Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-23 16:42:06 +01:00
Alejandro Colomar
9b67543987 lib/chkhash.c: is_valid_hash(): Accept an empty hash
It represents a passwordless account.
That is discouraged, but accepted.

Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e")
Link: <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124835>
Reported-by: Marc 'Zugschlus' Haber <mh+githubvisible@zugschlus.de>
Reported-by: "Serge E. Hallyn" <serge@hallyn.com>
Reported-by: Adam Williamson <awilliam@redhat.com>
Co-authored-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-23 16:42:06 +01:00
Iker Pedrosa
0e167e2a02 tests/system/framework/utils/tools.py: apply style fix for tuple unpacking
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2026-01-23 15:51:42 +01:00
Alejandro Colomar
958b485999 Revert "src/usermod.c: Remove optimizations"
This wasn't only an optimization; it also skipped some checks that were
now spuriously triggering errors.  We may be able to get rid of the
optimizations, but that will need more analysis.  For now, let's revert
to a known-good state.

Fixes: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations")
Reverts: 6a8a25dc7de6 (2025-10-15; "src/usermod.c: Remove optimizations")
Closes: <https://github.com/shadow-maint/shadow/issues/1509>
Reported-by: Adam Williamson <awilliam@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-19 10:13:52 +01:00
Alejandro Colomar
a49d2acdb4 src/usermod.c: -U: Report E_PASSWORDLESS on error due to passwordless account
Reproducer:

	$ useradd foo
	$ grep foo /etc/passwd /etc/shadow
	/etc/passwd:foo:x:1001:1001::/home/foo:/usr/bin/bash
	/etc/shadow:foo:!:20458:0:99999:7:::
	$ usermod -U testuser
	usermod: unlocking the user's password would result in a passwordless account.
	You should set a password with usermod -p to unlock this user's password.
	$ echo $?
	0
	$ grep foo /etc/passwd /etc/shadow
	/etc/passwd:foo:x:1001:1001::/home/foo:/usr/bin/bash
	/etc/shadow:foo:!:20458:0:99999:7:::

The program failed (didn't change anything, and reported the problem to
stderr) but reported success (0).  After this patch, the error is
reported as E_PASSWORDLESS (20).

Closes: <https://github.com/shadow-maint/shadow/issues/1479>
Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Acked-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-15 13:16:17 +01:00
Tobias Stoeckmann
b43089bcf1 lib/commonio.c: Drop lrename
The lrename function follows symlinks when renaming files. Since the
source is a temporary file and the target is the database file itself,
which is opened with O_NOFOLLOW, this function is only useful for an
attacker who manages to win some form of race.

Fixes: 0fa908302660 (2007-10-07; "[svn-upgrade] Integrating new upstream version, shadow (4.0.16)")
Fixes: 391a3847157c (2010-03-04; "2010-01-30  Paweł Hajdan, Jr.  <phajdan.jr@gentoo.org>")
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 23:56:46 +01:00
Tobias Stoeckmann
6cd3dcbbcc lib/commonio.c: Call utime for correct target
Since tmpf has been already renamed to target at this point, call utime
with target instead of tmpf.

Fixes: f8732b17dd1d (2026-01-14; "lib/commonio.c: Use unpredictable temporary names")
Reported-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 23:43:01 +01:00
Tobias Stoeckmann
65668fe093 vipw: Set correct pattern for fmkomstemp
The fmkomstemp call requires a suffix of XXXXXX for correct operation.
Do so in TCB case as well.

Note: If something fails and the file resides in this directory, it
could be interpreted as a username. Use the ',' character as an illegal
character to prevent shadow tools from erroneously accessing this file
and assuming that the user actually exists.

Fixes: a5b3d56e2902 (2026-01-09; "vipw: Use fmkomstemp for temporary file")
Reported-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 23:41:40 +01:00
Tobias Stoeckmann
f4777ac542 vipw: Set ownership, then mode
This is a safer approach, which handles cases in which a file would have
less permissions for a group than others.

A rare edge case, but let's be safe than sorry.

Reported-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 20:56:24 +01:00
Tobias Stoeckmann
976b7bffde vipw: Prefer fchmod/fchown over chmod/chown
Use file descriptor functions when file descriptor is available, instead
of path based operations. The latter resolve symbolic links and are
prone to race conditions.

Reported-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 20:56:24 +01:00
Tobias Stoeckmann
c745eea4a4 lib/commonio.c: Larger buffer size for file names
Make sure that enough bytes exist for file name of temporary file which
is used to construct the next database file.

While at it, use a better variable name.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 13:05:45 +01:00
Tobias Stoeckmann
f8732b17dd lib/commonio.c: Use unpredictable temporary names
Make sure that an attacker with sufficient privileges cannot simply
create a file with expected temporary name to retrieve content of
previous and/or future database.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 13:05:45 +01:00
Tobias Stoeckmann
a472091869 lib/commonio.c: Unlink backup file on error
It doesn't make sense to keep a file around if it's not even a proper
backup.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-14 13:05:45 +01:00
Tobias Stoeckmann
d5638a5b2b lib/shadowlog_internal.h: Hide shadow_progname
Accessing and setting shadow_progname is not as straight-forward as it
might seem due to the way of linking libshadow_la with libsubid and
programs.

Enforce the usage of log_get_progname to make this less messy.

With last entry of shadowlog_internal.h gone, remove the file entirely.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-12 14:27:05 +01:00
Tobias Stoeckmann
ecaae2f8cd lib/shadowlog_internal.h: Drop shadow_logfd
Accessing this variable directly is a recipe for disaster, because
binaries and libraries can have different versions in them due to how
libshadow_la linking is performed.

Make sure that at least NULL check is always performed by calling the
proper getter function.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-12 14:27:05 +01:00
Tobias Stoeckmann
828f465cd2 libsubid: Avoid shadow_logfd as variable name
A global shadow_logfd variable exists, so this effectively shadows it.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-12 14:27:05 +01:00
Iker Pedrosa
eec97ce4c5 Remove unused logoutd utility
Link: <https://github.com/shadow-maint/shadow/issues/999>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2026-01-12 13:27:48 +01:00
Tobias Stoeckmann
f051423a5a src/: Properly set up libsubid tools
Do not call any shadowlog functions directly from program source files
which are also linked with libsubid.

Both, the program and the library, will have their own version of the
static variables within shadowlog.c and thus would have different
logging mechanisms.

Use subid_init instead.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-12 01:56:27 +01:00
Tobias Stoeckmann
bd5fadaf29 su: Use exit instead of _exit in kill_child
Since this is no signal handler anymore, allow regular exit routine to
flush stderr etc.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
268961e044 su: Mark kill_child with NORETURN
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
cb31772d7f su: Remove dead code
The pid_child is never 0 when reaching kill_child, since kill_child
is called within an if-block which checks explicitly for pid_child not
being 0.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
67bcd85b77 su: Turn pid_child into local variable
The pid_child can be passed into kill_child, since it is no signal
handler anymore.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
2852d7aeed su: Drop unneeded char buffers
Since kill_child is no signal handler any longer, it is safe to call the
gettext macros directly and only when needed.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
b42b1cc9b9 su: Kill child outside of signal handler
This simplifies the alarm handler to just set a volatile
sig_atomic_t like catch_signals does, which makes the handler way
easier to review.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
8800423a8a su: Turn caught into volatile sig_atomic_t
Only these shared variables can be safely written to by signal handlers.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
df90ed8a43 su: Fix typos in comment
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Ruihan Li <lrh2000@pku.edu.cn>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 15:46:59 +01:00
Tobias Stoeckmann
e37e43fd0a lib/motd.c: Remove unused include
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-11 03:05:31 +01:00
Tobias Stoeckmann
69a8862c27 vipw: set SIGCHLD before fork
It could happen that, if SIGCHLD was set to SIG_IGN before calling vipw,
the forked child is already gone before SIGCHLD is set to SIG_DFL after
the fork.

Prevent this race condition and also properly set up SIGCHLD for child
handling within the fork, even though system() should take care of that.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-09 14:15:18 +01:00
Tobias Stoeckmann
a5b3d56e29 vipw: Use fmkomstemp for temporary file
Avoid fixed and thus predictable temporary file names. Especially avoid
just opening already existing ones.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-09 14:13:59 +01:00
Tobias Stoeckmann
413c4908c8 Fix typos
Typos found with codespell

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-08 22:28:13 +01:00
Tobias Stoeckmann
78120f17df configure.ac: Drop libattr linking
The libattr dependency is no longer needed.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-08 09:12:02 +01:00
Tobias Stoeckmann
c8b7b5ef0d lib/copydir.c: Drop reset_selinux
The reset_selinux flag is always true, so it can be removed.
Remove all functions which are not used anymore as well.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-08 09:12:02 +01:00
Alejandro Colomar
ddc2549f87 lib/chkhash.c: is_valid_hash(): Accept '*' as the hash
This is widely accepted as an invalid hash, to remove password access
for an account (that is, no passwords will match the "hash").

Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e")
Closes: <https://github.com/shadow-maint/shadow/issues/1483>
Closes: <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124835>
Reported-by: Chris Hofstaedtler <zeha@debian.org>
Reviewed-by: Chris Hofstaedtler <zeha@debian.org>
Cc: vinz <mmpx09@protonmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-07 20:01:02 -06:00
Alejandro Colomar
87ec7a52ab lib/chkhash.c: is_valid_hash(): Accept a leading '!'
A leading '!' means that the account is locked.

Fixes: c44f1e096a19 (2025-07-20; "chpasswd: Check hash before write when using -e")
Link: <https://github.com/shadow-maint/shadow/issues/1483>
Link: <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1124835>
Reported-by: Chris Hofstaedtler <zeha@debian.org>
Reviewed-by: Chris Hofstaedtler <zeha@debian.org>
Cc: vinz <mmpx09@protonmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2026-01-07 20:01:02 -06:00
Tobias Stoeckmann
6d983709fa man/chage.1: Drop empty configuration section
If TCB is not in use, the whole configuration section is a stub,
containing no useful information. Make it conditional so it
disappears if TCB is not in use.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-05 19:24:26 +01:00
Tobias Stoeckmann
01f705ad50 man/groupmems: Fix grammar
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2026-01-04 18:37:36 +01:00
Hadi Chokr
3e8c105f07 src/useradd: Support config for creating home dirs as Btrfs subvolumes
Closes: #1162

Co-authored-by: Neal Gompa <ngompa@velocitylimitless.com>
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
Signed-off-by: Neal Gompa <ngompa@velocitylimitless.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2026-01-02 23:52:59 +01:00
Iker Pedrosa
a0d5a6165d tests/system/tests/test_groupmod.py: add test for groupmod -U with user list
Add comprehensive test for the groupmod -U option when provided with a
list of users to set group membership. This test verifies:

- Setting initial group membership with multiple users
- Proper membership verification in both group and gshadow entries
- Updating group membership by modifying the user list
- Correct handling of membership changes in group databases

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2026-01-01 15:44:52 +01:00
Iker Pedrosa
ce9e598fac tests/system/framework/utils/tools.py: fix GShadowEntry
GShadowEntry administrators and members represent a list of usernames,
not a single string. Thus, set them to `list[str]`. This fixes type
safety and clarifies the expected data structure.

Fixes: 458700b5d670 (2025-09-10; "tests/system/framework/: fix Python linter issues")
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2026-01-01 15:44:52 +01:00
77 changed files with 496 additions and 1388 deletions

View File

@ -123,18 +123,6 @@ AC_ARG_ENABLE([man],
[enable_man="no"]
)
AC_ARG_ENABLE([account-tools-setuid],
[AS_HELP_STRING([--enable-account-tools-setuid],
[Install the user and group management tools setuid and authenticate the callers. This requires --with-libpam.])],
[case "${enableval}" in
yes) enable_acct_tools_setuid="yes" ;;
no) enable_acct_tools_setuid="no" ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-account-tools-setuid])
;;
esac],
[enable_acct_tools_setuid="no"]
)
AC_ARG_ENABLE([subordinate-ids],
[AS_HELP_STRING([--enable-subordinate-ids],
[support subordinate ids @<:@default=yes@:>@])],
@ -408,32 +396,6 @@ if test "$with_acl" != "no"; then
fi
fi
AC_SUBST([LIBATTR])
if test "$with_attr" != "no"; then
AC_CHECK_HEADERS([attr/libattr.h attr/error_context.h], [attr_header="yes"], [attr_header="no"])
if test "X$attr_header$with_attr" = "noyes" ; then
AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
elif test "X$attr_header" = "Xyes" ; then
AC_CHECK_LIB([attr], [attr_copy_file],
[AC_CHECK_LIB([attr], [attr_copy_fd],
[attr_lib="yes"],
[attr_lib="no"])],
[attr_lib="no"])
if test "X$attr_lib$with_attr" = "Xnoyes" ; then
AC_MSG_ERROR([libattr not found])
elif test "X$attr_lib" = "Xno" ; then
with_attr="no"
else
AC_DEFINE([WITH_ATTR], [1],
[Build shadow with Extended Attributes support])
LIBATTR="-lattr"
with_attr="yes"
fi
else
with_attr="no"
fi
fi
AC_SUBST([LIBAUDIT])
if test "$with_audit" != "no"; then
AC_CHECK_HEADER([libaudit.h], [audit_header="yes"], [audit_header="no"])
@ -605,25 +567,6 @@ else
fi
AM_CONDITIONAL([USE_PAM], [test "X$with_libpam" = "Xyes"])
if test "$enable_acct_tools_setuid" != "no"; then
if test "$with_libpam" != "yes"; then
if test "X$enable_acct_tools_setuid" = "Xyes"; then
AC_MSG_ERROR([PAM support is required for --enable-account-tools-setuid])
else
enable_acct_tools_setuid="no"
fi
else
enable_acct_tools_setuid="yes"
fi
if test "X$enable_acct_tools_setuid" = "Xyes"; then
AC_DEFINE([ACCT_TOOLS_SETUID],
[1],
[Define if account management tools should be installed setuid and authenticate the callers])
fi
fi
AM_CONDITIONAL([ACCT_TOOLS_SETUID], [test "x$enable_acct_tools_setuid" = "xyes"])
AC_ARG_WITH([fcaps],
[AS_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
[with_fcaps=$withval], [with_fcaps=no])
@ -700,7 +643,6 @@ AC_MSG_NOTICE([shadow ${PACKAGE_VERSION} has been configured with the following
auditing support: $with_audit
PAM support: $with_libpam
suid account management tools: $enable_acct_tools_setuid
SELinux support: $with_selinux
BtrFS support: $with_btrfs
ACL support: $with_acl

View File

@ -10,25 +10,13 @@ pamd_files = \
newusers \
passwd
pamd_acct_tools_files = \
chgpasswd \
groupadd \
groupdel \
groupmod \
useradd \
userdel \
usermod
if USE_PAM
pamddir = $(sysconfdir)/pam.d
pamd_DATA = $(pamd_files)
if ACCT_TOOLS_SETUID
pamd_DATA += $(pamd_acct_tools_files)
endif
endif
if WITH_SU
pamd_files += su
endif
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
EXTRA_DIST = $(pamd_files)

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth

View File

@ -179,7 +179,6 @@ libshadow_la_SOURCES = \
shadowio.h \
shadowlog.c \
shadowlog.h \
shadowlog_internal.h \
shadowmem.c \
shell.c \
sizeof.h \

View File

@ -37,7 +37,6 @@ int
add_groups(const char *list)
{
char *dup;
FILE *shadow_logfd = log_get_logfd();
gid_t *gids;
size_t n;
@ -62,7 +61,7 @@ add_groups(const char *list)
grp = getgrnam(g); /* local, no need for xgetgrnam */
if (NULL == grp) {
fprintf(shadow_logfd, _("Warning: unknown group %s\n"), g);
fprintf(log_get_logfd(), _("Warning: unknown group %s\n"), g);
continue;
}
@ -72,7 +71,7 @@ add_groups(const char *list)
free(dup);
if (setgroups(n, gids) == -1) {
fprintf(shadow_logfd, "setgroups: %s\n", strerrno());
fprintf(log_get_logfd(), "setgroups: %s\n", strerrno());
goto free_gids;
}

View File

@ -7,6 +7,9 @@
#include <stddef.h>
#include <string.h>
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
/*
* match_regex - return true if match, false if not
@ -28,15 +31,24 @@ match_regex(const char *pattern, const char *string)
/*
* is_valid_hash - check if the given string is a valid password hash
*
* Returns true if the string appears to be a valid hash, false otherwise.
* is_valid_hash - check if the string is a valid shadow(5) 2nd field.
*
* regex from: https://man.archlinux.org/man/crypt.5.en
*/
bool
is_valid_hash(const char *hash)
{
// Password temporarily locked
hash = strprefix(hash, "!") ?: hash;
// Passwordless account; discouraged
if (streq(hash, ""))
return true;
// Password permanently locked (and forgotten)
if (streq(hash, "*"))
return true;
// Minimum hash length
if (strlen(hash) < 13)
return false;
@ -50,15 +62,15 @@ is_valid_hash(const char *hash)
return true;
// SHA-512: $6$ + salt + $ + 86-char hash
if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash))
if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash))
return true;
// SHA-256: $5$ + salt + $ + 43-char hash
if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash))
if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash))
return true;
// MD5: $1$ + salt + $ + 22-char hash
if (match_regex("^\\$1\\$[^$:\\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash))
if (match_regex("^\\$1\\$[^$:\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash))
return true;
// DES: exactly 13 characters from [A-Za-z0-9./]

View File

@ -53,9 +53,8 @@ void chown_tty (const struct passwd *info)
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
int err = errno;
FILE *shadow_logfd = log_get_logfd();
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Unable to change owner or mode of tty stdin: %s"),
strerror (err));
SYSLOG ((LOG_WARN,

View File

@ -27,12 +27,13 @@
#include "atoi/getnum.h"
#include "commonio.h"
#include "defines.h"
#include "fs/mkstemp/fmkomstemp.h"
#include "nscd.h"
#ifdef WITH_TCB
#include <tcb.h>
#endif /* WITH_TCB */
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "sssd.h"
#include "string/memset/memzero.h"
#include "string/sprintf/aprintf.h"
@ -44,12 +45,10 @@
/* local function prototypes */
static int lrename (const char *, const char *);
static int check_link_count (const char *file, bool log);
static int do_lock_file (const char *file, const char *lock, bool log);
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
const char *name,
const char *mode,
static /*@null@*/ /*@dependent@*/FILE *fmkstemp_set_perms (
char *name,
const struct stat *sb);
static int create_backup (const char *, FILE *);
static void free_linked_list (struct commonio_db *);
@ -69,50 +68,24 @@ static /*@dependent@*/ /*@null@*/struct commonio_entry *next_entry_by_name (
static int lock_count = 0;
static bool nscd_need_reload = false;
/*
* Simple rename(P) alternative that attempts to rename to symlink
* target.
*/
int lrename (const char *old, const char *new)
{
int res;
char *r = NULL;
struct stat sb;
if (lstat (new, &sb) == 0 && S_ISLNK (sb.st_mode)) {
r = realpath (new, NULL);
if (NULL == r) {
perror ("realpath in lrename()");
} else {
new = r;
}
}
res = rename (old, new);
free (r);
return res;
}
static int check_link_count (const char *file, bool log)
{
struct stat sb;
if (stat (file, &sb) != 0) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: %s file stat error: %s\n",
shadow_progname, file, strerrno());
log_get_progname(), file, strerrno());
}
return 0;
}
if (sb.st_nlink != 2) {
if (log) {
fprintf(shadow_logfd,
fprintf(log_get_logfd(),
"%s: %s: lock file already used (nlink: %ju)\n",
shadow_progname, file, (uintmax_t) sb.st_nlink);
log_get_progname(), file, (uintmax_t) sb.st_nlink);
}
return 0;
}
@ -132,9 +105,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (-1 == fd) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: %s: %s\n",
shadow_progname, file, strerrno());
log_get_progname(), file, strerrno());
}
return 0;
}
@ -144,9 +117,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
len = (ssize_t) strlen (buf) + 1;
if (write_full(fd, buf, len) == -1) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: %s file write error: %s\n",
shadow_progname, file, strerrno());
log_get_progname(), file, strerrno());
}
(void) close (fd);
unlink (file);
@ -154,9 +127,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
if (fdatasync (fd) == -1) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: %s file sync error: %s\n",
shadow_progname, file, strerrno());
log_get_progname(), file, strerrno());
}
(void) close (fd);
unlink (file);
@ -173,9 +146,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
fd = open (lock, O_RDWR);
if (-1 == fd) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: %s: %s\n",
shadow_progname, lock, strerrno());
log_get_progname(), lock, strerrno());
}
unlink (file);
errno = EINVAL;
@ -185,9 +158,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
close (fd);
if (len <= 0) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: existing lock file %s without a PID\n",
shadow_progname, lock);
log_get_progname(), lock);
}
unlink (file);
errno = EINVAL;
@ -196,9 +169,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
stpcpy(&buf[len], "");
if (get_pid(buf, &pid) == -1) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: existing lock file %s with an invalid PID '%s'\n",
shadow_progname, lock, buf);
log_get_progname(), lock, buf);
}
unlink (file);
errno = EINVAL;
@ -206,9 +179,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
if (kill (pid, 0) == 0) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: lock %s already used by PID %lu\n",
shadow_progname, lock, (unsigned long) pid);
log_get_progname(), lock, (unsigned long) pid);
}
unlink (file);
errno = EEXIST;
@ -216,9 +189,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
if (unlink (lock) != 0) {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: cannot get lock %s: %s\n",
shadow_progname, lock, strerrno());
log_get_progname(), lock, strerrno());
}
unlink (file);
return 0;
@ -229,9 +202,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
retval = check_link_count (file, log);
} else {
if (log) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: cannot get lock %s: %s\n",
shadow_progname, lock, strerrno());
log_get_progname(), lock, strerrno());
}
}
@ -240,17 +213,13 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
const char *name,
const char *mode,
static /*@null@*/ /*@dependent@*/FILE *fmkstemp_set_perms (
char *name,
const struct stat *sb)
{
FILE *fp;
mode_t mask;
mask = umask (0777);
fp = fopen (name, mode);
(void) umask (mask);
fp = fmkomstemp(name, 0, 0600);
if (NULL == fp) {
return NULL;
}
@ -266,24 +235,26 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
fail:
(void) fclose (fp);
/* fopen_set_perms is used for intermediate files */
/* fmkstemp_set_perms is used for intermediate files */
(void) unlink (name);
return NULL;
}
static int create_backup (const char *backup, FILE * fp)
static int create_backup (const char *name, FILE * fp)
{
char tmpf[PATH_MAX], target[PATH_MAX];
struct stat sb;
struct utimbuf ub;
FILE *bkfp;
int c;
stprintf_a(tmpf, "%s.cioXXXXXX", name);
if (fstat (fileno (fp), &sb) != 0) {
return -1;
}
bkfp = fopen_set_perms (backup, "w", &sb);
bkfp = fmkstemp_set_perms(tmpf, &sb);
if (NULL == bkfp) {
return -1;
}
@ -299,22 +270,28 @@ static int create_backup (const char *backup, FILE * fp)
}
if ((c != EOF) || (ferror (fp) != 0) || (fflush (bkfp) != 0)) {
(void) fclose (bkfp);
/* FIXME: unlink the backup file? */
unlink(tmpf);
return -1;
}
if (fsync (fileno (bkfp)) != 0) {
(void) fclose (bkfp);
/* FIXME: unlink the backup file? */
unlink(tmpf);
return -1;
}
if (fclose (bkfp) != 0) {
/* FIXME: unlink the backup file? */
unlink(tmpf);
return -1;
}
stprintf_a(target, "%s-", name);
if (rename(tmpf, target) != 0) {
unlink(tmpf);
return -1;
}
ub.actime = sb.st_atime;
ub.modtime = sb.st_mtime;
(void) utime (backup, &ub);
(void) utime(target, &ub);
return 0;
}
@ -402,9 +379,9 @@ int commonio_lock (struct commonio_db *db)
if (0 == lock_count) {
if (lckpwdf () == -1) {
if (geteuid () != 0) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
"%s: Permission denied.\n",
shadow_progname);
log_get_progname());
}
return 0; /* failure */
}
@ -438,8 +415,8 @@ int commonio_lock (struct commonio_db *db)
}
/* no unnecessary retries on "permission denied" errors */
if (geteuid () != 0) {
(void) fprintf (shadow_logfd, "%s: Permission denied.\n",
shadow_progname);
(void) fprintf (log_get_logfd(), "%s: Permission denied.\n",
log_get_progname());
return 0;
}
}
@ -868,7 +845,7 @@ int
commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
{
bool errors = false;
char buf[1024];
char tmpf[PATH_MAX];
struct stat sb;
if (!db->isopen) {
@ -900,19 +877,13 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
/*
* Create backup file.
*/
if (stprintf_a(buf, "%s-", db->filename) == -1) {
(void) fclose (db->fp);
db->fp = NULL;
goto fail;
}
#ifdef WITH_SELINUX
if (process_selinux
&& set_selinux_file_context (db->filename, S_IFREG) != 0) {
errors = true;
}
#endif
if (create_backup (buf, db->fp) != 0) {
if (create_backup(db->filename, db->fp) != 0) {
errors = true;
}
@ -939,7 +910,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
sb.st_gid = db->st_gid;
}
if (stprintf_a(buf, "%s+", db->filename) == -1)
if (stprintf_a(tmpf, "%s.cioXXXXXX", db->filename) == -1)
goto fail;
#ifdef WITH_SELINUX
@ -949,7 +920,7 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
}
#endif
db->fp = fopen_set_perms (buf, "w", &sb);
db->fp = fmkstemp_set_perms(tmpf, &sb);
if (NULL == db->fp) {
goto fail;
}
@ -973,11 +944,11 @@ commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
db->fp = NULL;
if (errors) {
unlink (buf);
unlink(tmpf);
goto fail;
}
if (lrename (buf, db->filename) != 0) {
if (rename(tmpf, db->filename) != 0) {
goto fail;
}
@ -1045,7 +1016,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
p = find_entry_by_name(db, db->ops->cio_getname(eptr));
if (NULL != p) {
if (next_entry_by_name(db, p->next, db->ops->cio_getname(eptr)) != NULL) {
fprintf(shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->cio_getname(eptr), db->filename);
fprintf(log_get_logfd(), _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->cio_getname(eptr), db->filename);
db->ops->cio_free(nentry);
return 0;
}
@ -1150,7 +1121,7 @@ int commonio_remove (struct commonio_db *db, const char *name)
return 0;
}
if (next_entry_by_name (db, p->next, name) != NULL) {
fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
fprintf (log_get_logfd(), _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
return 0;
}

View File

@ -27,16 +27,11 @@
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#if defined(WITH_ACL) || defined(WITH_ATTR)
#if defined(WITH_ACL)
#include <stdarg.h>
#include <attr/error_context.h>
#endif /* WITH_ACL || WITH_ATTR */
#ifdef WITH_ACL
#include <acl/libacl.h>
#endif /* WITH_ACL */
#ifdef WITH_ATTR
#include <attr/libattr.h>
#endif /* WITH_ATTR */
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
#include "string/strcmp/streq.h"
@ -63,11 +58,9 @@ struct path_info {
};
static int copy_entry (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
@ -78,12 +71,10 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
static int copy_hardlink (const struct path_info *dst,
struct link_name *lp);
static int copy_special (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int copy_file (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
@ -94,7 +85,7 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
#if defined(WITH_ACL) || defined(WITH_ATTR)
#if defined(WITH_ACL)
/*
* error_acl - format the error messages for the ACL and EQ libraries.
*/
@ -103,7 +94,6 @@ static void
error_acl(struct error_context *, const char *fmt, ...)
{
va_list ap;
FILE *shadow_logfd = log_get_logfd();
/* ignore the case when destination does not support ACLs
* or extended attributes */
@ -113,18 +103,18 @@ error_acl(struct error_context *, const char *fmt, ...)
}
va_start (ap, fmt);
(void) fprintf (shadow_logfd, _("%s: "), log_get_progname());
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
(void) fputs (_(": "), shadow_logfd);
(void) fprintf (log_get_logfd(), _("%s: "), log_get_progname());
if (vfprintf (log_get_logfd(), fmt, ap) != 0) {
(void) fputs (_(": "), log_get_logfd());
}
(void) fprintf(shadow_logfd, "%s\n", strerrno());
(void) fprintf(log_get_logfd(), "%s\n", strerrno());
va_end (ap);
}
static struct error_context ctx = {
error_acl, NULL, NULL
};
#endif /* WITH_ACL || WITH_ATTR */
#endif /* WITH_ACL */
#ifdef WITH_ACL
static int perm_copy_path(const struct path_info *src,
@ -151,32 +141,6 @@ static int perm_copy_path(const struct path_info *src,
}
#endif /* WITH_ACL */
#ifdef WITH_ATTR
static int attr_copy_path(const struct path_info *src,
const struct path_info *dst,
int (*callback) (const char *, struct error_context *),
struct error_context *errctx)
{
int src_fd, dst_fd, ret;
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
ret = attr_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, callback, errctx);
(void) close (src_fd);
(void) close (dst_fd);
return ret;
}
#endif /* WITH_ATTR */
/*
* remove_link - delete a link from the linked list
*/
@ -241,7 +205,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
}
static int copy_tree_impl (const struct path_info *src, const struct path_info *dst,
bool copy_root, bool reset_selinux,
bool copy_root,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@ -269,8 +233,7 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
return -1;
}
return copy_entry (src, dst, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
return copy_entry (src, dst, old_uid, new_uid, old_gid, new_gid);
}
/*
@ -341,7 +304,7 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
dst_entry.dirfd = dst_fd;
dst_entry.name = ent->d_name;
err = copy_entry(&src_entry, &dst_entry, reset_selinux,
err = copy_entry(&src_entry, &dst_entry,
old_uid, new_uid, old_gid, new_gid);
free(dst_name);
@ -397,7 +360,6 @@ skip:
* to -1.
*/
static int copy_entry (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@ -419,7 +381,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
if (S_ISDIR (sb.st_mode)) {
err = copy_dir (src, dst, reset_selinux, &sb, mt,
err = copy_dir (src, dst, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
@ -455,7 +417,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
*/
else if (!S_ISREG (sb.st_mode)) {
err = copy_special (src, dst, reset_selinux, &sb, mt,
err = copy_special (src, dst, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
@ -465,7 +427,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
*/
else {
err = copy_file (src, dst, reset_selinux, &sb, mt,
err = copy_file (src, dst, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
@ -483,7 +445,6 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
* Return 0 on success, -1 on error.
*/
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
@ -506,7 +467,7 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
* but copy into it (recursively).
*/
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
return (copy_tree_impl (src, dst, false, reset_selinux,
return (copy_tree_impl (src, dst, false,
old_uid, new_uid, old_gid, new_gid) != 0);
}
@ -518,19 +479,7 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (copy_tree_impl (src, dst, false, reset_selinux,
|| (copy_tree_impl (src, dst, false,
old_uid, new_uid, old_gid, new_gid) != 0)
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
err = -1;
@ -651,7 +600,6 @@ static int copy_hardlink (const struct path_info *dst,
*/
static int
copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
@ -675,20 +623,6 @@ copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *d
return -1;
#endif
#if defined(WITH_ATTR)
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
if (!reset_selinux) {
if (attr_copy_path(src, dst, NULL, &ctx) == -1 && errno != 0)
return -1;
}
#endif
if (utimensat(dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) == -1)
return -1;
@ -706,7 +640,6 @@ copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *d
* Return 0 on success, -1 on error.
*/
static int copy_file (const struct path_info *src, const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
@ -734,18 +667,6 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
) {
if (ofd >= 0) {
(void) close (ofd);
@ -857,9 +778,6 @@ static int chownat_if_needed (const struct path_info *dst,
* copy_tree() walks a directory tree and copies ordinary files
* as it goes.
*
* When reset_selinux is enabled, extended attributes (and thus
* SELinux attributes) are not copied.
*
* old_uid and new_uid are used to set the ownership of the copied
* files. Unless old_uid is set to -1, only the files owned by
* old_uid have their ownership changed to new_uid. In addition, if
@ -869,7 +787,7 @@ static int chownat_if_needed (const struct path_info *dst,
* old_gid/new_gid.
*/
int copy_tree (const char *src_root, const char *dst_root,
bool copy_root, bool reset_selinux,
bool copy_root,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@ -884,6 +802,5 @@ int copy_tree (const char *src_root, const char *dst_root,
.name = dst_root
};
return copy_tree_impl(&src, &dst, copy_root, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
return copy_tree_impl(&src, &dst, copy_root, old_uid, new_uid, old_gid, new_gid);
}

View File

@ -16,7 +16,7 @@
#include "prototypes.h"
#include "defines.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/strcmp/strprefix.h"
@ -64,7 +64,7 @@
method = &nummethod[0];
}
}
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
_("crypt method not supported by libcrypt? (%s)\n"),
method);
errno = EINVAL;

View File

@ -26,7 +26,7 @@
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "sizeof.h"
#include "string/sprintf/aprintf.h"
#include "string/strcmp/strcaseeq.h"
@ -255,7 +255,7 @@ getdef_num(const char *item, int dflt)
}
if (a2si(&val, d->value, NULL, 0, -1, INT_MAX) == -1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
@ -289,7 +289,7 @@ getdef_unum(const char *item, unsigned int dflt)
}
if (a2ui(&val, d->value, NULL, 0, 0, UINT_MAX) == -1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
@ -322,7 +322,7 @@ long getdef_long (const char *item, long dflt)
}
if (a2sl(&val, d->value, NULL, 0, -1, LONG_MAX) == -1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
@ -354,7 +354,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt)
}
if (str2ul(&val, d->value) == -1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
@ -391,7 +391,7 @@ int putdef_str (const char *name, const char *value, const char *srcfile)
cp = strdup (value);
if (NULL == cp) {
(void) fputs (_("Could not allocate space for config info.\n"),
shadow_logfd);
log_get_logfd());
SYSLOG ((LOG_ERR, "could not allocate space for config info"));
return -1;
}
@ -435,7 +435,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, cons
goto out;
}
}
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("configuration error - unknown item '%s' (notify administrator)\n"),
name);
if (srcfile != NULL)

View File

@ -29,7 +29,6 @@
gettime(void)
{
char *source_date_epoch;
FILE *shadow_logfd = log_get_logfd();
time_t fallback, epoch;
fallback = time (NULL);
@ -39,7 +38,7 @@ gettime(void)
return fallback;
if (a2i(time_t, &epoch, source_date_epoch, NULL, 10, 0, fallback) == -1) {
fprintf(shadow_logfd,
fprintf(log_get_logfd(),
_("Environment variable $SOURCE_DATE_EPOCH: a2i(\"%s\"): %s"),
source_date_epoch, strerrno());
return fallback;

View File

@ -14,7 +14,6 @@
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"

View File

@ -10,7 +10,7 @@
#include "defines.h"
#include "prototypes.h"
#include "nscd.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#define MSG_NSCD_FLUSH_CACHE_FAILED "%s: Failed to flush the nscd cache.\n"
@ -26,15 +26,15 @@ int nscd_flush_cache (const char *service)
if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) {
/* run_command writes its own more detailed message. */
(void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname);
(void) fprintf (log_get_logfd(), _(MSG_NSCD_FLUSH_CACHE_FAILED), log_get_progname());
return -1;
}
code = WEXITSTATUS (status);
if (!WIFEXITED (status)) {
(void) fprintf (shadow_logfd,
(void) fprintf (log_get_logfd(),
_("%s: nscd did not terminate normally (signal %d)\n"),
shadow_progname, WTERMSIG (status));
log_get_progname(), WTERMSIG (status));
return -1;
} else if (code == E_CMD_NOTFOUND) {
/* nscd is not installed, or it is installed but uses an
@ -44,9 +44,9 @@ int nscd_flush_cache (const char *service)
/* nscd is installed, but it isn't active. */
return 0;
} else if (code != 0) {
(void) fprintf (shadow_logfd, _("%s: nscd exited with status %d\n"),
shadow_progname, code);
(void) fprintf (shadow_logfd, _(MSG_NSCD_FLUSH_CACHE_FAILED), shadow_progname);
(void) fprintf (log_get_logfd(), _("%s: nscd exited with status %d\n"),
log_get_progname(), code);
(void) fprintf (log_get_logfd(), _(MSG_NSCD_FLUSH_CACHE_FAILED), log_get_progname());
return -1;
}

View File

@ -12,7 +12,6 @@
#include "alloc/malloc.h"
#include "prototypes.h"
#include "../libsubid/subid.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/strcaseprefix.h"
@ -55,7 +54,6 @@ nss_init(const char *nsswitch_path) {
char *line = NULL, *p;
char libname[64];
FILE *nssfp = NULL;
FILE *shadow_logfd = log_get_logfd();
void *h;
size_t len = 0;
@ -74,7 +72,7 @@ nss_init(const char *nsswitch_path) {
nssfp = fopen(nsswitch_path, "r");
if (!nssfp) {
if (errno != ENOENT)
fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path);
fprintf(log_get_logfd(), "Failed opening %s: %m\n", nsswitch_path);
atomic_store(&nss_init_completed, true);
return;
@ -97,7 +95,7 @@ nss_init(const char *nsswitch_path) {
goto null_subid;
}
if (stpsep(p, " \t\n") == NULL) {
fprintf(shadow_logfd, "No usable subid NSS module found, using files\n");
fprintf(log_get_logfd(), "No usable subid NSS module found, using files\n");
// subid_nss has to be null here, but to ease reviews:
goto null_subid;
}
@ -105,15 +103,15 @@ nss_init(const char *nsswitch_path) {
goto null_subid;
}
if (strlen(p) > 50) {
fprintf(shadow_logfd, "Subid NSS module name too long (longer than 50 characters): %s\n", p);
fprintf(shadow_logfd, "Using files\n");
fprintf(log_get_logfd(), "Subid NSS module name too long (longer than 50 characters): %s\n", p);
fprintf(log_get_logfd(), "Using files\n");
goto null_subid;
}
stprintf_a(libname, "libsubid_%s.so", p);
h = dlopen(libname, RTLD_LAZY);
if (!h) {
fprintf(shadow_logfd, "Error opening %s: %s\n", libname, dlerror());
fprintf(shadow_logfd, "Using files\n");
fprintf(log_get_logfd(), "Error opening %s: %s\n", libname, dlerror());
fprintf(log_get_logfd(), "Using files\n");
goto null_subid;
}
subid_nss = malloc_T(1, struct subid_nss_ops);
@ -122,22 +120,22 @@ nss_init(const char *nsswitch_path) {
}
subid_nss->has_range = dlsym(h, "shadow_subid_has_range");
if (!subid_nss->has_range) {
fprintf(shadow_logfd, "%s did not provide @has_range@\n", libname);
fprintf(log_get_logfd(), "%s did not provide @has_range@\n", libname);
goto close_lib;
}
subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges");
if (!subid_nss->list_owner_ranges) {
fprintf(shadow_logfd, "%s did not provide @list_owner_ranges@\n", libname);
fprintf(log_get_logfd(), "%s did not provide @list_owner_ranges@\n", libname);
goto close_lib;
}
subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners");
if (!subid_nss->find_subid_owners) {
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
fprintf(log_get_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);
fprintf(log_get_logfd(), "%s did not provide @subid_free@\n", libname);
goto close_lib;
}
subid_nss->handle = h;

View File

@ -32,7 +32,6 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
{
pam_handle_t *pamh = NULL;
int flags = 0, ret;
FILE *shadow_logfd = log_get_logfd();
if (silent)
flags |= PAM_SILENT;
@ -41,20 +40,20 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
ret = pam_start ("passwd", user, &conv, &pamh);
if (ret != PAM_SUCCESS) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("passwd: pam_start() failed, error %d\n"), ret);
exit (E_PAM_ERR);
}
ret = pam_chauthtok (pamh, flags);
if (ret != PAM_SUCCESS) {
fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret));
fputs (_("passwd: password unchanged\n"), shadow_logfd);
fprintf (log_get_logfd(), _("passwd: %s\n"), pam_strerror (pamh, ret));
fputs (_("passwd: password unchanged\n"), log_get_logfd());
pam_end (pamh, ret);
exit (E_PAM_ERR);
}
fputs (_("passwd: password updated successfully\n"), shadow_logfd);
fputs (_("passwd: password updated successfully\n"), log_get_logfd());
(void) pam_end (pamh, PAM_SUCCESS);
}
#else /* !USE_PAM */

View File

@ -106,7 +106,6 @@ extern bool console (const char *);
/* copydir.c */
extern int copy_tree (const char *src_root, const char *dst_root,
bool copy_root,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);

View File

@ -12,7 +12,7 @@
#include <lib/prototypes.h>
#include "run_part.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
#include "string/strerrno.h"
@ -26,14 +26,14 @@ static int run_part(char *script_path, const char *name, const char *action)
pid=fork();
if (pid==-1) {
fprintf(shadow_logfd, "fork: %s\n", strerrno());
fprintf(log_get_logfd(), "fork: %s\n", strerrno());
return 1;
}
if (pid==0) {
setenv("ACTION",action,1);
setenv("SUBJECT",name,1);
execv(script_path,args);
fprintf(shadow_logfd, "execv: %s\n", strerrno());
fprintf(log_get_logfd(), "execv: %s\n", strerrno());
_exit(1);
}
@ -42,7 +42,7 @@ static int run_part(char *script_path, const char *name, const char *action)
return (wait_status);
}
fprintf(shadow_logfd, "wait: %s\n", strerrno());
fprintf(log_get_logfd(), "wait: %s\n", strerrno());
return (1);
}
@ -64,7 +64,7 @@ int run_parts(const char *directory, const char *name, const char *action)
s = aprintf("%s/%s", directory, namelist[n]->d_name);
if (s == NULL) {
fprintf(shadow_logfd, "aprintf: %s\n", strerrno());
fprintf(log_get_logfd(), "aprintf: %s\n", strerrno());
for (; n<scanlist; n++) {
free(namelist[n]);
}
@ -74,7 +74,7 @@ int run_parts(const char *directory, const char *name, const char *action)
execute_result = 0;
if (stat(s, &sb) == -1) {
fprintf(shadow_logfd, "stat: %s\n", strerrno());
fprintf(log_get_logfd(), "stat: %s\n", strerrno());
free(s);
for (; n<scanlist; n++) {
free(namelist[n]);
@ -90,7 +90,7 @@ int run_parts(const char *directory, const char *name, const char *action)
free(s);
if (execute_result!=0) {
fprintf(shadow_logfd,
fprintf(log_get_logfd(),
"%s: did not exit cleanly.\n",
namelist[n]->d_name);
for (; n<scanlist; n++) {

View File

@ -15,7 +15,7 @@
#include <selinux/label.h>
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
#include "string/strerrno.h"
@ -138,7 +138,7 @@ static int selinux_log_cb (int type, const char *fmt, ...) {
&& (errno != EAFNOSUPPORT)) {
(void) fputs (_("Cannot open audit interface.\n"),
shadow_logfd);
log_get_logfd());
SYSLOG ((LOG_WARN, "Cannot open audit interface."));
}
}
@ -191,9 +191,9 @@ int check_selinux_permit (const char *perm_name)
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) { .func_log = selinux_log_cb });
if (getprevcon_raw (&user_context_raw) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: can not get previous SELinux process context: %s\n"),
shadow_progname, strerrno());
log_get_progname(), strerrno());
SYSLOG ((LOG_WARN,
"can not get previous SELinux process context: %s",
strerrno()));

View File

@ -23,7 +23,7 @@
#include "attr.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
@ -44,7 +44,7 @@ static void semanage_error_callback (void *,
switch (semanage_msg_get_level (handle)) {
case SEMANAGE_MSG_ERR:
case SEMANAGE_MSG_WARN:
fprintf (shadow_logfd, _("[libsemanage]: %s\n"), message);
fprintf (log_get_logfd(), _("[libsemanage]: %s\n"), message);
break;
case SEMANAGE_MSG_INFO:
/* nop */
@ -62,7 +62,7 @@ static semanage_handle_t *semanage_init (void)
handle = semanage_handle_create ();
if (NULL == handle) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Cannot create SELinux management handle\n"));
return NULL;
}
@ -71,26 +71,26 @@ static semanage_handle_t *semanage_init (void)
ret = semanage_is_managed (handle);
if (ret != 1) {
fprintf (shadow_logfd, _("SELinux policy not managed\n"));
fprintf (log_get_logfd(), _("SELinux policy not managed\n"));
goto fail;
}
ret = semanage_access_check (handle);
if (ret < SEMANAGE_CAN_READ) {
fprintf (shadow_logfd, _("Cannot read SELinux policy store\n"));
fprintf (log_get_logfd(), _("Cannot read SELinux policy store\n"));
goto fail;
}
ret = semanage_connect (handle);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Cannot establish SELinux management connection\n"));
goto fail;
}
ret = semanage_begin_transaction (handle);
if (ret != 0) {
fprintf (shadow_logfd, _("Cannot begin SELinux transaction\n"));
fprintf (log_get_logfd(), _("Cannot begin SELinux transaction\n"));
goto fail;
}
@ -115,7 +115,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
semanage_seuser_query (handle, key, &seuser);
if (NULL == seuser) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not query seuser for %s\n"), login_name);
ret = 1;
goto done;
@ -124,7 +124,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
if (serange && semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not set serange for %s to %s\n"),
login_name, serange);
ret = 1;
@ -134,7 +134,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not set sename for %s\n"),
login_name);
ret = 1;
@ -143,7 +143,7 @@ static int semanage_user_mod (semanage_handle_t *handle,
ret = semanage_seuser_modify_local (handle, key, seuser);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not modify login mapping for %s\n"),
login_name);
ret = 1;
@ -168,7 +168,7 @@ static int semanage_user_add (semanage_handle_t *handle,
ret = semanage_seuser_create (handle, &seuser);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Cannot create SELinux login mapping for %s\n"),
login_name);
ret = 1;
@ -177,7 +177,7 @@ static int semanage_user_add (semanage_handle_t *handle,
ret = semanage_seuser_set_name (handle, seuser, login_name);
if (ret != 0) {
fprintf (shadow_logfd, _("Could not set name for %s\n"), login_name);
fprintf (log_get_logfd(), _("Could not set name for %s\n"), login_name);
ret = 1;
goto done;
}
@ -185,7 +185,7 @@ static int semanage_user_add (semanage_handle_t *handle,
if (serange && semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not set serange for %s to %s\n"),
login_name, serange);
ret = 1;
@ -195,7 +195,7 @@ static int semanage_user_add (semanage_handle_t *handle,
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not set SELinux user for %s\n"),
login_name);
ret = 1;
@ -204,7 +204,7 @@ static int semanage_user_add (semanage_handle_t *handle,
ret = semanage_seuser_modify_local (handle, key, seuser);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not add login mapping for %s\n"),
login_name);
ret = 1;
@ -232,21 +232,21 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
handle = semanage_init ();
if (NULL == handle) {
fprintf (shadow_logfd, _("Cannot init SELinux management\n"));
fprintf (log_get_logfd(), _("Cannot init SELinux management\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_key_create (handle, login_name, &key);
if (ret != 0) {
fprintf (shadow_logfd, _("Cannot create SELinux user key\n"));
fprintf (log_get_logfd(), _("Cannot create SELinux user key\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_exists (handle, key, &seuser_exists);
if (ret < 0) {
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
@ -254,7 +254,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
if (0 != seuser_exists) {
ret = semanage_user_mod (handle, key, login_name, seuser_name, serange);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Cannot modify SELinux user mapping\n"));
ret = 1;
goto done;
@ -262,7 +262,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
} else {
ret = semanage_user_add (handle, key, login_name, seuser_name, serange);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Cannot add SELinux user mapping\n"));
ret = 1;
goto done;
@ -271,7 +271,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
ret = semanage_commit (handle);
if (ret < 0) {
fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n"));
fprintf (log_get_logfd(), _("Cannot commit SELinux transaction\n"));
ret = 1;
goto done;
}
@ -297,27 +297,27 @@ int del_seuser (const char *login_name)
handle = semanage_init ();
if (NULL == handle) {
fprintf (shadow_logfd, _("Cannot init SELinux management\n"));
fprintf (log_get_logfd(), _("Cannot init SELinux management\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_key_create (handle, login_name, &key);
if (ret != 0) {
fprintf (shadow_logfd, _("Cannot create SELinux user key\n"));
fprintf (log_get_logfd(), _("Cannot create SELinux user key\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_exists (handle, key, &exists);
if (ret < 0) {
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
if (0 == exists) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Login mapping for %s is not defined, OK if default mapping was used\n"),
login_name);
ret = 0; /* probably default mapping */
@ -326,13 +326,13 @@ int del_seuser (const char *login_name)
ret = semanage_seuser_exists_local (handle, key, &exists);
if (ret < 0) {
fprintf (shadow_logfd, _("Cannot verify the SELinux user\n"));
fprintf (log_get_logfd(), _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
if (0 == exists) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Login mapping for %s is defined in policy, cannot be deleted\n"),
login_name);
ret = 0; /* Login mapping defined in policy can't be deleted */
@ -341,7 +341,7 @@ int del_seuser (const char *login_name)
ret = semanage_seuser_del_local (handle, key);
if (ret != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("Could not delete login mapping for %s"),
login_name);
ret = 1;
@ -350,7 +350,7 @@ int del_seuser (const char *login_name)
ret = semanage_commit (handle);
if (ret < 0) {
fprintf (shadow_logfd, _("Cannot commit SELinux transaction\n"));
fprintf (log_get_logfd(), _("Cannot commit SELinux transaction\n"));
ret = 1;
goto done;
}

View File

@ -19,7 +19,6 @@
#include "atoi/getnum.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2arr.h"
@ -37,7 +36,7 @@
* performance reasons. I am going to come up with some conditional
* compilation glarp to improve on this in the future.
*/
// from-string get pasword entry
// from-string get password entry
struct passwd *
sgetpwent(const char *s)
{

View File

@ -21,7 +21,6 @@
#include "atoi/a2i.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "sizeof.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"

View File

@ -1,9 +1,7 @@
#include "shadowlog.h"
#include "lib/shadowlog_internal.h"
const char *shadow_progname = "libshadow";
FILE *shadow_logfd = NULL;
static const char *shadow_progname = "libshadow";
static FILE *shadow_logfd = NULL;
void log_set_progname(const char *progname)
{

View File

@ -1,7 +0,0 @@
#ifndef _SHADOWLOG_INTERNAL_H
#define _SHADOWLOG_INTERNAL_H
extern const char *shadow_progname; /* Program name shown in error messages */
extern FILE *shadow_logfd; /* file descriptor to which error messages are printed */
#endif /* _SHADOWLOG_INTERNAL_H */

View File

@ -15,7 +15,7 @@
#include "exitcodes.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/strerrno.h"
@ -30,7 +30,7 @@ run_command(const char *cmd, const char *argv[],
}
(void) fflush (stdout);
(void) fflush (shadow_logfd);
(void) fflush (log_get_logfd());
pid = fork ();
if (0 == pid) {
@ -39,12 +39,12 @@ run_command(const char *cmd, const char *argv[],
if (ENOENT == errno) {
_exit (E_CMD_NOTFOUND);
}
fprintf (shadow_logfd, "%s: cannot execute %s: %s\n",
shadow_progname, cmd, strerrno());
fprintf (log_get_logfd(), "%s: cannot execute %s: %s\n",
log_get_progname(), cmd, strerrno());
_exit (E_CMD_NOEXEC);
} else if ((pid_t)-1 == pid) {
fprintf (shadow_logfd, "%s: cannot execute %s: %s\n",
shadow_progname, cmd, strerrno());
fprintf (log_get_logfd(), "%s: cannot execute %s: %s\n",
log_get_progname(), cmd, strerrno());
return -1;
}
@ -56,8 +56,8 @@ run_command(const char *cmd, const char *argv[],
|| ((pid_t)-1 != wpid && wpid != pid));
if ((pid_t)-1 == wpid) {
fprintf (shadow_logfd, "%s: waitpid (status: %d): %s\n",
shadow_progname, *status, strerrno());
fprintf (log_get_logfd(), "%s: waitpid (status: %d): %s\n",
log_get_progname(), *status, strerrno());
return -1;
}

View File

@ -14,7 +14,6 @@
#include "exitcodes.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/strcmp/streq.h"
@ -57,22 +56,22 @@ sssd_flush_cache(int dbflags)
free(sss_cache_args);
if (rv != 0) {
/* run_command writes its own more detailed message. */
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname));
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, log_get_progname()));
return -1;
}
code = WEXITSTATUS (status);
if (!WIFEXITED (status)) {
SYSLOG ((LOG_WARN, "%s: sss_cache did not terminate normally (signal %d)",
shadow_progname, WTERMSIG (status)));
log_get_progname(), WTERMSIG (status)));
return -1;
} else if (code == E_CMD_NOTFOUND) {
/* sss_cache is not installed, or it is installed but uses an
interpreter that is missing. Probably the former. */
return 0;
} else if (code != 0) {
SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", shadow_progname, code));
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, shadow_progname));
SYSLOG ((LOG_WARN, "%s: sss_cache exited with status %d", log_get_progname(), code));
SYSLOG ((LOG_WARN, MSG_SSSD_FLUSH_CACHE_FAILED, log_get_progname()));
return -1;
}

View File

@ -23,7 +23,7 @@
#include "prototypes.h"
#include "tcbfuncs.h"
#include "shadowio.h"
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
@ -64,8 +64,8 @@ shadowtcb_status shadowtcb_gain_priv (void)
* to exit soon.
*/
#define OUT_OF_MEMORY do { \
fprintf (shadow_logfd, _("%s: out of memory\n"), shadow_progname); \
(void) fflush (shadow_logfd); \
fprintf (log_get_logfd(), _("%s: out of memory\n"), log_get_progname()); \
(void) fflush (log_get_logfd()); \
} while (false)
/* Returns user's tcb directory path relative to TCB_DIR. */
@ -102,9 +102,9 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
return NULL;
}
if (lstat (path, &st) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot stat %s: %s\n"),
shadow_progname, path, strerrno());
log_get_progname(), path, strerrno());
free (path);
return NULL;
}
@ -118,16 +118,16 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
return rval;
}
if (!S_ISLNK (st.st_mode)) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: %s is neither a directory, nor a symlink.\n"),
shadow_progname, path);
log_get_progname(), path);
free (path);
return NULL;
}
if (readlinknul_a(path, link) == -1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot read symbolic link %s: %s\n"),
shadow_progname, path, strerrno());
log_get_progname(), path, strerrno());
free (path);
return NULL;
}
@ -186,9 +186,9 @@ static shadowtcb_status mkdir_leading (const char *name, uid_t uid)
}
ptr = path;
if (stat (TCB_DIR, &st) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot stat %s: %s\n"),
shadow_progname, TCB_DIR, strerrno());
log_get_progname(), TCB_DIR, strerrno());
goto out_free_path;
}
while (NULL != (ind = strchr(ptr, '/'))) {
@ -199,21 +199,21 @@ static shadowtcb_status mkdir_leading (const char *name, uid_t uid)
return SHADOWTCB_FAILURE;
}
if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot create directory %s: %s\n"),
shadow_progname, dir, strerrno());
log_get_progname(), dir, strerrno());
goto out_free_dir;
}
if (chown (dir, 0, st.st_gid) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owner of %s: %s\n"),
shadow_progname, dir, strerrno());
log_get_progname(), dir, strerrno());
goto out_free_dir;
}
if (chmod (dir, 0711) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, dir, strerrno());
log_get_progname(), dir, strerrno());
goto out_free_dir;
}
free (dir);
@ -242,9 +242,9 @@ static shadowtcb_status unlink_suffs (const char *user)
return SHADOWTCB_FAILURE;
}
if ((unlink (tmp) != 0) && (errno != ENOENT)) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: unlink: %s: %s\n"),
shadow_progname, tmp, strerrno());
log_get_progname(), tmp, strerrno());
free (tmp);
return SHADOWTCB_FAILURE;
}
@ -272,9 +272,9 @@ rmdir_leading(const char *relpath)
if (rmdir(path) != 0) {
if (errno != ENOTEMPTY) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot remove directory %s: %s\n"),
shadow_progname, path, strerrno());
log_get_progname(), path, strerrno());
ret = SHADOWTCB_FAILURE;
}
break;
@ -306,9 +306,9 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
goto out_free_nomem;
}
if (stat (olddir, &oldmode) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot stat %s: %s\n"),
shadow_progname, olddir, strerrno());
log_get_progname(), olddir, strerrno());
goto out_free;
}
old_uid = oldmode.st_uid;
@ -333,18 +333,18 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
goto out_free;
}
if (rename (real_old_dir, real_new_dir) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot rename %s to %s: %s\n"),
shadow_progname, real_old_dir, real_new_dir, strerrno());
log_get_progname(), real_old_dir, real_new_dir, strerrno());
goto out_free;
}
if (rmdir_leading (real_old_dir_rel) == SHADOWTCB_FAILURE) {
goto out_free;
}
if ((unlink (olddir) != 0) && (errno != ENOENT)) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot remove %s: %s\n"),
shadow_progname, olddir, strerrno());
log_get_progname(), olddir, strerrno());
goto out_free;
}
newdir = aprintf(TCB_DIR "/%s", user_newname);
@ -357,9 +357,9 @@ static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
}
if ( !streq(real_new_dir, newdir)
&& (symlink (real_new_dir_rel, newdir) != 0)) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot create symbolic link %s: %s\n"),
shadow_progname, real_new_dir_rel, strerrno());
log_get_progname(), real_new_dir_rel, strerrno());
goto out_free;
}
ret = SHADOWTCB_SUCCESS;
@ -461,53 +461,53 @@ shadowtcb_status shadowtcb_move (/*@NULL@*/const char *user_newname, uid_t user_
return SHADOWTCB_FAILURE;
}
if (stat (tcbdir, &dirmode) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot stat %s: %s\n"),
shadow_progname, tcbdir, strerrno());
log_get_progname(), tcbdir, strerrno());
goto out_free;
}
if (chown (tcbdir, 0, 0) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owners of %s: %s\n"),
shadow_progname, tcbdir, strerrno());
log_get_progname(), tcbdir, strerrno());
goto out_free;
}
if (chmod (tcbdir, 0700) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, tcbdir, strerrno());
log_get_progname(), tcbdir, strerrno());
goto out_free;
}
if (lstat (shadow, &filemode) != 0) {
if (errno != ENOENT) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot lstat %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Warning, user %s has no tcb shadow file.\n"),
shadow_progname, user_newname);
log_get_progname(), user_newname);
} else {
if (!S_ISREG (filemode.st_mode) ||
filemode.st_nlink != 1) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Emergency: %s's tcb shadow is not a "
"regular file with st_nlink=1.\n"
"The account is left locked.\n"),
shadow_progname, user_newname);
log_get_progname(), user_newname);
goto out_free;
}
if (chown (shadow, user_newid, filemode.st_gid) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owner of %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
if (chmod (shadow, filemode.st_mode & 07777) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
}
@ -515,15 +515,15 @@ shadowtcb_status shadowtcb_move (/*@NULL@*/const char *user_newname, uid_t user_
goto out_free;
}
if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owner of %s: %s\n"),
shadow_progname, tcbdir, strerrno());
log_get_progname(), tcbdir, strerrno());
goto out_free;
}
if (chmod (tcbdir, dirmode.st_mode & 07777) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, tcbdir, strerrno());
log_get_progname(), tcbdir, strerrno());
goto out_free;
}
ret = SHADOWTCB_SUCCESS;
@ -546,9 +546,9 @@ shadowtcb_status shadowtcb_create (const char *name, uid_t uid)
return SHADOWTCB_SUCCESS;
}
if (stat (TCB_DIR, &tcbdir_stat) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot stat %s: %s\n"),
shadow_progname, TCB_DIR, strerrno());
log_get_progname(), TCB_DIR, strerrno());
return SHADOWTCB_FAILURE;
}
shadowgid = tcbdir_stat.st_gid;
@ -571,39 +571,39 @@ shadowtcb_status shadowtcb_create (const char *name, uid_t uid)
return SHADOWTCB_FAILURE;
}
if (mkdir (dir, 0700) != 0) {
fprintf (shadow_logfd,
_("%s: mkdir: %s: %s\n"), shadow_progname, dir, strerrno());
fprintf (log_get_logfd(),
_("%s: mkdir: %s: %s\n"), log_get_progname(), dir, strerrno());
goto out_free;
}
fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (fd < 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot open %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
if (fchown (fd, 0, authgid) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owner of %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
if (fchmod (fd, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, shadow, strerrno());
log_get_progname(), shadow, strerrno());
goto out_free;
}
if (chown (dir, 0, authgid) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change owner of %s: %s\n"),
shadow_progname, dir, strerrno());
log_get_progname(), dir, strerrno());
goto out_free;
}
if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) {
fprintf (shadow_logfd,
fprintf (log_get_logfd(),
_("%s: Cannot change mode of %s: %s\n"),
shadow_progname, dir, strerrno());
log_get_progname(), dir, strerrno());
goto out_free;
}
if ( (shadowtcb_set_user (name) == SHADOWTCB_FAILURE)

View File

@ -32,7 +32,7 @@
* After a yes/no question, this function gets the answer from the
* user.
*
* Calls to this function will normally be preceeded by a prompt on
* Calls to this function will normally be preceded by a prompt on
* stdout, so we should fflush(3).
*
* Return value

View File

@ -14,7 +14,6 @@ MISCLIBS = \
$(LIBECONF) \
$(LIBCRYPT) \
$(LIBACL) \
$(LIBATTR) \
$(LIBTCB) \
$(LIBPAM)

View File

@ -21,7 +21,7 @@
bool subid_init(const char *progname, FILE * logfd)
{
FILE *shadow_logfd;
FILE *fp;
if (progname) {
progname = strdup(progname);
if (!progname)
@ -35,12 +35,12 @@ bool subid_init(const char *progname, FILE * logfd)
log_set_logfd(logfd);
return true;
}
shadow_logfd = fopen("/dev/null", "w");
if (!shadow_logfd) {
fp = fopen("/dev/null", "w");
if (!fp) {
log_set_logfd(stderr);
return false;
}
log_set_logfd(shadow_logfd);
log_set_logfd(fp);
return true;
}

View File

@ -27,7 +27,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \
@ -95,7 +94,6 @@ man_XMANS = \
login.1.xml \
login.access.5.xml \
login.defs.5.xml \
logoutd.8.xml \
newgidmap.1.xml \
newgrp.1.xml \
newuidmap.1.xml \

View File

@ -270,7 +270,7 @@
</para>
</refsect1>
<refsect1 id='configuration'>
<refsect1 id='configuration' condition="tcb">
<title>CONFIGURATION</title>
<para>
The following configuration variables in

View File

@ -22,6 +22,5 @@ man_MANS += man8/lastlog.8
endif
EXTRA_DIST = $(man_MANS) \
man8/groupmems.8 \
man8/logoutd.8
man8/groupmems.8

View File

@ -6,7 +6,6 @@ man_MANS = \
man1/chfn.1 \
man8/groupdel.8 \
man5/gshadow.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/nologin.8 \
man1/sg.1 \

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -84,7 +84,7 @@
<listitem>
<para>Add a user to the group membership list.</para>
<para condition="gshadow">
If the <filename>/etc/gshadow</filename> file exist, and the
If the <filename>/etc/gshadow</filename> file exists, and the
group has no entry in the <filename>/etc/gshadow</filename>
file, a new entry will be created.
</para>
@ -95,12 +95,12 @@
<listitem>
<para>Delete a user from the group membership list.</para>
<para condition="gshadow">
If the <filename>/etc/gshadow</filename> file exist, the user
If the <filename>/etc/gshadow</filename> file exists, the user
will be removed from the list of members and administrators of
the group.
</para>
<para condition="gshadow">
If the <filename>/etc/gshadow</filename> file exist, and the
If the <filename>/etc/gshadow</filename> file exists, and the
group has no entry in the <filename>/etc/gshadow</filename>
file, a new entry will be created.
</para>
@ -131,7 +131,7 @@
<listitem>
<para>Purge all users from the group membership list.</para>
<para condition="gshadow">
If the <filename>/etc/gshadow</filename> file exist, and the
If the <filename>/etc/gshadow</filename> file exists, and the
group has no entry in the <filename>/etc/gshadow</filename>
file, a new entry will be created.
</para>

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -18,7 +18,6 @@ man_MANS = \
man8/grpunconv.8 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man1/passwd.1 \

View File

@ -379,7 +379,6 @@
</para>
</listitem>
</varlistentry>
<!-- logoutd: no variables -->
<varlistentry>
<term>newgrp / sg</term>
<listitem>

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
SPDX-FileCopyrightText: 1991 , Julianne Frances Haugh
SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
SPDX-License-Identifier: BSD-3-Clause
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!-- SHADOW-CONFIG-HERE -->
]>
<refentry id='logoutd.8'>
<!-- $Id$ -->
<refentryinfo>
<author>
<firstname>Julianne Frances</firstname>
<surname>Haugh</surname>
<contrib>Creation, 1991</contrib>
</author>
<author>
<firstname>Thomas</firstname>
<surname>Kłoczko</surname>
<email>kloczek@pld.org.pl</email>
<contrib>shadow-utils maintainer, 2000 - 2007</contrib>
</author>
<author>
<firstname>Nicolas</firstname>
<surname>François</surname>
<email>nicolas.francois@centraliens.net</email>
<contrib>shadow-utils maintainer, 2007 - now</contrib>
</author>
</refentryinfo>
<refmeta>
<refentrytitle>logoutd</refentrytitle>
<manvolnum>8</manvolnum>
<refmiscinfo class="sectdesc">System Management Commands</refmiscinfo>
<refmiscinfo class="source">shadow-utils</refmiscinfo>
<refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
</refmeta>
<refnamediv id='name'>
<refname>logoutd</refname>
<refpurpose>enforce login time restrictions</refpurpose>
</refnamediv>
<!-- body begins here -->
<refsynopsisdiv id='synopsis'>
<cmdsynopsis>
<command>logoutd</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id='description'>
<title>DESCRIPTION</title>
<para>
<command>logoutd</command> enforces the login time and port
restrictions specified in <filename>/etc/porttime</filename>.
<command>logoutd</command> should be started from
<filename>/etc/rc</filename>. The <filename>/var/run/utmp</filename>
file is scanned periodically and each user name is checked to see if
the named user is permitted on the named port at the current time.
Any login session which is violating the restrictions in
<filename>/etc/porttime</filename> is terminated.
</para>
</refsect1>
<refsect1 id='files'>
<title>FILES</title>
<variablelist>
<varlistentry>
<term><filename>/etc/porttime</filename></term>
<listitem>
<para>File containing port access.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>/var/run/utmp</filename></term>
<listitem>
<para>List of current login sessions.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>

View File

@ -14,7 +14,6 @@ man_MANS = \
man8/groupmems.8 \
man8/groupmod.8 \
man8/grpck.8 \
man8/logoutd.8 \
man1/newgrp.1 \
man1/sg.1 \
man3/shadow.3 \

View File

@ -90,6 +90,7 @@ $(DOMAIN).pot-update: $(XMLFILES) $(srcdir)/XMLFILES
@set -ex; tmpdir=`mktemp -d`; \
origdir=`pwd`; \
cd $(top_srcdir)/man; \
cp -r login.defs.d $$tmpdir/; \
cp *.xml $$tmpdir/; \
files=""; \
for file in $(notdir $(XMLFILES)); do \

View File

@ -20,7 +20,6 @@ XMLFILES = \
$(top_srcdir)/man/login.1.xml \
$(top_srcdir)/man/login.access.5.xml \
$(top_srcdir)/man/login.defs.5.xml \
$(top_srcdir)/man/logoutd.8.xml \
$(top_srcdir)/man/newgrp.1.xml \
$(top_srcdir)/man/newusers.8.xml \
$(top_srcdir)/man/nologin.8.xml \

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -82,8 +82,12 @@
If the password field begins with an exclamation mark <emphasis>!</emphasis>,
the password is locked.
The remaining characters on the
line represent the password field before the password was
locked.
line represent the password hash.
</para>
<para>
If the password hash consists of a star <emphasis>*</emphasis>,
password access is effectively disallowed;
this is because no password can produce a hash like this.
</para>
<para>
Refer to <citerefentry><refentrytitle>crypt</refentrytitle>

View File

@ -14,7 +14,6 @@ man_MANS = \
man8/groupmod.8 \
man8/grpck.8 \
man5/gshadow.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/nologin.8 \
man1/passwd.1 \

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -134,6 +134,33 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--btrfs-subvolume-home</option>
</term>
<listitem>
<para>
Create the user's home directory as a Btrfs subvolume.
</para>
<para>
If this option is not specified,
<command>useradd</command> will follow the default behavior
defined by the <option>BTRFS_SUBVOLUME_HOME</option> variable
in <filename>/etc/default/useradd</filename>.
If this variable is not set, the default value is no.
</para>
<para>
When the <option>--btrfs-subvolume-home</option> command-line option
is specified,
a Btrfs subvolume is created
regardless of any configuration file settings.
</para>
<para>
Note: this feature works only if the underlying filesystem supports
Btrfs subvolumes.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-c</option>, <option>--comment</option>&nbsp;<replaceable>COMMENT</replaceable>
@ -160,7 +187,7 @@
login directory name.
The directory <replaceable>HOME_DIR</replaceable> is not created by
default. However it will be created for non-system users if either the
<option>-m</option> flag is specifed or
<option>-m</option> flag is specified or
<replaceable>CREATE_HOME</replaceable> in
<filename>login.defs</filename> is set to true. However, it will never
be created if the <option>-M</option> flag is specified.

View File

@ -22,7 +22,6 @@ man_MANS = \
man5/gshadow.5 \
man1/login.1 \
man5/login.defs.5 \
man8/logoutd.8 \
man1/newgrp.1 \
man8/newusers.8 \
man8/nologin.8 \

View File

@ -92,7 +92,6 @@ src/grpunconv.c
src/lastlog.c
src/login.c
src/login_nopam.c
src/logoutd.c
src/newgidmap.c
src/newgrp.c
src/newuidmap.c

1
src/.gitignore vendored
View File

@ -15,7 +15,6 @@
/grpunconv
/lastlog
/login
/logoutd
/newgrp
/newgidmap
/newuidmap

View File

@ -48,7 +48,6 @@ usbin_PROGRAMS = \
grpck \
grpconv \
grpunconv \
logoutd \
newusers \
pwck \
pwconv \
@ -70,9 +69,6 @@ endif
if !WITH_TCB
suidubins += passwd
endif
if ACCT_TOOLS_SETUID
suidusbins += chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
endif
if ENABLE_SUBIDS
if !FCAPS
suidubins += newgidmap newuidmap
@ -87,12 +83,6 @@ LDADD = $(INTLLIBS) \
$(top_builddir)/lib/libshadow.la \
$(LIBTCB)
if ACCT_TOOLS_SETUID
LIBPAM_SUID = $(LIBPAM)
else
LIBPAM_SUID =
endif
if USE_PAM
LIBCRYPT_NOPAM =
else
@ -103,15 +93,15 @@ chage_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chgpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF)
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) -ldl
expiry_LDADD = $(LDADD) $(LIBECONF)
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF)
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
groupadd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
groupdel_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
groupmems_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
groupmod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
groupmod_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) -ldl
grpck_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
grpconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
grpunconv_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
@ -132,9 +122,9 @@ su_SOURCES = \
suauth.c
su_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) $(LIBSELINUX)
sulogin_LDADD = $(LDADD) $(LIBCRYPT) $(LIBECONF)
useradd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
userdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
usermod_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBATTR) $(LIBECONF) -ldl
useradd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBECONF) -ldl
userdel_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBECONF) -ldl
usermod_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBSEMANAGE) $(LIBACL) $(LIBECONF) -ldl
vipw_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF)
install-am: all-am

View File

@ -18,11 +18,6 @@
#include <stdio.h>
#include <stdlib.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "atoi/a2i.h"
#include "defines.h"
#include "nscd.h"
@ -80,7 +75,6 @@ NORETURN static void fail_exit (int code, bool process_selinux);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv, struct option_flags *flags);
static void check_flags (void);
static void check_perms (void);
static void open_files (bool process_selinux);
static void close_files(const struct option_flags *flags);
@ -292,56 +286,6 @@ static void check_flags (void)
}
}
/*
* check_perms - check if the caller is allowed to add a group
*
* With PAM support, the setuid bit can be set on chgpasswd to allow
* non-root users to groups.
* Without PAM support, only users who can write in the group databases
* can add groups.
*
* It will not return if the user is not allowed.
*/
static void check_perms (void)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (NULL == pampw) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
exit (1);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
exit (1);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
}
/*
* open_files - lock and open the group databases
*/
@ -463,8 +407,6 @@ int main (int argc, char **argv)
OPENLOG (Prog);
check_perms ();
#ifdef SHADOWGRP
is_shadow_grp = sgr_file_present ();
#endif

View File

@ -79,7 +79,6 @@ NORETURN static void fail_exit (int code, bool process_selinux);
NORETURN static void usage (int status);
static void process_flags (int argc, char **argv, struct option_flags *flags);
static void check_flags (void);
static void check_perms (void);
static void open_files(const struct option_flags *flags);
static void close_files(const struct option_flags *flags);
@ -288,60 +287,6 @@ static void check_flags (void)
}
}
/*
* check_perms - check if the caller is allowed to add a group
*
* With PAM support, the setuid bit can be set on chpasswd to allow
* non-root users to groups.
* Without PAM support, only users who can write in the group databases
* can add groups.
*
* It will not return if the user is not allowed.
*/
static void check_perms (void)
{
#ifdef USE_PAM
#ifdef ACCT_TOOLS_SETUID
/* If chpasswd uses PAM and is SUID, check the permissions,
* otherwise, the permissions are enforced by the access to the
* passwd and shadow files.
*/
pam_handle_t *pamh = NULL;
int retval;
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (NULL == pampw) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
exit (1);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
exit (1);
}
(void) pam_end (pamh, retval);
#endif /* ACCT_TOOLS_SETUID */
#endif /* USE_PAM */
}
/*
* open_files - lock and open the password databases
*/
@ -503,8 +448,6 @@ int main (int argc, char **argv)
OPENLOG (Prog);
check_perms ();
#ifdef USE_PAM
if (!use_pam)
#endif /* USE_PAM */
@ -576,7 +519,7 @@ int main (int argc, char **argv)
/*
* Prevent adding a non valid hash to /etc/shadow and
* potentialy lock account
* potentially lock account
*/
if (eflg) {

View File

@ -5,10 +5,9 @@
#include <unistd.h>
#include "atoi/a2i.h"
#include "string/strerrno.h"
#include "subid.h"
#include "stdlib.h"
#include "prototypes.h"
#include "shadowlog.h"
/* Test program for the subid freeing routine */
@ -29,8 +28,8 @@ int main(int argc, char *argv[])
struct subordinate_range range;
bool group = false; // get subuids by default
log_set_progname(Prog);
log_set_logfd(stderr);
if (!subid_init(Prog, stderr))
fprintf(stderr, "subid_init: %s\n", strerrno());
while ((c = getopt(argc, argv, "g")) != EOF) {
switch(c) {
case 'g': group = true; break;

View File

@ -6,9 +6,9 @@
#include "atoi/getnum.h"
#include "attr.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "stdlib.h"
#include "string/strcmp/streq.h"
#include "string/strerrno.h"
#include "subid.h"
@ -24,8 +24,8 @@ int main(int argc, char *argv[])
uid_t u;
uid_t *uids;
log_set_progname(Prog);
log_set_logfd(stderr);
if (!subid_init(Prog, stderr))
fprintf(stderr, "subid_init: %s\n", strerrno());
if (argc < 2) {
usage();
}

View File

@ -6,8 +6,8 @@
#include "attr.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "string/strcmp/streq.h"
#include "string/strerrno.h"
#include "subid.h"
static const char Prog[] = "getsubids";
@ -22,8 +22,8 @@ int main(int argc, char *argv[])
struct subid_range *ranges;
const char *owner;
log_set_progname(Prog);
log_set_logfd(stderr);
if (!subid_init(Prog, stderr))
fprintf(stderr, "subid_init: %s\n", strerrno());
if (argc < 2)
usage();
owner = argv[1];

View File

@ -18,12 +18,6 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#include <pwd.h>
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "atoi/getnum.h"
#include "chkname.h"
@ -100,7 +94,6 @@ static void close_files(const struct option_flags *flags);
static void open_files(const struct option_flags *flags);
static void process_flags (int argc, char **argv, struct option_flags *flags);
static void check_flags (void);
static void check_perms (void);
/*
* usage - display usage message and exit
@ -550,56 +543,6 @@ static void check_flags (void)
}
}
/*
* check_perms - check if the caller is allowed to add a group
*
* With PAM support, the setuid bit can be set on groupadd to allow
* non-root users to groups.
* Without PAM support, only users who can write in the group databases
* can add groups.
*
* It will not return if the user is not allowed.
*/
static void check_perms (void)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (NULL == pampw) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
fail_exit (1);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
fail_exit (1);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
}
/*
* main - groupadd command
*/
@ -634,8 +577,6 @@ int main (int argc, char **argv)
*/
process_flags (argc, argv, &flags);
check_perms ();
if (run_parts ("/etc/shadow-maint/groupadd-pre.d", group_name,
Prog)) {
exit(1);

View File

@ -15,11 +15,6 @@
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
@ -362,12 +357,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags)
int main (int argc, char **argv)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
struct option_flags flags = {.chroot = false, .prefix = false};
log_set_progname(Prog);
@ -394,41 +383,6 @@ int main (int argc, char **argv)
process_flags (argc, argv, &flags);
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (pampw == NULL) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
fail_exit (1);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
fail_exit (1);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#ifdef SHADOWGRP
is_shadow_grp = sgr_file_present ();

View File

@ -20,12 +20,6 @@
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#include <pwd.h>
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "alloc/malloc.h"
#include "atoi/getnum.h"
@ -783,12 +777,6 @@ void update_primary_groups (gid_t ogid, gid_t ngid)
*/
int main (int argc, char **argv)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
struct option_flags flags = {.chroot = false, .prefix = false};
log_set_progname(Prog);
@ -815,42 +803,6 @@ int main (int argc, char **argv)
process_flags (argc, argv, &flags);
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (NULL == pampw) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
exit (E_PAM_USERNAME);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
exit (E_PAM_ERROR);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#ifdef SHADOWGRP
is_shadow_grp = sgr_file_present ();
#endif

View File

@ -1,252 +0,0 @@
/*
* SPDX-FileCopyrightText: 1991 - 1993, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "config.h"
#ident "$Id$"
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utmpx.h>
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "sizeof.h"
#include "string/strcmp/strneq.h"
#include "string/strcpy/strncat.h"
#include "string/strdup/strndupa.h"
/*
* Global variables
*/
static const char Prog[] = "logoutd";
#ifndef DEFAULT_HUP_MESG
#define DEFAULT_HUP_MESG _("login time exceeded\n\n")
#endif
#ifndef HUP_MESG_FILE
#define HUP_MESG_FILE "/etc/logoutd.mesg"
#endif
/* local function prototypes */
static int check_login (const struct utmpx *ut);
static void send_mesg_to_tty (int tty_fd);
/*
* check_login - check if user (struct utmpx) allowed to stay logged in
*/
static int
check_login(const struct utmpx *ut)
{
char *user;
char *line;
time_t now;
user = strndupa_a(ut->ut_user);
line = strndupa_a(ut->ut_line);
now = time(NULL);
return isttytime(user, line, now);
}
static void send_mesg_to_tty (int tty_fd)
{
TERMIO oldt, newt;
FILE *mesg_file, *tty_file;
bool is_tty;
tty_file = fdopen (tty_fd, "w");
if (NULL == tty_file) {
return;
}
is_tty = (GTTY (tty_fd, &oldt) == 0);
if (is_tty) {
/* Suggested by Ivan Nejgebauar <ian@unsux.ns.ac.yu>:
set OPOST before writing the message. */
newt = oldt;
newt.c_oflag |= OPOST;
STTY (tty_fd, &newt);
}
mesg_file = fopen (HUP_MESG_FILE, "r");
if (NULL != mesg_file) {
int c;
while ((c = getc (mesg_file)) != EOF) {
if (c == '\n') {
putc ('\r', tty_file);
}
putc (c, tty_file);
}
fclose (mesg_file);
} else {
fputs (DEFAULT_HUP_MESG, tty_file);
}
fflush (tty_file);
fclose (tty_file);
if (is_tty) {
STTY (tty_fd, &oldt);
}
}
/*
* logoutd - logout daemon to enforce /etc/porttime file policy
*
* logoutd is started at system boot time and enforces the login
* time and port restrictions specified in /etc/porttime. The
* utmp file is periodically scanned and offending users are logged
* off from the system.
*/
int
main(int argc, char *[])
{
pid_t pid;
if (1 != argc) {
(void) fputs (_("Usage: logoutd\n"), stderr);
}
(void) setlocale (LC_ALL, "");
(void) bindtextdomain (PACKAGE, LOCALEDIR);
(void) textdomain (PACKAGE);
#ifndef DEBUG
for (int i = 0; close(i) == 0; i++);
setpgrp ();
/*
* Put this process in the background.
*/
pid = fork ();
if (pid > 0) {
/* parent */
exit (EXIT_SUCCESS);
} else if (pid < 0) {
/* error */
perror ("fork");
exit (EXIT_FAILURE);
}
#endif /* !DEBUG */
/*
* Start syslogging everything
*/
log_set_progname(Prog);
log_set_logfd(stderr);
OPENLOG (Prog);
/*
* Scan the utmp file once per minute looking for users that
* are not supposed to still be logged in.
*/
while (true) {
struct utmpx *ut;
/*
* Attempt to re-open the utmp file. The file is only
* open while it is being used.
*/
setutxent();
/*
* Read all of the entries in the utmp file. The entries
* for login sessions will be checked to see if the user
* is permitted to be signed on at this time.
*/
while (NULL != (ut = getutxent())) {
int tty_fd;
char tty_name[sizeof(ut->ut_line) + 6]; // /dev/ + NUL
if (ut->ut_type != USER_PROCESS) {
continue;
}
if (strneq_a(ut->ut_user, ""))
continue;
if (check_login (ut)) {
continue;
}
/*
* Put the rest of this in a child process. This
* keeps the scan from waiting on other ports to die.
*/
pid = fork ();
if (pid > 0) {
/* parent */
continue;
} else if (pid < 0) {
/* failed - give up until the next scan */
break;
}
/* child */
if (strncmp(ut->ut_line, "/dev/", 5) != 0)
strcpy(tty_name, "/dev/");
else
strcpy(tty_name, "");
strncat_a(tty_name, ut->ut_line);
#ifndef O_NOCTTY
#define O_NOCTTY 0
#endif
tty_fd =
open (tty_name, O_WRONLY | O_NDELAY | O_NOCTTY);
if (tty_fd != -1) {
send_mesg_to_tty (tty_fd);
close (tty_fd);
sleep (10);
}
if (ut->ut_pid > 1) {
kill (-ut->ut_pid, SIGHUP);
sleep (10);
kill (-ut->ut_pid, SIGKILL);
}
SYSLOG ((LOG_NOTICE,
"logged off user '%s' on '%s'",
strndupa_a(ut->ut_user),
tty_name));
/*
* This child has done all it can, drop dead.
*/
exit (EXIT_SUCCESS);
}
endutxent();
#ifndef DEBUG
sleep (60);
#endif
/*
* Reap any dead babies ...
*/
while (wait(NULL) != -1);
}
return EXIT_FAILURE;
}

View File

@ -4,10 +4,9 @@
#include <unistd.h>
#include "atoi/a2i.h"
#include "string/strerrno.h"
#include "subid.h"
#include "stdlib.h"
#include "prototypes.h"
#include "shadowlog.h"
/* Test program for the subid creation routine */
@ -31,8 +30,8 @@ int main(int argc, char *argv[])
bool group = false; // get subuids by default
bool ok;
log_set_progname(Prog);
log_set_logfd(stderr);
if (!subid_init(Prog, stderr))
fprintf(stderr, "subid_init: %s\n", strerrno());
while ((c = getopt(argc, argv, "gn")) != EOF) {
switch(c) {
case 'n': makenew = true; break;

View File

@ -36,11 +36,6 @@
#include "atoi/a2i.h"
#include "atoi/getnum.h"
#include "attr.h"
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "chkname.h"
#include "defines.h"
#include "getdef.h"
@ -118,7 +113,6 @@ static int update_passwd (struct passwd *, const char *);
static int add_passwd (struct passwd *, const char *);
static void process_flags (int argc, char **argv, struct option_flags *flags);
static void check_flags (void);
static void check_perms(const struct option_flags *flags);
static void open_files (bool process_selinux);
static void close_files(const struct option_flags *flags);
@ -788,60 +782,6 @@ static void check_flags (void)
#endif /* !USE_PAM */
}
/*
* check_perms - check if the caller is allowed to add a group
*
* With PAM support, the setuid bit can be set on groupadd to allow
* non-root users to groups.
* Without PAM support, only users who can write in the group databases
* can add groups.
*
* It will not return if the user is not allowed.
*/
static void
check_perms(MAYBE_UNUSED const struct option_flags *flags)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
struct passwd *pampw;
bool process_selinux;
process_selinux = !flags->chroot;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (NULL == pampw) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
fail_exit (EXIT_FAILURE, process_selinux);
}
retval = pam_start ("newusers", pampw->pw_name, &conv, &pamh);
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
fail_exit (EXIT_FAILURE, process_selinux);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
}
/*
* open_files - lock and open the password, group and shadow databases
*/
@ -1088,8 +1028,6 @@ int main (int argc, char **argv)
process_flags (argc, argv, &flags);
process_selinux = !flags.chroot;
check_perms (&flags);
is_shadow = spw_file_present ();
#ifdef SHADOWGRP

View File

@ -60,7 +60,6 @@
#include "prototypes.h"
#include "shadowlog.h"
#include "string/sprintf/aprintf.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strcpy/strtcpy.h"
@ -94,12 +93,9 @@ static char caller_name[BUFSIZ];
static bool change_environment = true;
#ifdef USE_PAM
static char kill_msg[256];
static char wait_msg[256];
static pam_handle_t *pamh = NULL;
static int caught = 0;
/* PID of the child, in case it needs to be killed */
static pid_t pid_child = 0;
static volatile sig_atomic_t caught = 0;
static volatile sig_atomic_t timeout = 0;
#endif
/*
@ -115,8 +111,9 @@ static void execve_shell (const char *shellname,
char *args[],
char *const envp[]);
#ifdef USE_PAM
static void kill_child(int);
static void kill_child(pid_t);
static void prepare_pam_close_session (void);
static void set_timeout(int);
#else /* !USE_PAM */
static void die (int);
static bool iswheel (const char *);
@ -169,16 +166,19 @@ static bool iswheel (const char *username)
return is_on_list (grp->gr_mem, username);
}
#else /* USE_PAM */
NORETURN
static void
kill_child(int)
kill_child(pid_t pid_child)
{
if (0 != pid_child) {
(void) kill (-pid_child, SIGKILL);
(void) write_full(STDERR_FILENO, kill_msg, strlen(kill_msg));
} else {
(void) write_full(STDERR_FILENO, wait_msg, strlen(wait_msg));
}
_exit (255);
kill(-pid_child, SIGKILL);
fputs(_(" ...killed.\n"), stderr);
exit (255);
}
static void
set_timeout(int)
{
timeout = 1;
}
#endif /* USE_PAM */
@ -286,6 +286,7 @@ static void prepare_pam_close_session (void)
int status;
int ret;
struct sigaction action;
pid_t pid_child;
/* reset SIGCHLD handling to default */
action.sa_handler = SIG_DFL;
@ -368,7 +369,7 @@ static void prepare_pam_close_session (void)
&& (EINTR == errno)
&& (SIGTSTP == caught)) {
caught = 0;
/* Except for SIGTSTP, which request to
/* Except for SIGTSTP, which requests to
* stop the child.
* We will SIGSTOP ourself on the next
* waitpid round.
@ -395,21 +396,18 @@ static void prepare_pam_close_session (void)
stderr);
(void) kill (-pid_child, caught);
stprintf_a(kill_msg, _(" ...killed.\n"));
stprintf_a(wait_msg, _(" ...waiting for child to terminate.\n"));
/* Any signals other than SIGCHLD and SIGALRM will no longer have any effect,
* so it's time to block all of them. */
sigfillset (&ourset);
if (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0) {
fprintf (stderr, _("%s: signal masking malfunction\n"), Prog);
kill_child (0);
/* Never reach (_exit called). */
kill_child(pid_child);
/* Never reached (exit called). */
}
/* Send SIGKILL to the child if it doesn't
* exit within 2 seconds (after SIGTERM) */
(void) signal (SIGALRM, kill_child);
(void) signal (SIGALRM, set_timeout);
(void) signal (SIGCHLD, catch_signals);
(void) alarm (2);
@ -418,6 +416,10 @@ static void prepare_pam_close_session (void)
while (0 == waitpid (pid_child, &status, WNOHANG)) {
sigsuspend (&ourset);
if (timeout) {
kill_child(pid_child);
/* Never reached (exit called). */
}
}
pid_child = 0;

View File

@ -23,11 +23,6 @@
#include <libgen.h>
#include <pwd.h>
#include <signal.h>
#ifdef ACCT_TOOLS_SETUID
# ifdef USE_PAM
# include "pam_defs.h"
# endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include <paths.h>
#include <stddef.h>
#include <stdio.h>
@ -114,6 +109,7 @@ static const char *def_shell = "/bin/bash";
static const char *def_template = SKEL_DIR;
static const char *def_usrtemplate = USRSKELDIR;
static const char *def_create_mail_spool = "yes";
static const char *def_btrfs_subvolume_home = "no";
static const char *def_log_init = "yes";
static long def_inactive = -1;
@ -222,6 +218,7 @@ static bool home_added = false;
#define DSKEL "SKEL"
#define DUSRSKEL "USRSKEL"
#define DCREATE_MAIL_SPOOL "CREATE_MAIL_SPOOL"
#define DBTRFS_SUBVOLUME_HOME "BTRFS_SUBVOLUME_HOME"
#define DLOG_INIT "LOG_INIT"
/* local function prototypes */
@ -456,6 +453,7 @@ get_defaults(const struct option_flags *flags)
def_usrtemplate = xstrdup(ccp);
}
}
/*
* Create by default user mail spool or not ?
*/
@ -466,6 +464,15 @@ get_defaults(const struct option_flags *flags)
def_create_mail_spool = xstrdup(ccp);
}
/*
* Create home directories as Btrfs subvolumes by default?
*/
else if (streq(buf, DBTRFS_SUBVOLUME_HOME)) {
if (streq(ccp, ""))
ccp = "no";
def_btrfs_subvolume_home = xstrdup(ccp);
}
/*
* By default do we add the user to the lastlog and faillog databases ?
*/
@ -500,6 +507,7 @@ static void show_defaults (void)
printf ("SKEL=%s\n", def_template);
printf ("USRSKEL=%s\n", def_usrtemplate);
printf ("CREATE_MAIL_SPOOL=%s\n", def_create_mail_spool);
printf ("BTRFS_SUBVOLUME_HOME=%s\n", def_btrfs_subvolume_home);
printf ("LOG_INIT=%s\n", def_log_init);
}
@ -523,6 +531,7 @@ set_defaults(void)
bool out_skel = false;
bool out_usrskel = false;
bool out_create_mail_spool = false;
bool out_btrfs_subvolume_home = false;
bool out_log_init = false;
char buf[1024];
char *new_file = NULL;
@ -639,6 +648,11 @@ set_defaults(void)
DCREATE_MAIL_SPOOL "=%s\n",
def_create_mail_spool);
out_create_mail_spool = true;
} else if (!out_btrfs_subvolume_home && streq(buf, DBTRFS_SUBVOLUME_HOME)) {
fprintf(ofp,
DBTRFS_SUBVOLUME_HOME "=%s\n",
def_btrfs_subvolume_home);
out_btrfs_subvolume_home = true;
} else if (!out_log_init && streq(buf, DLOG_INIT)) {
fprintf(ofp, DLOG_INIT "=%s\n", def_log_init);
out_log_init = true;
@ -673,6 +687,8 @@ set_defaults(void)
if (!out_create_mail_spool)
fprintf (ofp, DCREATE_MAIL_SPOOL "=%s\n", def_create_mail_spool);
if (!out_btrfs_subvolume_home)
fprintf (ofp, DBTRFS_SUBVOLUME_HOME "=%s\n", def_btrfs_subvolume_home);
if (!out_log_init)
fprintf (ofp, DLOG_INIT "=%s\n", def_log_init);
/*
@ -1431,6 +1447,9 @@ static void process_flags (int argc, char **argv, struct option_flags *flags)
}
}
if (!subvolflg && strcaseeq(def_btrfs_subvolume_home, "yes"))
subvolflg = true;
if (!gflg && !Nflg && !Uflg) {
/* Get the settings from login.defs */
Uflg = getdef_bool ("USERGROUPS_ENAB");
@ -2430,13 +2449,6 @@ static void check_uid_range(int rflg, uid_t user_id)
*/
int main (int argc, char **argv)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#ifdef ENABLE_SUBIDS
uid_t uid_min;
uid_t uid_max;
@ -2500,42 +2512,6 @@ int main (int argc, char **argv)
exit(1);
}
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (pampw == NULL && getuid ()) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
fail_exit (1, process_selinux);
}
retval = pam_start (Prog, pampw?pampw->pw_name:"root", &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
fail_exit (1, process_selinux);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
/*
* See if we are messing with the defaults file, or creating
* a new user.
@ -2684,9 +2660,9 @@ int main (int argc, char **argv)
if (mflg) {
create_home (&flags);
if (home_added) {
copy_tree (def_template, prefix_user_home, false, true,
copy_tree (def_template, prefix_user_home, false,
(uid_t)-1, user_id, (gid_t)-1, user_gid);
copy_tree (def_usrtemplate, prefix_user_home, false, true,
copy_tree (def_usrtemplate, prefix_user_home, false,
(uid_t)-1, user_id, (gid_t)-1, user_gid);
} else {
fprintf (stderr,

View File

@ -20,11 +20,6 @@
#include <sys/types.h>
#include <unistd.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include "defines.h"
#include "getdef.h"
#include "groupio.h"
@ -909,12 +904,6 @@ int main (int argc, char **argv)
{
bool errors = false; /* Error in the removal of the home directory */
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
struct option_flags flags = {.chroot = false, .prefix = false};
bool process_selinux;
@ -1001,42 +990,6 @@ int main (int argc, char **argv)
usage (E_USAGE);
}
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (pampw == NULL) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
exit (E_PW_UPDATE);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
exit (E_PW_UPDATE);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
is_shadow_pwd = spw_file_present ();
#ifdef SHADOWGRP
is_shadow_grp = sgr_file_present ();

View File

@ -21,13 +21,9 @@
#include <lastlog.h>
#endif /* ENABLE_LASTLOG */
#include <pwd.h>
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
@ -97,6 +93,7 @@
#define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */
#define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */
#endif /* ENABLE_SUBIDS */
#define E_PASSWORDLESS 20 /* would result in a passwordless account */
#define VALID(s) (!strpbrk(s, ":\n"))
@ -437,7 +434,8 @@ usage (int status)
* update encrypted password string (for both shadow and non-shadow
* passwords)
*/
static char *new_pw_passwd (char *pw_pass)
static char *
new_pw_passwd(char *pw_pass, bool process_selinux)
{
if (Lflg && ('!' != pw_pass[0])) {
#ifdef WITH_AUDIT
@ -452,7 +450,7 @@ static char *new_pw_passwd (char *pw_pass)
_("%s: unlocking the user's password would result in a passwordless account.\n"
"You should set a password with usermod -p to unlock this user's password.\n"),
Prog);
return pw_pass;
fail_exit(E_PASSWORDLESS, process_selinux);
}
#ifdef WITH_AUDIT
@ -507,7 +505,7 @@ static void new_pwent (struct passwd *pwent, bool process_selinux)
*/
if ( (!is_shadow_pwd)
|| !streq(pwent->pw_passwd, SHADOW_PASSWD_STRING)) {
pwent->pw_passwd = new_pw_passwd (pwent->pw_passwd);
pwent->pw_passwd = new_pw_passwd(pwent->pw_passwd, process_selinux);
}
if (uflg) {
@ -622,7 +620,7 @@ static void new_spent (struct spwd *spent, bool process_selinux)
* + there were already both entries
* + aging has been requested
*/
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
spent->sp_pwdp = new_pw_passwd(spent->sp_pwdp, process_selinux);
if (pflg) {
spent->sp_lstchg = gettime () / DAY;
@ -1388,6 +1386,48 @@ process_flags(int argc, char **argv, struct option_flags *flags)
}
#endif /* WITH_SELINUX */
if (user_newid == user_id) {
uflg = false;
oflg = false;
}
if (user_newgid == user_gid) {
gflg = false;
}
if ( (NULL != user_newshell)
&& streq(user_newshell, user_shell)) {
sflg = false;
}
if (streq(user_newname, user_name)) {
lflg = false;
}
if (user_newinactive == user_inactive) {
fflg = false;
}
if (user_newexpire == user_expire) {
eflg = false;
}
if ( (NULL != user_newhome)
&& streq(user_newhome, user_home)) {
dflg = false;
mflg = false;
}
if ( (NULL != user_newcomment)
&& streq(user_newcomment, user_comment)) {
cflg = false;
}
if (!(Uflg || uflg || sflg || pflg || mflg || Lflg ||
lflg || Gflg || gflg || fflg || eflg || dflg || cflg
#ifdef ENABLE_SUBIDS
|| vflg || Vflg || wflg || Wflg
#endif /* ENABLE_SUBIDS */
#ifdef WITH_SELINUX
|| Zflg
#endif /* WITH_SELINUX */
)) {
exit (E_SUCCESS);
}
if (!is_shadow_pwd && (eflg || fflg)) {
fprintf (stderr,
_("%s: shadow passwords required for -e and -f\n"),
@ -1850,7 +1890,6 @@ static void move_home (bool process_selinux)
#endif
if (copy_tree (prefix_user_home, prefix_user_newhome, true,
true,
user_id,
uflg ? user_newid : (uid_t)-1,
user_gid,
@ -2128,12 +2167,6 @@ static void move_mailbox (void)
*/
int main (int argc, char **argv)
{
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
pam_handle_t *pamh = NULL;
int retval;
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
struct option_flags flags = {.chroot = false, .prefix = false};
bool process_selinux;
@ -2182,42 +2215,6 @@ int main (int argc, char **argv)
exit (E_USER_BUSY);
}
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
{
struct passwd *pampw;
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
if (pampw == NULL) {
fprintf (stderr,
_("%s: Cannot determine your user name.\n"),
Prog);
exit (1);
}
retval = pam_start (Prog, pampw->pw_name, &conv, &pamh);
}
if (PAM_SUCCESS == retval) {
retval = pam_authenticate (pamh, 0);
}
if (PAM_SUCCESS == retval) {
retval = pam_acct_mgmt (pamh, 0);
}
if (PAM_SUCCESS != retval) {
fprintf (stderr, _("%s: PAM: %s\n"),
Prog, pam_strerror (pamh, retval));
SYSLOG((LOG_ERR, "%s", pam_strerror (pamh, retval)));
if (NULL != pamh) {
(void) pam_end (pamh, retval);
}
exit (1);
}
(void) pam_end (pamh, retval);
#endif /* USE_PAM */
#endif /* ACCT_TOOLS_SETUID */
#ifdef WITH_TCB
if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) {
exit (E_PW_UPDATE);

View File

@ -43,6 +43,7 @@
#endif /* WITH_TCB */
#include "shadowlog.h"
#include "sssd.h"
#include "fs/mkstemp/fmkomstemp.h"
#include "string/sprintf/aprintf.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/streq.h"
@ -72,7 +73,7 @@ static bool tcb_mode = false;
/* local function prototypes */
static void usage (int status);
static int create_backup_file (FILE *, const char *, struct stat *);
static int create_backup_file (FILE *, char *, struct stat *);
static void vipwexit (const char *msg, int syserr, int ret);
static void vipwedit (const char *, int (*)(void), int (*)(bool));
@ -103,16 +104,13 @@ static void usage (int status)
/*
*
*/
static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
static int create_backup_file (FILE * fp, char *backup, struct stat *sb)
{
struct utimbuf ub;
FILE *bkfp;
int c;
mode_t mask;
mask = umask (077);
bkfp = fopen (backup, "w");
(void) umask (mask);
bkfp = fmkomstemp(backup, 0, 0600);
if (NULL == bkfp) {
return -1;
}
@ -134,16 +132,18 @@ static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
unlink (backup);
return -1;
}
if (fclose (bkfp) != 0) {
unlink (backup);
return -1;
}
ub.actime = sb->st_atime;
ub.modtime = sb->st_mtime;
if ( (utime (backup, &ub) != 0)
|| (chmod (backup, sb->st_mode) != 0)
|| (chown (backup, sb->st_uid, sb->st_gid) != 0)) {
|| (fchown(fileno(bkfp), sb->st_uid, sb->st_gid) != 0)
|| (fchmod(fileno(bkfp), sb->st_mode) != 0)) {
fclose(bkfp);
unlink (backup);
return -1;
}
if (fclose (bkfp) != 0) {
unlink (backup);
return -1;
}
@ -217,11 +217,11 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
vipwexit (_("failed to drop privileges"), errno, 1);
}
stprintf_a(fileedit,
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.vipw.shadow.%s",
user);
TCB_DIR "/" SHADOWTCB_SCRATCHDIR "/.%s.shadow.%s.XXXXXX",
Prog, user);
} else {
#endif /* WITH_TCB */
stprintf_a(fileedit, "%s.edit", file);
stprintf_a(fileedit, "/etc/.%s.XXXXXX", Prog);
#ifdef WITH_TCB
}
#endif /* WITH_TCB */
@ -291,6 +291,9 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
orig_pgrp = tcgetpgrp(STDIN_FILENO);
/* set SIGCHLD to default for waitpid */
signal(SIGCHLD, SIG_DFL);
pid = fork ();
if (-1 == pid) {
vipwexit ("fork", 1, 1);
@ -338,9 +341,6 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
sigprocmask(SIG_BLOCK, &mask, &omask);
}
/* set SIGCHLD to default for waitpid */
signal(SIGCHLD, SIG_DFL);
for (;;) {
pid = waitpid (pid, &status, WUNTRACED);
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
@ -426,7 +426,7 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (bool))
if (stat (file, &st1) != 0) {
vipwexit (_("failed to stat edited file"), errno, 1);
}
to_rename = aprintf("%s+", file);
to_rename = aprintf("%s,XXXXXX", file);
if (to_rename == NULL)
vipwexit (_("aprintf() failed"), errno, 1);

View File

@ -61,7 +61,7 @@ class UnixObject(object):
if len(o) != 2 or not isinstance(o[0], int) or not isinstance(o[1], str):
raise NotImplementedError(f"Unable to compare {type(o)} with {self.__class__}")
(id, name) = o
id, name = o
return id == self.id and name == self.name
elif isinstance(o, UnixObject):
# Fallback to identity comparison
@ -388,8 +388,8 @@ class GShadowEntry(object):
self,
name: str | None,
password: str | None,
administrators: str | None,
members: str | None,
administrators: list[str],
members: list[str],
) -> None:
self.name: str | None = name
"""
@ -401,18 +401,18 @@ class GShadowEntry(object):
Group password.
"""
self.administrators: str | None = administrators
self.administrators: list[str] = administrators
"""
Group administrators.
"""
self.members: str | None = members
self.members: list[str] = members
"""
Group members.
"""
def __str__(self) -> str:
return f"({self.name}:{self.password}:{self.administrators}:" f"{self.members})"
return f"({self.name}:{self.password}:" f"{self.administrators}:" f"{self.members})"
def __repr__(self) -> str:
return str(self)
@ -422,7 +422,7 @@ class GShadowEntry(object):
return cls(
name=d.get("group_name", None),
password=d.get("password", None),
administrators=d.get("administrators", None),
administrators=d.get("administrators", []),
members=d.get("members", []),
)

View File

@ -69,3 +69,63 @@ def test_groupmod__u_option_empty_string_clears_members(shadow: Shadow):
assert gshadow_entry is not None, "Group should be found"
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
assert not gshadow_entry.members, "Group should have no members"
@pytest.mark.topology(KnownTopology.Shadow)
def test_groupmod__u_option_with_user_list(shadow: Shadow):
"""
:title: Test groupmod -U option with user list to set group membership
:setup:
1. Create three test users
2. Create test group
:steps:
1. Set group membership to all three users using groupmod -U
2. Verify all three users are members in group and gshadow entry
3. Modify group membership to only two users using groupmod -U
4. Verify updated membership in group and gshadow entries
:expectedresults:
1. Initial groupmod -U command sets membership correctly for all three users
2. group and gshadow entries show correct membership
3. Second groupmod -U command updates membership correctly
4. Updated group and gshadow entries reflect new membership
:customerscenario: False
"""
shadow.useradd("tuser1")
shadow.useradd("tuser2")
shadow.useradd("tuser3")
shadow.groupadd("tgroup")
shadow.groupmod("-U tuser1,tuser2,tuser3 tgroup")
group_entry = shadow.tools.getent.group("tgroup")
assert group_entry is not None, "Group should be found"
assert group_entry.name == "tgroup", "Incorrect groupname"
assert len(group_entry.members) == 3, f"Group should have 3 members, but has {len(group_entry.members)}"
assert "tuser1" in group_entry.members, "tuser1 should be a member of tgroup"
assert "tuser2" in group_entry.members, "tuser2 should be a member of tgroup"
assert "tuser3" in group_entry.members, "tuser3 should be a member of tgroup"
if shadow.host.features["gshadow"]:
gshadow_entry = shadow.tools.getent.gshadow("tgroup")
assert gshadow_entry is not None, "Group should be found"
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
assert len(gshadow_entry.members) == 3, f"Group should have 3 members, but has {len(gshadow_entry.members)}"
assert "tuser1" in gshadow_entry.members, "tuser1 should be a member of tgroup"
assert "tuser2" in gshadow_entry.members, "tuser2 should be a member of tgroup"
assert "tuser3" in gshadow_entry.members, "tuser3 should be a member of tgroup"
shadow.groupmod("-U tuser1,tuser2 tgroup")
group_entry = shadow.tools.getent.group("tgroup")
assert group_entry is not None, "Group should be found"
assert group_entry.name == "tgroup", "Incorrect groupname"
assert len(group_entry.members) == 2, f"Group should have 2 members, but has {len(group_entry.members)}"
assert "tuser1" in group_entry.members, "tuser1 should be a member of tgroup"
assert "tuser2" in group_entry.members, "tuser2 should be a member of tgroup"
if shadow.host.features["gshadow"]:
gshadow_entry = shadow.tools.getent.gshadow("tgroup")
assert gshadow_entry is not None, "Group should be found"
assert gshadow_entry.name == "tgroup", "Incorrect groupname"
assert len(gshadow_entry.members) == 2, f"Group should have 2 members, but has {len(gshadow_entry.members)}"
assert "tuser1" in gshadow_entry.members, "tuser1 should be a member of tgroup"
assert "tuser2" in gshadow_entry.members, "tuser2 should be a member of tgroup"