Commit Graph

3070 Commits

Author SHA1 Message Date
Jaroslav Jindrak
ef8a4449b1 chage: add --prefix/-P options 2023-06-09 16:22:24 +02:00
Jaroslav Jindrak
43e60eb681 passwd: Respect --prefix/-P options
Add prefix_getpwnam_r() and xprefix_getpwnam() and make passwd
use prefix-aware functions when handling the database.
2023-06-09 16:22:24 +02:00
Michael Vetter
ded9cab35d prefix: add prefix support 2023-06-09 16:22:24 +02:00
Iker Pedrosa
89a7ee7b22 strtoday: remove unnecessary cast
Resolves: https://github.com/shadow-maint/shadow/issues/704

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2023-06-09 07:48:48 -05:00
Alejandro Colomar
787ea57a18 Use temporary variable
-  Use the temporary variable more, as it helps readability: it removes
   a derefecence, which itself allows removing some parentheses.

-  Use a shorter name, which is more common with temporaries, and so
   there's less to read.

-  Assign to *ranges at the end of the function.  It's the same, but
   with the other changes, I think this makes it slightly clearer.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-08 09:05:39 -05:00
Alejandro Colomar
f2ac1e2540 realloc(NULL, ...) is equivalent to malloc(...)
Don't have a branch for when the old pointer is NULL.  realloc(3) can
handle that case just fine.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-08 09:05:39 -05:00
Alejandro Colomar
09775d3718 Simplify allocation APIs
If we consider simple objects as arrays of size 1, we can considerably
simplify these APIs, merging the *ARRAY and the non-array variants.

That will produce more readable code, since lines will be shorter (by
not having ARRAY in the macro names, as all macros will consistently
handle arrays), and the allocated size will be also more explicit.

The syntax will now be of the form:

    p = MALLOC(42, foo_t);  // allocate 42 elements of type foo_t.
    p = MALLOC(1, bar_t);   // allocate 1 element of type foo_t.

The _array() allocation functions should _never_ be called directly, and
instead these macros should be used.

The non-array functions (e.g., malloc(3)) still have their place, but
are limited to allocating structures with flexible array members.  For
any other uses, the macros should be used.

Thus, we don't use any array or ARRAY variants in any code any more, and
they are only used as implementation details of these macros.

Link: <https://software.codidact.com/posts/285898/288023#answer-288023>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-08 09:05:39 -05:00
Christian Göttsche
065a752b42 Drop alloca(3)
alloca(3) fails silently if not enough memory can be allocated on the
stack.  Use checked dynamic allocation instead.

Also drop unnecessary manual NUL assignment, ensured by snprintf(3).

Co-developed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-08 09:05:39 -05:00
Christian Göttsche
7a2b302e68 usermod: fix off-by-one issues
Allocate enough memory for the strings, two slashes and the NUL
terminator.

Reported-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-08 09:05:39 -05:00
Alejandro Colomar
170d24a251 libmisc/csrand.c: Update comments
Those comments were written when this function used 64 bits (and
temporary variables of 128 bits).  Now it uses 32 bits, with temporaries
of 64 bits, so some values have changed.

Fixes: 2a61122b5e ("Unoptimize the higher part of the domain of csrand_uniform()")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-06-05 16:50:40 -05:00
Alejandro Colomar
70399856c1 lib/nss.c: Fix use of invalid p
getline(3) might have succeeded in a previous iteration, in which case
p points to an offset that is not valid.  Make p NULL at the end of the
loop, to make sure it doesn't hold old stuff.

Link: <https://github.com/shadow-maint/shadow/pull/737#issuecomment-1568948769>
Reported-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Alejandro Colomar
848a95329c lib/nss.c: Fix use of uninitialized p
getline(3) might have never succeeded, in which case p is uninitialized
when used in strtok_r(3).

Link: <https://github.com/shadow-maint/shadow/pull/737#discussion_r1206007358>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Alejandro Colomar
54ba4814ae Centralize error handling
This makes the function fit in less screens.  This is to avoid consuming
more natural resources than we have available, and everyone knows the
supply of new-lines on a screen is not a renewable source[1].

Some transformations have been done thanks to free(NULL) being an alias
for loopity_loop(), as defined three comits ago.  The real definition of
free(3) that everyone has been hiding is this:

void
free(void *p)
{
	if (p == NULL)
		loopity_loop();
	else
		real_free(p);
}

Link: [1] <https://www.kernel.org/doc/html/v6.3/process/coding-style.html#placing-braces-and-spaces>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Alejandro Colomar
07b885318f Second verse, it gets worse; it gets no better than this
Just in case it's not obious:

	strlen("") < 8
	isalpha('\0') == false
	isdigit('\0') == false
	isspace('\0') == false

Link: <https://github.com/shadow-maint/shadow/pull/737>
Easter-egg: 8492dee663 ("subids: support nsswitch")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Alejandro Colomar
2f9ca4b49d ROFL: Rolling on the floor looping
Please tell me this was an easter egg :P

 #define go_banana() ({ goto nowhere; nowhere: 0-0; })

Closes: <https://github.com/shadow-maint/shadow/issues/736>
Easter-egg: 8492dee663 ("subids: support nsswitch")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Alejandro Colomar
8219fbd421 This ain't no loop
This was to a loop, as "1234" is to computer security.

No really; a loop that ends in a (forward) goto, and has no continue in it.

Still want a loop?  Take two:

 #define loopity_loop() do { for (;;) { break; } continue; } while (0-0)

Closes: <https://github.com/shadow-maint/shadow/issues/736>
Easter-egg: 8492dee663 ("subids: support nsswitch")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-31 09:29:49 -05:00
Iker Pedrosa
9233e5e0ae newusers: Improve error message
Fixes: b422e3c316: Check if crypt_method null before dereferencing

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2023-05-31 09:53:31 +02:00
Martin Kletzander
3c7327842c ch(g)passwd: Check selinux permissions upon startup
The permission also need to be checked before process_root_flag() since
that can chroot into non-selinux environment (unavailable selinux mount
point for example).

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-31 09:44:25 +02:00
Skyler Ferrante
b422e3c316 Check if crypt_method null before dereferencing
Make sure crypto_method set before sha-rounds. Only affects newusers.
2023-05-30 14:00:12 -05:00
Alejandro Colomar
d9f0246611 xgetXXbyYY: Simplify elifs
-  Use SIZE_MAX rather than (size_t)-1, to improve readability.

-  Move the only branch that breaks to the first place, so that we
   remove an else.  This reduces nesting while parsing the code.

-  Now that we only have a 2-branch conditional where both branches
   assign to the same variable, rewrite it as a ternary, to shorten.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-30 13:56:55 -05:00
Alejandro Colomar
89c9427087 xgetXXbyYY: Centralize error handling
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-30 13:56:55 -05:00
Alejandro Colomar
c8741a400d xgetXXbyYY: tfix
It seems obvious that it was a typo.

Link: <https://github.com/shadow-maint/shadow/pull/729#discussion_r1207551013>
Fixes: e73a2194b3 ("xgetXXbyYY: Handle DUP_FUNCTION failure")
Cc: Samanta Navarro <ferivoz@riseup.net>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-30 13:56:55 -05:00
Samanta Navarro
dcc90658fd xgetXXbyYY: Avoid duplicated error handling block
The error handling is performed after the loop. By just calling break it
is possible to reuse the error handling if status is not ERANGE.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-26 16:03:27 -05:00
Samanta Navarro
e73a2194b3 xgetXXbyYY: Handle DUP_FUNCTION failure
A failure of DUP_FUNCTION is already handled for non-reentrant
function wrapper. Perform the check for reentrant version as well.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-26 16:03:27 -05:00
Serge Hallyn
a80b792afc sub_[ug]id_{add,remove}: fix return values
On failure, these are meant to return 0 with errno set.  But if
an nss module is loaded, they were returning -ERRNO instead.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-26 15:16:29 -05:00
Martin Kletzander
8665fe1957 usermod: Small optimization using memmove for password unlock
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2023-05-26 15:14:02 -05:00
Alejandro Colomar
e3b7058110 Reorder logic to improve comprehensibility
-  Don't else after return or fail_exit().
-  Prefer == over != (negated logic is more complex to think about it).
-  Reduce nesting when reasonable.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-25 21:22:08 -05:00
Alejandro Colomar
5b117d5526 newusers: Fail early
There's no reason to report all errors.  Bail out at the first one,
which is simpler.

Suggested-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-25 21:22:08 -05:00
Alejandro Colomar
1957c8c881 newusers: Add missing error handling
Some errors were being reported in stderr, but then they weren't really
being treated as errors.

If mkdir(2) for EEXIST, it's possible that the sysadmin pre-created the
user dir; don't fail.  However, let's keep a log line, for having some
notice that it happened.

Also, run chmod(2) if mkdir(2) failed for EEXIST (so transform the
'else if' into an 'if').

Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2023-05-25 21:22:08 -05:00
Samanta Navarro
6491fef1e0 libmisc: Use safer chroot/chdir sequence
OpenSSH and coreutils' chroot call chroot first and then chdir. Doing it
this way is a bit safer because otherwise something could happen between
chdir and chroot to the specified path (like exchange of links) so the
working directory would not end up within the chroot environment.

This is a purely defensive measure.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-25 08:25:42 -05:00
Samanta Navarro
a116e20c76 su: Prevent stack overflow in check_perms
This is no real world security fix.

The overflow could occur if too many layered subsystems are encountered
because the function check_perms calls itself recursively.

It would already take a misconfigured system for this to achieve it.

Use an iterative approach by calling the do_check_perms in a loop
instead of calling itself recursively.

As a side note: At least GCC 13 optimized this code and already uses
a jmp in its assembler code. I could only see the stack overflow by
activating address sanitizer which prevented the optimization.

Co-developed-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-25 08:25:42 -05:00
Samanta Navarro
4ad359ccc6 subsystem: Prevent endless loop
If a user has home directory "/" and login shell "*" then login and su
enter an endless loop by constantly switching to the next subsystem.

This could also be achieved with a layered approach so just checking
for "/" as home directory is not enough to protect against such a
misconfiguration.

Just break the loop if it progressed too far. I doubt that this has
negative impact on any real setup.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-25 08:25:42 -05:00
Serge Hallyn
419cf1f1c4 def_load: avoid NULL deref
If econf_getStringValue() fails, it will return an error and
set value to NULL.  Look for the error and avoid dereferencing
value in that case.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-22 10:23:12 +02:00
Serge Hallyn
9e854f525d def_load: split the econf from non-econf definition
The function is completely different based on USE_CONF.  Either copy
will be easier to read if we just keep them completely separate.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-22 10:23:12 +02:00
Tobias Stoeckmann
8175b1532e Plug econf memory leaks
You can see the memory leaks with address sanitizer if shadow is
compiled with `--enable-vendordir=/usr/etc`.

How to reproduce:

1. Prepare a custom shell file as root
```
mkdir -p /etc/shells.d
echo /bin/myshell > /etc/shells.d/custom
```

2. Run chsh as regular user
```
chsh
```

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2023-05-19 08:02:24 -05:00
Samanta Navarro
7321ceaf69 chsh: Verify that login shell path is absolute
The getusershell implementation of musl returns every line within the
/etc/shells file, which even includes comments. Only consider absolute
paths for login shells.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-18 16:03:41 +02:00
Samanta Navarro
812f934e77 process_prefix_flag: Drop privileges
Using --prefix in a setuid binary is quite dangerous. An unprivileged
user could prepare a custom shadow file in home directory. During a data
race the user could exchange directories with links which could lead to
exchange of shadow file in system's /etc directory.

This could be used for local privilege escalation.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-18 15:36:59 +02:00
bubu
1132b89236 Update French translations
Please find attached the french updated translation of shadow-man-page,
proofread by the debian-l10n-french mailing list contributors.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2023-05-15 08:42:40 -05:00
Samanta Navarro
4ef4477535 get_pid.c: Use tighter validation checks
Neither a pid_t below 1 nor a negative fd could be valid in this context.

Proof of Concept:

$ newuidmap -1 1 1 1
newuidmap: Could not open proc directory for target 4294967295

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-15 09:21:16 +02:00
Markus Hiereth
a022d39d2a replace inadequate German translation of login error message
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-11 17:01:43 -05:00
Markus Hiereth
bd6db6f226 Update German translations
find the attached German message catalogue proofread by the German
language team.

Best regards
Markus

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-11 11:05:59 -05:00
Samanta Navarro
666468cc36 Remove some static char arrays
Some strings are first written into static char arrays before passed to
functions which expect a const char pointer anyway.

It is easier to pass these strings directly as arguments.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-11 11:05:29 -05:00
Samanta Navarro
72290ede0e commonio: Use do_lock_file again
This avoids regressions introduced with do_fcntl_lock.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-11 10:59:21 -05:00
Serge Hallyn
4abcbb056e Fix broken docbook translations
its by default does not support xml tags inside translatable
units.  Use custom its rules from

https://www.w3.org/TR/xml-i18n-bp/#relating-docbook-plus-its

to enable the tags which are in use by docbook.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2023-05-10 09:15:53 +02:00
ed neville
0bce9c9808 open with O_CREAT when lock path does not exist
Reported in #686, by wyj611 when trying to lock a file that is not
present

Lock method should be F_SETLKW rather than open file descriptor
2023-05-08 08:16:11 -05:00
Samanta Navarro
627631bf9a commonio_open: Remove fcntl call
The fcntl call to set FD_CLOEXEC can be performed directly with the
previously performed open call by using the O_CLOEXEC flag.

O_CLOEXEC is required by POSIX.1-2008.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-05 16:15:46 +02:00
Samanta Navarro
e899e3d745 commonio_lock_nowait: Remove deprecated code
Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-05 16:15:46 +02:00
Samanta Navarro
7109b7c066 login_prompt: Simplify login_prompt API
The only user of login_prompt is the login tool. This implies that the
first argument is always the same.

It is much easier to verify printf's format string and its argument if
both are next to each other.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-03 07:54:28 -05:00
Samanta Navarro
3010ec11ae login_prompt: Use _exit in signal handler
Calling exit is not signal safe.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-03 07:54:28 -05:00
Samanta Navarro
8fc8de382a login_prompt: Do not parse environment variables
Parsing optional environment variables after a login name is a feature
which is neither documented nor available in util-linux or busybox
login which are other wide spread login utilities used in Linux
distributions as reference.

Removing this feature resolves two issues:

- A memory leak exists if variables without an equal sign are used,
  because set_env creates copies on its own. This could lead to OOM
  situations in privileged part of login or may lead to heap spraying.
- Environment variables are not reset between login attempts. This
  could lead to additional environment variables set for a user who
  never intended to do so.

Proof of Concept on a system with shadow login without PAM and
util-linux agetty:

1. Provoke an invalid login, e.g. user `noone` and password `invalid`.
   This starts shadow login and subsequent inputs are passed through
   the function login_prompt.
2. Provoke an invalid login with environment variables, e.g.
   user `noone HISTFILE=/tmp/owo` and password `invalid`.
3. Log in correctly with user `root`.

Now you can see with `echo $HISTFILE` that `/tmp/owo` has been set for
the root user.

This requires a malicious failed login attempt and a successful login
within the configured login timeout (default 60 seconds).

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2023-05-03 07:54:28 -05:00