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>
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>
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>
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>
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>
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>
Clang doesn't implement this attribute and reports an error. Work
around it by hiding it in a macro that will be empty in clang.
Reported-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
There are several issues with getpass(3).
Many implementations of it share the same issues that the infamous
gets(3). In glibc it's not so terrible, since it's a wrapper
around getline(3). But it still has an important bug:
If the password is long enough, getline(3) will realloc(3) memory,
and prefixes of the password will be laying around in some
deallocated memory.
See the getpass(3) manual page for more details, and especially
the commit that marked it as deprecated, which links to a long
discussion in the linux-man@ mailing list.
So, readpassphrase(3bsd) is preferrable, which is provided by
libbsd on GNU systems. However, using readpassphrase(3) directly
is a bit verbose, so we can write our own wrapper with a simpler
interface similar to that of getpass(3).
One of the benefits of writing our own interface around
readpassphrase(3) is that we can hide there any checks that should
be done always and which would be error-prone to repeat every
time. For example, check that there was no truncation in the
password.
Also, use malloc(3) to get the buffer, instead of using a global
buffer. We're not using a multithreaded program (and it wouldn't
make sense to do so), but it's nice to know that the visibility of
our passwords is as limited as possible.
erase_pass() is a clean-up function that handles all clean-up
correctly, including zeroing the entire buffer, and then
free(3)ing the memory. By using [[gnu::malloc(erase_pass)]], we
make sure that we don't leak the buffers in any case, since the
compiler will be able to enforce clean up.
Link: <https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit?id=7ca189099d73bde954eed2d7fc21732bcc8ddc6b>
Reported-by: Christian Göttsche <cgzones@googlemail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
free(3) accepts NULL, since the oldest ISO C. I guess the
paranoid code was taking care of prehistoric implementations of
free(3). I've never known of an implementation that doesn't
conform to this, so let's simplify this.
Remove xfree(3), which was effectively an equivalent of free(3).
Signed-off-by: Alejandro Colomar <alx@kernel.org>
nss_init() does not modify its path argument, thus declare it const.
Also drop superfluous prototype.
nss.c:54:31: warning: assignment discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
54 | nsswitch_path = NSSWITCH;
| ^
Function declarations with no argument declare functions taking an
arbitrary number of arguments. Use the special type void to declare
functions taking no argument.
PARAMETERS:
According to the C2x charter, I reordered the parameters 'size'
and 'buf' from previously existing date_to_str() definitions.
C2x charter:
> 15. Application Programming Interfaces (APIs) should be
> self-documenting when possible. In particular, the order of
> parameters in function declarations should be arranged such that
> the size of an array appears before the array. The purpose is to
> allow Variable-Length Array (VLA) notation to be used. This not
> only makes the code's purpose clearer to human readers, but also
> makes static analysis easier. Any new APIs added to the Standard
> should take this into consideration.
I used 'long' for the date parameter, as some uses of the function
need to pass a negative value meaning "never".
FUNCTION BODY:
I didn't check '#ifdef HAVE_STRFTIME', which old definitions did,
since strftime(3) is guaranteed by the C89 standard, and all of
the conversion specifiers that we use are also specified by that
standard, so we don't need any extensions at all.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Close the selabel handle to update the file_context. This means that the
file_context will be remmaped and used by selabel_lookup() to return
the appropriate context to label the home folder.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1993081
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Closes#331
1. drop 'has_any_range' nss method as it is not useful
2. do not try to create a subid range in newusers when using nss for
subids, since that's not possible.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
(cherry picked from commit 88a434adbdcf4a8640793fd58bcd2ba77598349d)
Following alexey-tikhonov's suggestion.
Since we've dropped the 'owner' field in the data returned for
get_subid_ranges, we can just return a single allocated array of
simple structs. This means we can return a ** instead of ***, and
we can get rid of the subid_free_ranges() helper, since the caller
can just free() the returned data.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Closes: 339
struct subordinate_range is pretty closely tied to the existing
subid code and /etc/subuid format, so it includes an owner. Dropping
that or even renaming it is more painful than I'd first thought.
So introduce a 'struct subid_range' which is only the start and
count, leaving 'struct subordinate_range' as the owner, start and
count.
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Closes#325
Add a new subid_init() function which can be used to specify the
stream on which error messages should be printed. (If you want to
get fancy you can redirect that to memory :) If subid_init() is
not called, use stderr. If NULL is passed, then /dev/null will
be used.
This patch also fixes up the 'Prog', which previously had to be
defined by any program linking against libsubid. Now, by default
in libsubid it will show (subid). Once subid_init() is called,
it will use the first variable passed to subid_init().
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Search the SELinux selabel database for the file type to be created.
Not specifying the file mode can cause an incorrect file context to be
returned.
Also prepare contexts in commonio_close() for the generic database
filename, not with the backup suffix appended, to ensure the desired
file context after the final rename.
Closes: #322
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Closes#154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Using hard-coded access vector ids is deprecated and can lead to issues with custom SELinux policies.
Switch to `selinux_check_access()`.
Also use the libselinux log callback and log if available to audit.
This makes it easier for users to catch SELinux denials.
Drop legacy shortcut logic for passwd, which avoided a SELinux check if uid 0 changes a password of a user which username equals the current SELinux user identifier.
Nowadays usernames rarely match SELinux user identifiers and the benefit of skipping a SELinux check is negligible.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
new switch added to useradd command, --btrfs-subvolume-home. When
specified *and* the filesystem is detected as btrfs, it will create a
subvolume for user's home instead of a plain directory. This is done via
`btrfs subvolume` command. Specifying the new switch while trying to
create home on non-btrfs will result in an error.
userdel -r will handle and remove this subvolume transparently via
`btrfs subvolume` command. Previosuly this failed as you can't rmdir a
subvolume.
usermod, when moving user's home across devices, will detect if the home
is a subvolume and issue an error messages instead of copying it. Moving
user's home (as subvolume) on same btrfs works transparently.
This allows shadow-utils to build on systems like Adélie, which have no
<utmp.h> header or `struct utmp`. We use a <utmpx.h>-based daemon,
utmps[1], which uses `struct utmpx` only.
Tested both `login` and `logoutd` with utmps and both work correctly.
[1]: http://skarnet.org/software/utmps/
The third field in the /etc/shadow file (sp_lstchg) contains the date of
the last password change expressed as the number of days since Jan 1, 1970.
As this is a relative time, creating a user today will result in:
username:17238:0:99999:7:::
whilst creating the same user tomorrow will result in:
username:17239:0:99999:7:::
This has an impact for the Reproducible Builds[0] project where we aim to
be independent of as many elements the build environment as possible,
including the current date.
This patch changes the behaviour to use the SOURCE_DATE_EPOCH[1]
environment variable (instead of Jan 1, 1970) if valid.
[0] https://reproducible-builds.org/
[1] https://reproducible-builds.org/specs/source-date-epoch/
Signed-off-by: Chris Lamb <lamby@debian.org>
* configure.in: Add configure options --enable-subordinate-ids /
--disable-subordinate-ids. Enabled by default.
* lib/prototypes.h: Include <config.h> before using its macros.
* lib/commonio.h, lib/commonio.c: Define commonio_append only when
ENABLE_SUBIDS is defined.
* lib/prototypes.h, libmisc/find_new_sub_gids.c,
libmisc/find_new_sub_uids.c: Likewise.
* lib/subordinateio.h, lib/subordinateio.c: Likewise.
* libmisc/user_busy.c: Only check if subordinate IDs are in use if
ENABLE_SUBIDS is defined.
* src/Makefile.am: Create newgidmap and newuidmap only if
ENABLE_SUBIDS is defined.
* src/newusers.c: Check for ENABLE_SUBIDS to enable support for
subordinate IDs.
* src/useradd.c: Likewise.
* src/userdel.c: Likewise.
* src/usermod.c: Likewise.
* man/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1,
man5/subgid.5, and man5/subuid.5 only if ENABLE_SUBIDS is defined.
* man/fr/Makefile.am: Install man1/newgidmap.1, man1/newuidmap.1,
man5/subgid.5, and man5/subuid.5 (not translated yet).
* man/generate_mans.mak: Add xsltproc conditionals
subids/no_subids.
* man/login.defs.d/SUB_GID_COUNT.xml: Add dependency on subids
condition.
* man/login.defs.d/SUB_UID_COUNT.xml: Likewise.
* man/usermod.8.xml: Document options for subordinate IDs and
reference subgid(5) / subuid(5) depending on the subids condition.
* Changelog: Update documentation of 2013-07-28 mancha entry.
* lib/prototypes.h, lib/encrypt.c: Update splint marker,
pw_encrypt can return NULL.
* lib/encrypt.c: Fix outdated statement on GNU crypt.
* src/chgpasswd.c: Improve diagnostic to user when pw_encrypt
fails and use fail_exit() instead of exit().
* src/chpasswd.c: Likewise.
* src/newusers.c: Likewise.
* src/passwd.c: Likewise when new password is encrypted.
* src/newgrp.c: Improve diagnostic to user and syslog when
pw_encrypt fails. Do not apply 1s penalty as this is not an
invalid password issue.
* src/passwd.c: Likewise when password is checked.
libmisc/copydir.c, lib/selinux.c: Move set_selinux_file_context()
and reset_selinux_file_context() from libmisc/copydir.c to
lib/selinux.c.
* lib/commonio.c: Use set_selinux_file_context() and
reset_selinux_file_context() instead of using the existing
database SELinux context to set the context for the newly created
files.
po/POTFILES.in: Add process_root_flag() to process the --root
option and chroot so that the chroot config is used and changes
are applied to the chroot.