]> git.ipfire.org Git - thirdparty/shadow.git/log
thirdparty/shadow.git
2 years agoUpdate translation
maqi [Thu, 23 Feb 2023 10:21:13 +0000 (18:21 +0800)] 
Update translation

2 years agonewuidmap and newgidmap: support passing pid as fd
Serge Hallyn [Tue, 7 Feb 2023 04:49:42 +0000 (22:49 -0600)] 
newuidmap and newgidmap: support passing pid as fd

Closes #635

newuidmap and newgidmap currently take an integner pid as
the first argument, determining the process id on which to
act.  Accept also "fd:N", where N must be an open file
descriptor to the /proc/pid directory for the process to
act upon.  This way, if you

exec 10</proc/99
newuidmap fd:10 100000 0 65536

and pid 99 dies and a new process happens to take pid 99 before
newuidmap happens to do its work, then since newuidmap will use
openat() using fd 10, it won't change the mapping for the new
process.

Example:

// terminal 1:
serge@jerom ~/src/nsexec$ ./nsexec -W -s 0 -S 0 -U
about to unshare with 10000000
Press any key to exec (I am 129176)

// terminal 2:
serge@jerom ~/src/shadow$ exec 10</proc/129176
serge@jerom ~/src/shadow$ sudo chown root src/newuidmap src/newgidmap
serge@jerom ~/src/shadow$ sudo chmod u+s src/newuidmap
serge@jerom ~/src/shadow$ sudo chmod u+s src/newgidmap
serge@jerom ~/src/shadow$ ./src/newuidmap fd:10 0 100000 10
serge@jerom ~/src/shadow$ ./src/newgidmap fd:10 0 100000 10

// Terminal 1:
uid=0(root) gid=0(root) groups=0(root)

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agoFix use-after-free of pointer after realloc(3)
Alejandro Colomar [Sat, 4 Feb 2023 23:01:13 +0000 (00:01 +0100)] 
Fix use-after-free of pointer after realloc(3)

We can't use a pointer that was input to realloc(3), nor any pointers
that point to reallocated memory, without making sure that the memory
wasn't moved.  If we do, the Behavior is Undefined.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse safer allocation macros
Alejandro Colomar [Sat, 4 Feb 2023 21:41:18 +0000 (22:41 +0100)] 
Use safer allocation macros

Use of these macros, apart from the benefits mentioned in the commit
that adds the macros, has some other good side effects:

-  Consistency in getting the size of the object from sizeof(type),
   instead of a mix of sizeof(type) sometimes and sizeof(*p) other
   times.

-  More readable code: no casts, and no sizeof(), so also shorter lines
   that we don't need to cut.

-  Consistency in using array allocation calls for allocations of arrays
   of objects, even when the object size is 1.

Cc: Valentin V. Bartenev <vbartenev@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agolibmisc: Add safer allocation macros
Alejandro Colomar [Wed, 1 Feb 2023 15:30:52 +0000 (16:30 +0100)] 
libmisc: Add safer allocation macros

This macros have several benefits over the standard functions:

-  The type of the allocated object (not the pointer) is specified as an
   argument, which improves readability:
   -  It is directly obvious what is the type of the object just by
      reading the macro call.
   -  It allows grepping for all allocations of a given type.

   This is admittedly similar to using sizeof() to get the size of the
   object, but we'll see why this is better.

-  In the case of reallocation macros, an extra check is performed to
   make sure that the previous pointer was compatible with the allocated
   type, which can avoid some mistakes.

-  The cast is performed automatically, with a pointer type derived from
   the type of the object.  This is the best point of this macro, since
   it does an automatic cast, where there's no chance of typos.

   Usually, programmers have to decide whether to cast or not the result
   of malloc(3).  Casts usually hide warnings, so are to be avoided.
   However, these functions already return a void *, so a cast doesn't
   really add much danger.  Moreover, a cast can even add warnings in
   this exceptional case, if the type of the cast is different than the
   type of the assigned pointer.  Performing a manual cast is still not
   perfect, since there are chances that a mistake will be done, and
   even ignoring accidents, they clutter code, hurting readability.
   And now we have a cast that is synced with sizeof.

-  Whenever the type of the object changes, since we perform an explicit
   cast to the old type, there will be a warning due to type mismatch in
   the assignment, so we'll be able to see all lines that are affected
   by such a change.  This is especially important, since changing the
   type of a variable and missing to update an allocation call far away
   from the declaration is easy, and the consequences can be quite bad.

Cc: Valentin V. Bartenev <vbartenev@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse xreallocarray() instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 22:43:26 +0000 (23:43 +0100)] 
Use xreallocarray() instead of its pattern

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse reallocarrayf() instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 21:52:13 +0000 (22:52 +0100)] 
Use reallocarrayf() instead of its pattern

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse *array() allocation functions where appropriate
Alejandro Colomar [Sat, 4 Feb 2023 20:47:01 +0000 (21:47 +0100)] 
Use *array() allocation functions where appropriate

This prevents overflow from multiplication.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse xcalloc(3) instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 20:43:43 +0000 (21:43 +0100)] 
Use xcalloc(3) instead of its pattern

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agolibmisc: Add safer allocation functions
Alejandro Colomar [Sat, 4 Feb 2023 20:13:59 +0000 (21:13 +0100)] 
libmisc: Add safer allocation functions

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agolibmisc: Move xmalloc.c to alloc.c
Alejandro Colomar [Sun, 19 Feb 2023 19:40:16 +0000 (20:40 +0100)] 
libmisc: Move xmalloc.c to alloc.c

We'll expand the contents in a following commit, so let's move the file
to a more generic name, have a dedicated header, and update includes.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Use the new header for xstrdup()

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse calloc(3) instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 20:43:43 +0000 (21:43 +0100)] 
Use calloc(3) instead of its pattern

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse reallocarray(3) instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 22:20:38 +0000 (23:20 +0100)] 
Use reallocarray(3) instead of its pattern

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse reallocf(3) instead of its pattern
Alejandro Colomar [Sat, 4 Feb 2023 20:25:04 +0000 (21:25 +0100)] 
Use reallocf(3) instead of its pattern

In addition, don't set local variables just before return.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agomalloc(3) already sets errno to ENOMEM
Alejandro Colomar [Sat, 4 Feb 2023 22:37:55 +0000 (23:37 +0100)] 
malloc(3) already sets errno to ENOMEM

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRely on realloc(NULL, ...) being equivalent to malloc(...)
Alejandro Colomar [Sat, 4 Feb 2023 20:21:36 +0000 (21:21 +0100)] 
Rely on realloc(NULL, ...) being equivalent to malloc(...)

This is guaranteed by ISO C.  Now that we require ISO C (and even POSIX)
to compile, we can simplify this code.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agolibmisc: agetpass(): Fix bug detecting truncation
Alejandro Colomar [Sun, 19 Feb 2023 18:26:56 +0000 (19:26 +0100)] 
libmisc: agetpass(): Fix bug detecting truncation

On 2/19/23 18:09, David Mudrich wrote:
> I am working on a RAM based Linux OS from source, and try to use
> latest versions of all software.  I found shadow needs libbsd's
> readpassphrase(3) as superior alternative to getpass(3).  While
> considering if I a) include libbsd, or include libbsd's code of
> readpassphrase(3) into shadow, found, that libbsd's readpassphrase(3)
> never returns \n or \r
> <https://cgit.freedesktop.org/libbsd/tree/src/readpassphrase.c>
> line 122, while agetpass() uses a check for \n in agetpass.c line 108.
> I assume it always fails.

Indeed, it always failed.  I made a mistake when writing agetpass(),
assuming that readpassphrase(3) would keep newlines.

>
> I propose a check of len == PASS_MAX - 1, with false positive error for
> exactly PASS_MAX - 1 long passwords.

Instead, I added an extra byte to the allocation to allow a maximum
password length of PASS_MAX (which is the maximum for getpass(3), which
we're replacing.

While doing that, I notice that my previous implementation also had
another bug (minor): The maximum password length was PASS_MAX - 1
instead of PASS_MAX.  That's also fixed in this commit.

Reported-by: David Mudrich <dmudrich@gmx.de>
Fixes: 155c9421b935 ("libmisc: agetpass(), erase_pass(): Add functions for getting passwords safely")
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agofind_new_[gu]id(): Skip over IDs that are reserved for legacy reasons
Martin Kletzander [Wed, 1 Feb 2023 14:36:41 +0000 (15:36 +0100)] 
find_new_[gu]id(): Skip over IDs that are reserved for legacy reasons

Some programs don't support `(uint16_t) -1` or `(uint32_t) -1` as user
or group IDs.  This is because `-1` is used as an error code or as an
unspecified ID, e.g. in `chown(2)` parameters, and in the past, `gid_t`
and `uid_t` have changed width.  For legacy reasons, those values have
been kept reserved in programs today (for example systemd does this; see
the documentation in the link below).

This should not be confused with catching overflow in the ID values,
since that is already caught by our ERANGE checks.  This is about not
using reserved values that have been reserved for legacy reasons.

Link: <https://systemd.io/UIDS-GIDS/>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2 years agoFix comments
Samanta Navarro [Thu, 16 Feb 2023 11:57:03 +0000 (11:57 +0000)] 
Fix comments

These comments should indicate which functions they really wrap.
An alternative would be to remove the line completely to avoid
future copy&paste mistakes.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoFix grammar
Samanta Navarro [Thu, 16 Feb 2023 11:54:14 +0000 (11:54 +0000)] 
Fix grammar

Use proper grammar (third-person singular).

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoFix typo
Samanta Navarro [Thu, 16 Feb 2023 11:53:52 +0000 (11:53 +0000)] 
Fix typo

It should be "if" not "is".

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoFix typos
Samanta Navarro [Thu, 16 Feb 2023 11:52:23 +0000 (11:52 +0000)] 
Fix typos

It is a user, not an user.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoUse stpecpy() where appropriate
Alejandro Colomar [Fri, 10 Feb 2023 21:52:25 +0000 (22:52 +0100)] 
Use stpecpy() where appropriate

This function simplifies the calculation of the bounds of the buffer for
catenating strings.  It would also reduce error checking, but we don't
care about truncation in this specific code. :)

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd stpecpy()
Alejandro Colomar [Fri, 10 Feb 2023 21:34:37 +0000 (22:34 +0100)] 
Add stpecpy()

strncat(3), strlcpy(3), and many other functions are often misused for
catenating strings, when they should never be used for that.  strlcat(3)
is good.  However, there's no equivalent to strlcat(3) similar to
snprintf(3).  Let's add stpecpy(), which is similar to strlcat(3), but
it is also the only function compatible with stpeprintf(), which makes
it more useful than strlcat(3).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd mempcpy(3)
Alejandro Colomar [Fri, 10 Feb 2023 21:16:21 +0000 (22:16 +0100)] 
Add mempcpy(3)

We'll use it for implementing stpecpy(), and may be interesting to have
it around.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove unnecessary NUL terminators
Alejandro Colomar [Sun, 29 Jan 2023 23:56:57 +0000 (00:56 +0100)] 
Remove unnecessary NUL terminators

All the string-copying functions called above do terminate the strings
they create with a NUL byte.  Writing it again at the end of the buffer
is unnecessary paranoid code.  Let's remove it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse stpeprintf() where appropriate
Alejandro Colomar [Sun, 29 Jan 2023 23:54:07 +0000 (00:54 +0100)] 
Use stpeprintf() where appropriate

This function allows reducing error checking (since errors are
propagated across chained calls), and also simplifies the calculation of
the start and end of the buffer where the string should be written.

Moreover, the new code is more optimized, since many calls to strlen(3)
have been removed.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd stpeprintf()
Alejandro Colomar [Sun, 29 Jan 2023 23:19:56 +0000 (00:19 +0100)] 
Add stpeprintf()

[v]stpeprintf() are similar to [v]snprintf(3), but they allow chaining.
[v]snprintf(3) are very dangerous for catenating strings, since the
obvious ways to do it invoke Undefined Behavior, and the ways that avoid
UB are very error-prone.

Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoagetpass.c: Use SPDX tags
Alejandro Colomar [Sun, 29 Jan 2023 20:44:17 +0000 (21:44 +0100)] 
agetpass.c: Use SPDX tags

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoFix VPATH build
Martin Kletzander [Tue, 7 Feb 2023 08:34:59 +0000 (09:34 +0100)] 
Fix VPATH build

When trying to build shadow in a different directory I stumbled upon few
issues, this commit aims to fix all of them:

- The `subid.h` file is generated and hence in the build directory and
not in the source directory, so use `$(builddir)` instead of
`$(srcdir)`.

- Using `$<` instead of filenames utilises autotools to locate the files
  in either the source or build directory automatically.

- `xsltproc` needs to access the files in login.defs.d in either the
  source directory or the symlink in a language subdirectory, but it
does not interpret the `--path` as prefix of the entity path, but
rather a path under which to locate the basename of the entity
from the XML file.  So specify the whole path to login.defs.d.

- The above point could be used to make the symlinks of login.defs.d
  and entity path specifications in the XMLs obsolete, but I trying
not to propose possibly disrupting patches, so for the sake of
simplicity just specify `$(srcdir)` when creating the symlink.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
2 years agottytype(): Fix race
Alejandro Colomar [Fri, 3 Feb 2023 19:32:12 +0000 (20:32 +0100)] 
ttytype(): Fix race

The intention of the code is just to not report an error message when
'typefile' doesn't exist.  If we call access(2) and then fopen(2),
there's a race.  It's not a huge problem, and the worst thing that can
happen is reporting an error when the file has been removed after
access(2).  It's not a problem, but we can fix the race and at the same
time clarify the intention of not warning about ENOENT and also remove
one syscall.  Seems like a win-win.

Suggested-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove superfluous casts
Alejandro Colomar [Wed, 1 Feb 2023 12:50:48 +0000 (13:50 +0100)] 
Remove superfluous casts

-  Every non-const pointer converts automatically to void *.
-  Every pointer converts automatically to void *.
-  void * converts to any other pointer.
-  const void * converts to any other const pointer.
-  Integer variables convert to each other.

I changed the declaration of a few variables in order to allow removing
a cast.

However, I didn't attempt to edit casts inside comparisons, since they
are very delicate.  I also kept casts in variadic functions, since they
are necessary, and in allocation functions, because I have other plans
for them.

I also changed a few casts to int that are better as ptrdiff_t.

This change has triggered some warnings about const correctness issues,
which have also been fixed in this patch (see for example src/login.c).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agorun on github runner
Serge Hallyn [Thu, 9 Feb 2023 14:38:02 +0000 (08:38 -0600)] 
run on github runner

2 years agotests: print default timeout message to stderr
Serge Hallyn [Wed, 8 Feb 2023 03:12:59 +0000 (21:12 -0600)] 
tests: print default timeout message to stderr

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agouse self-hosted runner for testsuite
Serge Hallyn [Mon, 30 Jan 2023 02:13:52 +0000 (20:13 -0600)] 
use self-hosted runner for testsuite

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agoUse the noreturn attribute, rather than comments
Alejandro Colomar [Tue, 7 Feb 2023 18:50:36 +0000 (19:50 +0100)] 
Use the noreturn attribute, rather than comments

This will allow the compiler to understand these functions better.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agolib/defines.h: Add NORETURN attribute macro
Alejandro Colomar [Tue, 7 Feb 2023 18:39:36 +0000 (19:39 +0100)] 
lib/defines.h: Add NORETURN attribute macro

We could use the standard (C11) _Noreturn qualifier, but it will be
deprecated in C23, and replaced by C++'s [[noreturn]], which is
compatible with the GCC attribute, so let's directly use the attribute,
and in the future we'll be able to switch to [[]].

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAssume getutent(3) exists (remove dead code)
Alejandro Colomar [Tue, 7 Feb 2023 17:37:23 +0000 (18:37 +0100)] 
Assume getutent(3) exists (remove dead code)

Recently, we removed support for 'struct utmpx'.  We did it because utmp
and utmpx are identical, and while POSIX specifies utmpx (and not utmp),
GNU/Linux documentation seems to favor utmp.  Also, this project
defaulted to utmp, so changing to utmpx would be more dangerous than
keeping old defaults, even if it's supposed to be the same.

Now, I just found more code that didn't make much sense: lib/utent.c
provides definitions for getutent(3) and friends in case the system
doesn't provide them, but we don't provide prototypes for those
definitions, so code using the functions would have never compiled.

Let's just remove these definitions as dead code.

Fixes: 3be7b9d75a6b ("Remove traces of utmpx")
Fixes: 170b76cdd1a9 ("Disable utmpx permanently")
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoHandle reallocf(3) errors
Alejandro Colomar [Thu, 2 Feb 2023 11:31:54 +0000 (12:31 +0100)] 
Handle reallocf(3) errors

Reported-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoFix memory leaks by replacing realloc(3) with reallocf(3)
Alejandro Colomar [Wed, 1 Feb 2023 23:59:55 +0000 (00:59 +0100)] 
Fix memory leaks by replacing realloc(3) with reallocf(3)

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove unused function: gr_append_member()
Alejandro Colomar [Fri, 3 Feb 2023 14:27:40 +0000 (15:27 +0100)] 
Remove unused function: gr_append_member()

Reported-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoImprove TTYGROUP description in login.defs manpage
Serge Hallyn [Thu, 2 Feb 2023 18:27:23 +0000 (12:27 -0600)] 
Improve TTYGROUP description in login.defs manpage

Closes #457

The existing prose was confusing, or simply wrong.  Make it clear
that only the group ownership of the tty is affected, and how.
Also move the paragraph about defaults after the discussion of
acceptable TTYGROUPs, as this seems more natural.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agoRemove superfluous casts to 'void*'
Alejandro Colomar [Wed, 1 Feb 2023 12:50:48 +0000 (13:50 +0100)] 
Remove superfluous casts to 'void*'

Every non-const pointer converts automatically to it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoCall NULL by its name
Alejandro Colomar [Wed, 1 Feb 2023 01:50:14 +0000 (02:50 +0100)] 
Call NULL by its name

In variadic functions we still do the cast.  In POSIX, it's not
necessary, since NULL is required to be of type 'void *', and 'void *'
is guaranteed to have the same alignment and representation as 'char *'.
However, since ISO C still doesn't mandate that, and moreover they're
doing dubious stuff by adding nullptr, let's be on the cautious side.
Also, C++ requires that NULL is _not_ 'void *', but either plain 0 or
some magic stuff.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse freezero(3) where suitable
Alejandro Colomar [Wed, 1 Feb 2023 19:29:29 +0000 (20:29 +0100)] 
Use freezero(3) where suitable

It originated in OpenBSD, and is available in libbsd.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoPrevent out of boundary access
Samanta Navarro [Mon, 30 Jan 2023 11:54:49 +0000 (11:54 +0000)] 
Prevent out of boundary access

If lines start with '\0' then it is possible to trigger out of
boundary accesses.

Check if indices are valid before accessing them.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoExplicitly override only newlines
Samanta Navarro [Mon, 30 Jan 2023 11:53:47 +0000 (11:53 +0000)] 
Explicitly override only newlines

Override only newlines with '\0' to avoid undesired truncation of
actual line content.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoCorrectly handle illegal system file in tz
Samanta Navarro [Fri, 27 Jan 2023 11:57:51 +0000 (11:57 +0000)] 
Correctly handle illegal system file in tz

If the file referenced by ENV_TZ has a zero length string, then an out
of boundary write occurs. Also the result can be wrong because it is
assumed that the file will always end with a newline.

Only override a newline character with '\0' to avoid these cases.

This cannot be considered to be security relevant because login.defs
and its contained references to system files should be trusted to begin
with.

Proof of Concept:

1. Compile shadow's su with address sanitizer and --without-libpam

2. Setup your /etc/login.defs to contain ENV_TZ=/etc/tzname

3. Prepare /etc/tzname to contain a '\0' byte at the beginning

`python -c "print('\x00')" > /etc/tzname`

4. Use su

`su -l`

You can see the following output:

`tz.c:45:8: runtime error: index 18446744073709551615 out of bounds for type 'char [8192]'`

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoleading_zerosul(): Fix bug
Alejandro Colomar [Tue, 31 Jan 2023 15:47:40 +0000 (16:47 +0100)] 
leading_zerosul(): Fix bug

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUnoptimize the higher part of the domain of csrand_uniform()
Alejandro Colomar [Mon, 30 Jan 2023 12:13:36 +0000 (13:13 +0100)] 
Unoptimize the higher part of the domain of csrand_uniform()

__int128, which is needed for optimizing that part of the range, is not
always available.  We need the unoptimized version for portability
reasons.

Closes: <https://github.com/shadow-maint/shadow/issues/634>
Fixes: 1a0e13f94edc ("Optimize csrand_uniform()")
Reported-by: Adam Sampson <ats@offog.org>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd bit manipulation functions
Alejandro Colomar [Mon, 30 Jan 2023 11:43:34 +0000 (12:43 +0100)] 
Add bit manipulation functions

We do need the unoptimized version of csrand_uniform() for high values
of `n`, since the optimized version depends on having __int128, and it's
not available on several platforms, including ARMv7, IA32, and MK68k.

This reverts commit 848f53c1d3c1362c86d3baab6906e1e4419d2634; however,
I applied some tweaks to the reverted commit.

Reported-by: Adam Sampson <ats@offog.org>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRevert "Add bit manipulation functions"
Alejandro Colomar [Thu, 19 Jan 2023 03:23:44 +0000 (04:23 +0100)] 
Revert "Add bit manipulation functions"

Now that we optimized csrand_uniform(), we don't need these functions.

This reverts commit 7c8fe291b1260e127c10562bfd7616961013730f.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoOptimize csrand_uniform()
Alejandro Colomar [Wed, 18 Jan 2023 12:26:47 +0000 (13:26 +0100)] 
Optimize csrand_uniform()

Use a different algorithm to minimize rejection.  This is essentially
the same algorithm implemented in the Linux kernel for
__get_random_u32_below(), but written in a more readable way, and
avoiding microopimizations that make it less readable.

Which (the Linux kernel implementation) is itself based on Daniel
Lemire's algorithm from "Fast Random Integer Generation in an Interval",
linked below.  However, I couldn't really understand that paper very
much, so I had to reconstruct the proofs from scratch, just from what I
could understand from the Linux kernel implementation source code.

I constructed some graphical explanation of how it works, and why it
is optimal, because I needed to visualize it to understand it.  It is
published in the GitHub pull request linked below.

Here goes a wordy explanation of why this algorithm based on
multiplication is better optimized than my original implementation based
on masking.

masking:

It discards the extra bits of entropy that are not necessary for
this operation.  This works as if dividing the entire space of
possible csrand() values into smaller spaces of a size that is
a smaller power of 2.  Each of those smaller spaces has a
rejection band, so we get as many rejection bands as spaces
there are.  For smaller values of 'n', the size of each
rejection band is smaller, but having more rejection bands
compensates for this, and results in the same inefficiency as
for large values of 'n'.

multiplication:

It divides the entire space of possible random numbers in
chunks of size exactly 'n', so that there is only one rejection
band that is the remainder of `2^64 % n`.  The worst case is
still similar to the masking algorithm, a rejection band that is
almost half the entire space (n = 2^63 + 1), but for lower
values of 'n', by only having one small rejection band, it is
much faster than the masking algorithm.

This algorithm, however, has one caveat: the implementation
is harder to read, since it relies on several bitwise tricky
operations to perform operations like `2^64 % n`, `mult % 2^64`,
and `mult / 2^64`.  And those operations are different depending
on the number of bits of the maximum possible random number
generated by the function.  This means that while this algorithm
could also be applied to get uniform random numbers in the range
[0, n-1] quickly from a function like rand(3), which only
produces 31 bits of (non-CS) random numbers, it would need to be
implemented differently.  However, that's not a concern for us,
it's just a note so that nobody picks this code and expects it
to just work with rand(3) (which BTW I tried for testing it, and
got a bit confused until I realized this).

Finally, here's some light testing of this implementation, just to know
that I didn't goof it.  I pasted this function into a standalone
program, and run it many times to find if it has any bias (I tested also
to see how many iterations it performs, and it's also almost always 1,
but that test is big enough to not paste it here).

int main(int argc, char *argv[])
{
printf("%lu\n", csrand_uniform(atoi(argv[1])));
}

$ seq 1 1000 | while read _; do ./a.out 3; done | grep 1 | wc -l
341
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 1 | wc -l
339
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 1 | wc -l
338
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 2 | wc -l
336
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 2 | wc -l
328
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 2 | wc -l
335
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 0 | wc -l
332
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 0 | wc -l
331
$ seq 1 1000 | while read _; do ./a.out 3; done | grep 0 | wc -l
327

This isn't a complete test for a cryptographically-secure random number
generator, of course, but I leave that for interested parties.

Link: <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e9a688bcb19348862afe30d7c85bc37c4c293471>
Link: <https://github.com/shadow-maint/shadow/pull/624#discussion_r1059574358>
Link: <https://arxiv.org/abs/1805.10941>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Sam James <sam@gentoo.org>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
[Daniel Lemire: Added link to research paper in source code]
Cc: Daniel Lemire <daniel@lemire.me>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse WIDTHOF() instead of its expansion
Alejandro Colomar [Wed, 18 Jan 2023 11:40:01 +0000 (12:40 +0100)] 
Use WIDTHOF() instead of its expansion

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd WIDTHOF() to get the width in bits
Alejandro Colomar [Wed, 18 Jan 2023 11:38:18 +0000 (12:38 +0100)] 
Add WIDTHOF() to get the width in bits

It is common to use the expression 'sizeof(x) * CHAR_BIT' to mean the
width in bits of a type or object.  Now that there are _WIDTH macros for
some types, indicating the number of bits that they use, it makes sense
to wrap this calculation in a macro of a similar name.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRewrite csrand_interval() as a wrapper around csrand_uniform()
Alejandro Colomar [Fri, 30 Dec 2022 18:46:09 +0000 (19:46 +0100)] 
Rewrite csrand_interval() as a wrapper around csrand_uniform()

The old code didn't produce very good random numbers.  It had a bias.
And that was from performing some unnecessary floating-point
calculations that overcomplicate the problem.

Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Sam James <sam@gentoo.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd csrand_uniform()
Alejandro Colomar [Fri, 30 Dec 2022 18:46:09 +0000 (19:46 +0100)] 
Add csrand_uniform()

This API is similar to arc4random_uniform(3).  However, for an input of
0, this function is equivalent to csrand(), while arc4random_uniform(0)
returns 0.

This function will be used to reimplement csrand_interval() as a wrapper
around this one.

The current implementation of csrand_interval() doesn't produce very good
random numbers.  It has a bias.  And that comes from performing some
unnecessary floating-point calculations that overcomplicate the problem.

Looping until the random number hits within bounds is unbiased, and
truncating unwanted bits makes the overhead of the loop very small.

We could reduce loop overhead even more, by keeping unused bits of the
random number, if the width of the mask is not greater than
ULONG_WIDTH/2, however, that complicates the code considerably, and I
prefer to be a bit slower but have simple code.

BTW, Björn really deserves the copyright for csrand() (previously known
as read_random_bytes()), since he rewrote it almost from scratch last
year, and I kept most of its contents.  Since he didn't put himself in
the copyright back then, and BSD-3-Clause doesn't allow me to attribute
derived works, I won't add his name, but if he asks, he should be put in
the copyright too.

Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Sam James <sam@gentoo.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd bit manipulation functions
Alejandro Colomar [Fri, 30 Dec 2022 22:00:14 +0000 (23:00 +0100)] 
Add bit manipulation functions

These functions implement bit manipulation APIs, which will be added to
C23, so that in the far future, we will be able to replace our functions
by the standard ones, just by adding the stdc_ prefix, and including
<stdbit.h>.

However, we need to avoid UB for an input of 0, so slightly deviate from
C23, and use a different name (with _wrap) for distunguishing our API
from the standard one.

Cc: Joseph Myers <joseph@codesourcery.com>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoMove csrand() to a new file csrand.c
Alejandro Colomar [Fri, 30 Dec 2022 18:46:09 +0000 (19:46 +0100)] 
Move csrand() to a new file csrand.c

A set of APIs similar to arc4random(3) is complex enough to deserve its
own file.

Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Cc: Yann Droneaud <ydroneaud@opteya.com>
Cc: Joseph Myers <joseph@codesourcery.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse naming consistent with other common functions
Alejandro Colomar [Fri, 30 Dec 2022 18:42:17 +0000 (19:42 +0100)] 
Use naming consistent with other common functions

arc4random(3) returns a number.
arc4random_buf(3) fills a buffer.
arc4random_uniform(3) returns a number less than a bound.

and I'd add a hypothetical one which we use:

*_interval() should return a number within the interval [min, max].

In reality, the function being called csrand() in this patch is not
really cryptographically secure, since it had a bias, but a subsequent
patch will fix that.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoFix types of the csrand_interval() API
Alejandro Colomar [Fri, 30 Dec 2022 17:50:21 +0000 (18:50 +0100)] 
Fix types of the csrand_interval() API

We were always casting the result to u_long.  Better just use that type
in the function.  Since we're returning u_long, it makes sense to also
specify the input as u_long.  In fact, that'll help for doing bitwise
operations inside this function.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse a more precise name for a CSPRNG API with an interval
Alejandro Colomar [Fri, 30 Dec 2022 17:46:22 +0000 (18:46 +0100)] 
Use a more precise name for a CSPRNG API with an interval

I have plans to split this function in smaller functions that implement
bits of this functionallity, to simplify the implementation.  So, let's
use names that distinguish them.

This one produces a number within an interval, so make that clear.  Also
make clear that the function produces cryptographically-secure numbers.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoSupporting vendor given -shells- configuration file
Stefan Schubert [Mon, 28 Nov 2022 16:18:09 +0000 (17:18 +0100)] 
Supporting vendor given -shells- configuration file

2 years agolibmisc: fix grammar
Samanta Navarro [Fri, 30 Dec 2022 11:51:42 +0000 (11:51 +0000)] 
libmisc: fix grammar

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoFix typos
Samanta Navarro [Fri, 30 Dec 2022 11:51:29 +0000 (11:51 +0000)] 
Fix typos

Typos found with codespell.

Signed-off-by: Samanta Navarro <ferivoz@riseup.net>
2 years agoDeclare constant data structure const
Christian Göttsche [Tue, 24 Jan 2023 15:50:49 +0000 (16:50 +0100)] 
Declare constant data structure const

    ./lib/pam_defs.h:18:24: warning: ‘conv’ defined but not used [-Wunused-variable]
       18 | static struct pam_conv conv = {
          |                        ^~~~

2 years agoProvide strlcpy declaration
Christian Göttsche [Tue, 24 Jan 2023 15:31:23 +0000 (16:31 +0100)] 
Provide strlcpy declaration

strlcpy(3) might not be visible since it is declared in <bsd/string.h>.
This can lead to warnings, like:

    fields.c: In function 'change_field':
    fields.c:103:17: warning: implicit declaration of function 'strlcpy'; did you mean 'strncpy'? [-Wimplicit-function-declaration]
      103 |                 strlcpy (buf, cp, maxsize);
          |                 ^~~~~~~
          |                 strncpy

    ../lib/fields.c:103:17: warning: type of 'strlcpy' does not match original declaration [-Wlto-type-mismatch]
      103 |                 strlcpy (buf, cp, maxsize);
          |                 ^
    /usr/include/bsd/string.h:44:8: note: return value type mismatch
       44 | size_t strlcpy(char *dst, const char *src, size_t siz);
          |        ^
    /usr/include/bsd/string.h:44:8: note: type 'size_t' should match type 'int'
    /usr/include/bsd/string.h:44:8: note: 'strlcpy' was previously declared here
    /usr/include/bsd/string.h:44:8: note: code may be misoptimized unless '-fno-strict-aliasing' is used

2 years agoAvoid comparisons of different signs
Christian Göttsche [Tue, 24 Jan 2023 15:05:20 +0000 (16:05 +0100)] 
Avoid comparisons of different signs

Comparisons if different signedness can result in unexpected results.
Add casts to ensure operants are of the same type.

    gettime.c: In function 'gettime':
    gettime.c:58:26: warning: comparison of integer expressions of different signedness: 'long long unsigned int' and 'time_t' {aka 'long int'} [-Wsign-compare]
       58 |         } else if (epoch > fallback) {
          |                          ^

Cast to time_t, since epoch is less than ULONG_MAX at this point.

    idmapping.c: In function 'write_mapping':
    idmapping.c:202:48: warning: comparison of integer expressions of different signedness: 'int' and 'long unsigned int' [-Wsign-compare]
      202 |                 if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
          |                                                ^~

    newgidmap.c: In function ‘main’:
    newgidmap.c:178:40: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
      178 |         if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
          |                                        ^~
    newuidmap.c: In function ‘main’:
    newuidmap.c:107:40: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
      107 |         if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
          |                                        ^~

2 years agoDrop redundant declaration
Christian Göttsche [Tue, 24 Jan 2023 14:59:47 +0000 (15:59 +0100)] 
Drop redundant declaration

environ is exported in <unistd.h>.

    env.c:29:15: warning: redundant redeclaration of 'environ' [-Wredundant-decls]
       29 | extern char **environ;
          |               ^~~~~~~
    login.c:92:15: warning: redundant redeclaration of ‘environ’ [-Wredundant-decls]
       92 | extern char **environ;
          |               ^~~~~~~
    sulogin.c:40:15: warning: redundant redeclaration of ‘environ’ [-Wredundant-decls]
       40 | extern char **environ;
          |               ^~~~~~~
    newgrp.c:32:15: warning: redundant redeclaration of ‘environ’ [-Wredundant-decls]
       32 | extern char **environ;
          |               ^~~~~~~

2 years agocopydir: fix impl usage
Christian Göttsche [Tue, 24 Jan 2023 14:53:42 +0000 (15:53 +0100)] 
copydir: fix impl usage

    copydir.c: In function 'copy_dir':
    copydir.c:517:32: warning: passing argument 1 of 'copy_tree' from incompatible pointer type [-Wincompatible-pointer-types]
      517 |             return (copy_tree (src, dst, false, reset_selinux,
          |                                ^~~
          |                                |
          |                                const struct path_info *
    In file included from copydir.c:20:
    ../lib/prototypes.h:108:35: note: expected 'const char *' but argument is of type 'const struct path_info *'
      108 | extern int copy_tree (const char *src_root, const char *dst_root,
          |                       ~~~~~~~~~~~~^~~~~~~~
    copydir.c:517:37: warning: passing argument 2 of 'copy_tree' from incompatible pointer type [-Wincompatible-pointer-types]
      517 |             return (copy_tree (src, dst, false, reset_selinux,
          |                                     ^~~
          |                                     |
          |                                     const struct path_info *
    ../lib/prototypes.h:108:57: note: expected 'const char *' but argument is of type 'const struct path_info *'
      108 | extern int copy_tree (const char *src_root, const char *dst_root,
          |                                             ~~~~~~~~~~~~^~~~~~~~

Fixes: 74c17c71 ("Add support for skeleton files from /usr/etc/skel")
2 years agoModernize manual memzero implementation
Christian Göttsche [Tue, 24 Jan 2023 14:44:35 +0000 (15:44 +0100)] 
Modernize manual memzero implementation

Instead of using volatile pointers to prevent the compiler from
optimizing the call away, use a memory barrier.
This requires support for embedded assembly, which should be fine after
the recent requirement bumps.

2 years agoReplace flawed memset_s usage
Christian Göttsche [Tue, 24 Jan 2023 14:39:41 +0000 (15:39 +0100)] 
Replace flawed memset_s usage

memset_s() has a different signature than memset(3) or explicit_bzero(),
thus the current code would not compile.  Also memset_s()
implementations are quite rare.
Use the C23 standardized version memset_explicit(3).

Fixes: 7a799ebb ("Ensure memory cleaning")
2 years agoUse getnameinfo(3) instead of our own equivalent
Alejandro Colomar [Thu, 19 Jan 2023 18:33:53 +0000 (19:33 +0100)] 
Use getnameinfo(3) instead of our own equivalent

I didn't know getnameinfo(3) existed, so I implemented it, or something
similar to it called inet_sockaddr2str().  Let's use the standard API.

Link: <https://inbox.sourceware.org/libc-alpha/0f25d60f-f183-b518-b6c1-6d46aa63ee57@gmail.com/T/>
Link: <https://stackoverflow.com/a/42190913/6872717>
Link: <https://github.com/shadow-maint/shadow/pull/617>
Link: <https://software.codidact.com/posts/287748>
Cc: Zack Weinberg <zack@owlfolio.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoPrefer getrandom(3)/getentropy(3) over arc4random(3bsd)
Alejandro Colomar [Fri, 30 Dec 2022 11:48:55 +0000 (12:48 +0100)] 
Prefer getrandom(3)/getentropy(3) over arc4random(3bsd)

arc4random(3) without kernel support is unsafe, as it can't know when to
drop the buffer.  Since we depend on libbsd since recently, we have
arc4random(3) functions always available, and thus, this code would have
always called arc4random_buf(3bsd), which is unsafe.  Put it after some
better alternatives, at least until in a decade or so all systems have a
recent enough glibc.

glibc implements arc4random(3) safely, since it's just a wrapper around
getrandom(2).

Link: <https://inbox.sourceware.org/libc-alpha/20220722122137.3270666-1-adhemerval.zanella@linaro.org/>
Link: <https://inbox.sourceware.org/libc-alpha/5c29df04-6283-9eee-6648-215b52cfa26b@cs.ucla.edu/T/>
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Cc: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: Guillem Jover <guillem@hadrons.org>
Cc: Björn Esser <besser82@fedoraproject.org>
Reviewed-by: "Jason A. Donenfeld" <Jason@zx2c4.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoworkflow: update checkout acton v2 to v3
Serge Hallyn [Fri, 13 Jan 2023 00:39:18 +0000 (18:39 -0600)] 
workflow: update checkout acton v2 to v3

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agoshadow: Fix can not print full login timeout message
SoumyaWind [Tue, 27 Dec 2022 12:10:17 +0000 (17:40 +0530)] 
shadow: Fix can not print full login timeout message

Login timed out message prints only first few bytes when write is immediately followed by exit.
Calling exit from new handler provides enough time to display full message.

2 years agofix typo
lilinjie [Thu, 12 Jan 2023 05:42:13 +0000 (13:42 +0800)] 
fix typo

Signed-off-by: lilinjie <lilinjie@uniontech.com>
2 years agoWarn if failed to read existing /etc/nsswitch.conf
Christian Göttsche [Mon, 2 Jan 2023 15:11:58 +0000 (16:11 +0100)] 
Warn if failed to read existing /etc/nsswitch.conf

Commit 90424e7c ("Don't warn when failed to open /etc/nsswitch.conf")
removed the logging for failing to read /etc/nsswitch.conf to reduce the
noise in the case the file does not exists (e.g. musl based systems).

Reintroduce a warning if /etc/nsswitch.conf exists but we failed to read
it (e.g. permission denied).

Improves: 90424e7c ("Don't warn when failed to open /etc/nsswitch.conf")

2 years agoCall inet_sockaddr2str() instead of inet_ntop(3)
Alejandro Colomar [Thu, 22 Dec 2022 14:48:40 +0000 (15:48 +0100)] 
Call inet_sockaddr2str() instead of inet_ntop(3)

To simplify.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAdd inet_sockaddr2str() to wrap inet_ntop(3)
Alejandro Colomar [Thu, 22 Dec 2022 14:26:01 +0000 (15:26 +0100)] 
Add inet_sockaddr2str() to wrap inet_ntop(3)

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoReplace gethostbyname(3) by getaddrinfo(3)
Alejandro Colomar [Thu, 22 Dec 2022 13:03:05 +0000 (14:03 +0100)] 
Replace gethostbyname(3) by getaddrinfo(3)

gethostbyname(3) was removed in POSIX.1-2008.  It has been obsoleted,
and replaced by getaddrinfo(3), which is superior in several ways:

-  gethostbyname(3) is not reentrant.  There's a GNU extension,
   gethostbyname_r(3) which is reentrant, but it's not likely to be
   standardized for the following reason.  And we don't care too much
   about this point either.

-  gethostbyname(3) only supports IPv4, but getaddrinfo(3) supports both
   IPv4 and IPv6 (and may support other address families in the future).

We don't care about reentrancy, so for keeping the code simple (i.e.,
not touch call site to add code to free(3) an allocated buffer), I added
a static buffer for inet_ntop(3).  We could address that in the future,
but I don't think it's worth it.

BTW, we also replace inet_ntoa(3) by inet_ntop(3), as a consequence of
using getaddrinfo(3).  inet_ntoa(3) is also marked as deprecated, but
that deprecation seems to have been documented only in the manual page,
and POSIX doesn't mark it as deprecated.  The deprecation notice goes
back to when the inet_ntop(3) manual page was added by Sam Varshavchik
to the Linux man-pages in version 1.30 (year 2000).

So, this, apart from updating the code to POSIX.1-2008, is also adding
support for IPv6 :)  Although, probably many other parts of the code are
written for IPv4 only, so I wouldn't yet claim support for it.

A few notes:

-  I didn't check the return value of inet_ntop(3), since it can't fail
   for the given input:

   -  EAFNOSUPPORT:  We only call it with AF_INET and AF_INET6.
   -  ENOSPC:  We calculate the size of the buffer to be wide enough:
               MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) so it always fits.

Cc: Dave Hagewood <admin@arrowweb.com>
Cc: Sam Varshavchik
Cc: Jakub Jelinek <jakub@redhat.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agochanging lock mechanism
ed neville [Tue, 6 Dec 2022 19:21:55 +0000 (19:21 +0000)] 
changing lock mechanism

Systems can suffer power interruptions whilst .lock files are in /etc,
preventing scripts and other automation tools from updating shadow's
files which persist across boots.

This commit replaces that mechanism with file locking to avoid problems
of power interruption/crashing.

Minor tweak to groupmems man page, requested by 'xx' on IRC.

Signed-off-by: ed neville <ed@s5h.net>
2 years agochfn: new_fields: fix wrong fields printed
Serge Hallyn [Thu, 22 Dec 2022 23:54:51 +0000 (17:54 -0600)] 
chfn: new_fields: fix wrong fields printed

When the caller may not change the room number, work phone, or
home number, then rather than prompting for the new one it will
print the existing one.  But due to a typo it printed the full name
in place of each of those.

Fix the fields being printed.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2 years agoAdd NITEMS(arr) to get the number of elements of an array
Alejandro Colomar [Thu, 22 Dec 2022 12:51:20 +0000 (13:51 +0100)] 
Add NITEMS(arr) to get the number of elements of an array

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse strlcpy(3) instead of its pattern
Alejandro Colomar [Fri, 16 Dec 2022 03:13:53 +0000 (04:13 +0100)] 
Use strlcpy(3) instead of its pattern

-  Since strncpy(3) is not designed to write strings, but rather
   (null-padded) character sequences (a.k.a. unterminated strings), we
   had to manually append a '\0'.  strlcpy(3) creates strings, so they
   are always terminated.  This removes dependencies between lines, and
   also removes chances of accidents.

-  Repurposing strncpy(3) to create strings requires calculating the
   location of the terminating null byte, which involves a '-1'
   calculation.  This is a source of off-by-one bugs.  The new code has
   no '-1' calculations, so there's almost-zero chance of these bugs.

-  strlcpy(3) doesn't padd with null bytes.  Padding is relevant when
   writing fixed-width buffers to binary files, when interfacing certain
   APIs (I believe utmpx requires null padding at lease in some
   systems), or when sending them to other processes or through the
   network.  This is not the case, so padding is effectively ignored.

-  strlcpy(3) requires that the input string is really a string;
   otherwise it crashes (SIGSEGV).  Let's check if the input strings are
   really strings:

   -  lib/fields.c:
      -  'cp' was assigned from 'newft', and 'newft' comes from fgets(3).

   -  lib/gshadow.c:
      -  strlen(string) is calculated a few lines above.

   -  libmisc/console.c:
      -  'cons' comes from getdef_str, which is a bit cryptic, but seems
         to generate strings, I guess.1

   -  libmisc/date_to_str.c:
      -  It receives a string literal.  :)

   -  libmisc/utmp.c:
      -  'tname' comes from ttyname(3), which returns a string.

   -  src/su.c:
      -  'tmp_name' has been passed to strcmp(3) a few lines above.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agostrtoday.c: remove unused defines.h inclusion
Iker Pedrosa [Thu, 22 Dec 2022 15:29:00 +0000 (16:29 +0100)] 
strtoday.c: remove unused defines.h inclusion

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 years agostrtoday.c: remove USE_GETDATE as it was always used
Iker Pedrosa [Thu, 22 Dec 2022 15:26:21 +0000 (16:26 +0100)] 
strtoday.c: remove USE_GETDATE as it was always used

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 years agostrtoday.c: remove POSIX 1995 conditional dependency
Iker Pedrosa [Thu, 22 Dec 2022 15:14:24 +0000 (16:14 +0100)] 
strtoday.c: remove POSIX 1995 conditional dependency

Since the project is supposed to be POSIX.1-2001 compliant it doesn't
make sense to have that added conditionally.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2 years agoAssume struct tm is defined in <time.h>
Alejandro Colomar [Thu, 22 Dec 2022 10:53:44 +0000 (11:53 +0100)] 
Assume struct tm is defined in <time.h>

It has been a requirement since at least C90, according to tm(3type).

Link: <https://github.com/shadow-maint/shadow/pull/600>
Cc: Christian Göttsche <cgzones@googlemail.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAssume struct stat has st_atim and st_mtim fields
Alejandro Colomar [Thu, 22 Dec 2022 10:42:44 +0000 (11:42 +0100)] 
Assume struct stat has st_atim and st_mtim fields

That's required by POSIX.1-2008.

Link: <https://github.com/shadow-maint/shadow/pull/600>
Cc: Christian Göttsche <cgzones@googlemail.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove USE_SYSLOG preprocessor conditional, which was always defined
Alejandro Colomar [Wed, 21 Dec 2022 16:53:16 +0000 (17:53 +0100)] 
Remove USE_SYSLOG preprocessor conditional, which was always defined

Reported-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove dead code
Alejandro Colomar [Wed, 21 Dec 2022 16:43:31 +0000 (17:43 +0100)] 
Remove dead code

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoDon't redefine errno(3)
Alejandro Colomar [Wed, 21 Dec 2022 18:02:25 +0000 (19:02 +0100)] 
Don't redefine errno(3)

It is Undefined Behavior to declare errno (see NOTES in its manual page).
Instead of using the errno dummy declaration, use one that doesn't need
a comment.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoFix typos in length calculations
Alejandro Colomar [Fri, 16 Dec 2022 00:08:12 +0000 (01:08 +0100)] 
Fix typos in length calculations

Link: <https://github.com/shadow-maint/shadow/pull/607>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoUse 'uintmax_t' to print 'gid_t'
Alejandro Colomar [Fri, 16 Dec 2022 00:06:09 +0000 (01:06 +0100)] 
Use 'uintmax_t' to print 'gid_t'

This is shorter to write than 'unsigned long int', so we can collapse
some lines.  It is guaranteed by C99.

Link: <https://github.com/shadow-maint/shadow/pull/607>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoFix off-by-one mistakes
Alejandro Colomar [Thu, 15 Dec 2022 23:52:27 +0000 (00:52 +0100)] 
Fix off-by-one mistakes

The buffers have a size of 512 (see xmalloc() above), which is what
snprintf(3) expects.

Link: <https://github.com/shadow-maint/shadow/pull/607>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoCosmetic fixes
Alejandro Colomar [Wed, 21 Dec 2022 17:44:06 +0000 (18:44 +0100)] 
Cosmetic fixes

Previous commits, to keep readability of the diffs, left the code that
was previously wrapped by preprocessor coditionals untouched.  Apply
some minor cosmetic changes to merge it in the surrounding code.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoRemove traces of utmpx
Alejandro Colomar [Wed, 21 Dec 2022 17:36:57 +0000 (18:36 +0100)] 
Remove traces of utmpx

-  USER_NAME_MAX_LENGTH was being calculated in terms of utmpx.  Do it
   in terms of utmp.
-  Remove utmpx support from the whishlist.
-  Remove unused tests about utmpx members.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoDisable utmpx permanently
Alejandro Colomar [Wed, 21 Dec 2022 17:33:40 +0000 (18:33 +0100)] 
Disable utmpx permanently

On Linux, utmpx and utmp are identical.  However, documentation (manual
pages) covers utmp, and just says about utmpx that it's identical to
utmp.  It seems that it's preferred to use utmp, at least by reading the
manual pages.

Moreover, we were defaulting to utmp (utmpx had to be explicitly enabled
at configuration time).  So, it seems safer to just make it permanent,
which should not affect default builds.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2 years agoAssume <utmpx.h> always exists
Alejandro Colomar [Wed, 21 Dec 2022 16:59:30 +0000 (17:59 +0100)] 
Assume <utmpx.h> always exists

We already made that assumption in commit b47aa1e9aaf4.  While the
header is not required by POSIX (it is an XSI extension), it is defined
in systems that are of interest to this project (GNU/Linux).

Fixes: b47aa1e9aaf4 ("Assume <utmpx.h> exists")
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>