Compare commits

...

65 Commits

Author SHA1 Message Date
Serge Hallyn
cde08e422d configure.ac: release 4.16.0
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-18 16:34:10 -05:00
Serge Hallyn
2df2c35bad release 4.16.0-rc1
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-13 21:24:10 -05:00
Serge Hallyn
9b7d786b6f configure.ac: specify tar-pax to avoid 99 char filename limit
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-13 21:24:10 -05:00
Alejandro Colomar
ca046af5d9 Remove support for rlogind in login(1), that is, remove the '-r' flag
The "quick hack" finally disappeared.  Probably nobody noticed.  ;)
(See the changes in <configure.ac> for the context of this pun.)

Probably everybody uses SSH these days for remote login.  Let's remove
this insecure method.

Closes: <https://github.com/shadow-maint/shadow/issues/992>
Reviewed-by: dkwo <nicolopiazzalunga@gmail.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Michael Vetter <jubalh@iodoru.org>
Cc: Sam James <sam@gentoo.org>
Cc: Benedikt Brinkmann <datacobra@thinkbot.de>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-13 19:39:26 -05:00
Daniel Bershatsky
df59088641 libsubid: Fix code style issues 2024-06-12 21:45:31 +02:00
Daniel Bershatsky
b620b5d0d1 libsubid: Fail on plugin loading if no subid_free provided 2024-06-12 21:45:31 +02:00
Daniel Bershatsky
29dbcfbabd libsubid: Apply minor fixes 2024-06-12 21:45:31 +02:00
Daniel Bershatsky
0217516349 libsubid: Add routine to free allocated memory 2024-06-12 21:45:31 +02:00
Daniel Bershatsky
18f113cc46 libsubid: Dealocate memory on exit 2024-06-12 18:41:22 +02:00
lixinyun
10429edc14 src/groupmod.c: delete gr_free_members(&grp) to avoid double free
Groupmod -U may cause crashes because of double free. If without -a, the first free of (*ogrp).gr_mem is in gr_free_members(&grp), and then in gr_update without -n or gr_remove with -n.
Considering the minimal impact of modifications on existing code, delete gr_free_members(&grp) to avoid double free.Although this may seem reckless, the second free in two different positions will definitely be triggered, and the following two test cases can be used to illustrate the situation :

[root@localhost src]# ./useradd u1
[root@localhost src]# ./useradd u2
[root@localhost src]# ./useradd u3
[root@localhost src]# ./groupadd -U u1,u2,u3 g1
[root@localhost src]# ./groupmod -n g2 -U u1,u2 g1
Segmentation fault

This case would free (*ogrp).gr_mem in gr_free_members(&grp) due to assignment statements grp = *ogrp, then in if (nflg && (gr_remove (group_name) == 0)), which finally calls gr_free_members(grent) to free (*ogrp).gr_mem again.

[root@localhost src]# ./useradd u1
[root@localhost src]# ./useradd u2
[root@localhost src]# ./useradd u3
[root@localhost src]# ./groupadd -U u1,u2,u3 g1
[root@localhost src]# ./groupmod -U u1,u2 g1
Segmentation fault

The other case would free (*ogrp).gr_mem in gr_free_members(&grp) too, then in if (gr_update (&grp) == 0), which finally calls gr_free_members(grent) too to free (*ogrp).gr_mem again.

So the first free is unnecessary, maybe we can drop it.

Fixes: 342c934a35 ("add -U option to groupadd and groupmod")
Closes: <https://github.com/shadow-maint/shadow/issues/1013>
Link: <https://github.com/shadow-maint/shadow/pull/1007>
Link: <https://github.com/shadow-maint/shadow/pull/271>
Link: <https://github.com/shadow-maint/shadow/issues/265>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: lixinyun <li.xinyun@h3c.com>
2024-06-07 12:42:44 +02:00
Serge Hallyn
8acec35d1d man/lastlog: remove wrong use of keyword term
Per https://tdg.docbook.org/tdg/4.5/term, term is a word being
defined in a varlistentry.  The 'high uid' description is not a
varlistentry, so <term> and </term> show up in the processed
manpage.  See debian Bug#1072297.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-05 15:49:54 +02:00
Alejandro Colomar
69f74dbf8a lib/cast.h: const_cast(): Reimplement with _Generic(3)
This makes it much simpler and portable.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-04 09:10:23 +02:00
Iker Pedrosa
4e2453fa9f configure: move cmocka library detection
`PKG_CONFIG` variable needs to be set for `PKG_CHECK_MODULES` to
succeed, but this wasn't happening in Fedora because the first
appearance of `PKG_CHECK_MODULES` was conditionally skipped because this
distribution is compiled without `libbsd` support. Thus, moving the
cmocka library detection before libbsd fixes the problem.

Suggested-by: Lukas Slebodnik <lslebodn@fedoraproject.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-05-28 19:19:58 -05:00
Serge Hallyn
d0fef040ed tests: add the tests/ subdirectory to dist tarball
This is a first step to helping distributions to use our tests in CI.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-05-28 19:18:39 -05:00
Alejandro Colomar
71e28359d1 lib/atoi/strtou_noneg.[ch], tests/: strtoul_noneg(): Remove unused function
All call sites have been replaced by functions from "atoi/a2i.h" and
"atoi/str2i.h" recently.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-27 16:32:09 +02:00
Alejandro Colomar
f3a1e1cf09 src/check_subid_range.c: Call str2ul() instead of strtoul_noneg()
It is a simpler call, with more type safety.

A consequence of this change is that the program now accepts numbers in
bases 8 and 16.  That's not a problem here, I think.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-27 16:32:09 +02:00
Alejandro Colomar
fb49de61b7 lib/atoi/strtou_noneg.[ch], tests/: strtoull_noneg(): Remove unused function
All call sites were replaced by a2i() recently.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-27 16:32:09 +02:00
Alejandro Colomar
895dfd77d2 lib/gettime.c: gettime(): Call a2i() instead of strtoull_noneg()
time_t isn't necessarily unsigned (in fact, it's likely to be signed.
Therefore, parse the number as the right type, via a2i(time_t, ...).

Still, reject negative numbers, just to be cautious.  It was done
before (strtoull_noneg()), so it shouldn't be a problem.  (However,
strtoull_noneg() was only introduced recently, and before that we called
strtoull(3), which silently accepted negative values.)

Remove the limitation of ULONG_MAX, which seems arbitrary.  It probably
was written in times where 'time_t' had the same length of 'long', and
this was thus a test that the value didn't overflow 'time_t'.  Such a
test is implicit in the a2i() call, so forget about it.

Unify the error messages into a single one that provides all the info
(except the value of 'fallback').

Link: <cb610d54b4 (r136407772)>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Chris Lamb <lamby@debian.org>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-27 16:32:09 +02:00
Tianyu Chen
9dddcd29f1 STABLE.md: 4.15.x is now stable 2024-05-22 15:10:03 +02:00
Alejandro Colomar
a6eb312f60 src/login.c: main(): Use login_name_max_size()
Instead of raw sysconf(_SC_LOGIN_NAME_MAX) calls, which was being used
without error handling.

Fixes: 3b7cc05387 ("lib: replace `USER_NAME_MAX_LENGTH` macro")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-21 13:26:41 +02:00
Alejandro Colomar
99df9d746e lib/chkname.[ch]: login_name_max_size(): Add function
It encapsulates some logic that we may want to reuse elsewhere.

Link: <https://github.com/shadow-maint/shadow/pull/989>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-21 13:26:41 +02:00
Alejandro Colomar
27e467a61a lib/chkname.[ch]: Fix includes
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-21 13:26:41 +02:00
Alejandro Colomar
d8e6a8b99b src/usermod.c: update_gshadow(): Add helper function
Keep the while loop in the outer function, and move the iteration code
to this new helper.  This makes it a bit more readable.

Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
adf37cccd0 src/usermod.c: update_group(): Add helper function
Keep the while loop in the outer function, and move the iteration code
to this new helper.  This makes it a bit more readable.

Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
da77a82ecb src/usermod.c: update_gshadow_file(): Reduce scope of local variable
After _every_ iteration, 'changed' is always 'false'.  We don't need to
have it outside of the loop.

See:

$ grepc update_gshadow_file . \
| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \
| pcre2grep -v -M '{\n\t*}';
{
	bool               changed;
	changed = false;
	while ((sgrp = sgr_next ()) != NULL) {
		if (!was_member && !was_admin && !is_member) {
			continue;
		}
		if (was_admin && lflg) {
			changed = true;
		}
		if (was_member) {
			if ((!Gflg) || is_member) {
				if (lflg) {
					changed = true;
				}
			} else {
				changed = true;
			}
		} else if (is_member) {
			changed = true;
		}
		if (!changed)
			goto free_nsgrp;
		changed = false;
	}
}

This was already true in the commit that introduced the code:

$ git show 45c6603cc:src/usermod.c \
| grepc update_gshadow \
| grep -e changed -e goto -e break -e continue -e '\<if\>' -e '{' -e '}' \
| pcre2grep -v -M '{\n\t*}';
{
	int changed;
	changed = 0;
	while ((sgrp = sgr_next())) {
		 * See if the user was a member of this group
		 * See if the user was an administrator of this group
		 * See if the user specified this group as one of their
		if (!was_member && !was_admin && !is_member)
			continue;
		if (was_admin && lflg) {
			changed = 1;
		}
		if (was_member && (!Gflg || is_member)) {
			if (lflg) {
				changed = 1;
			}
		} else if (was_member && Gflg && !is_member) {
			changed = 1;
		} else if (!was_member && Gflg && is_member) {
			changed = 1;
		}
		if (!changed)
			continue;
		changed = 0;
	}
}

Fixes: 45c6603cc8 ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
68d42a8fbe src/usermod.c: update_group_file(): Reduce scope of local variable
After _every_ iteration, 'changed' is always 'false'.  We don't need to
have it outside of the loop.

See:

$ grepc update_group_file . \
| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \
| pcre2grep -v -M '{\n\t*}';
{
	bool                changed;
	changed = false;
	while ((grp = gr_next ()) != NULL) {
		if (!was_member && !is_member) {
			continue;
		}
		if (was_member) {
			if ((!Gflg) || is_member) {
				if (lflg) {
					changed = true;
				}
			} else {
				changed = true;
			}
		} else if (is_member) {
			changed = true;
		}
		if (!changed)
			goto free_ngrp;
		changed = false;
free_ngrp:
	}
}

This was already true in the commit that introduced the code:

$ git show 45c6603cc:src/usermod.c \
| grepc update_group \
| grep -e changed -e goto -e break -e continue -e '\<if\>' -e '{' -e '}' \
| pcre2grep -v -M '{\n\t*}';
{
	int changed;
	changed = 0;
	while ((grp = gr_next())) {
		 * See if the user specified this group as one of their
		if (!was_member && !is_member)
			continue;
		if (was_member && (!Gflg || is_member)) {
			if (lflg) {
				changed = 1;
			}
		} else if (was_member && Gflg && !is_member) {
			changed = 1;
		} else if (!was_member && Gflg && is_member) {
			changed = 1;
		}
		if (!changed)
			continue;
		changed = 0;
	}
}

Fixes: 45c6603cc8 ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
71a3238b79 src/usermod.c: update_gshadow_file(): Fix RESOURCE_LEAK (CWE-772)
Report:
> shadow-4.15.0/src/usermod.c:864:3: alloc_fn: Storage is returned from allocation function "__sgr_dup".
> shadow-4.15.0/src/usermod.c:864:3: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)".
> shadow-4.15.0/src/usermod.c:964:1: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to.
> 962|                   free (nsgrp);
> 963|           }
> 964|-> }
> 965|   #endif                                /* SHADOWGRP */
> 966|

Link: https://issues.redhat.com/browse/RHEL-35383
Reported-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
61964aa06b src/usermod.c: update_group_file(): Fix RESOURCE_LEAK (CWE-772)
Report:
> shadow-4.15.0/src/usermod.c:734:3: alloc_fn: Storage is returned from allocation function "__gr_dup".
> shadow-4.15.0/src/usermod.c:734:3: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)".
> shadow-4.15.0/src/usermod.c:815:1: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to.
> 813|                   gr_free(ngrp);
> 814|           }
> 815|-> }
> 816|
> 817|   #ifdef SHADOWGRP

Link: https://issues.redhat.com/browse/RHEL-35383
Reported-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
81bc78ec5c src/usermod.c: Rename update_gshadow() => update_gshadow_file()
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
b089a63ab3 src/usermod.c: Rename update_group() => update_group_file()
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
151f14ad69 src/usermod.c: Reduce scope of local variables
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-20 09:37:01 +02:00
Alejandro Colomar
1ee066ae1e src/useradd.c: set_defaults(): Fix FILE* leak
Report:
> shadow-4.15.0/src/useradd.c:575:2: alloc_fn: Storage is returned from allocation function "fdopen".
> shadow-4.15.0/src/useradd.c:575:2: var_assign: Assigning: "ofp" = storage returned from "fdopen(ofd, "w")".
> shadow-4.15.0/src/useradd.c:734:2: leaked_storage: Variable "ofp" going out of scope leaks the storage it points to.
> 732|           }
> 733|
> 734|->         return ret;
> 735|   }
> 736|

Link: <https://issues.redhat.com/browse/RHEL-35383>
Reported-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Alejandro Colomar
e7d1508e07 src/useradd.c: Add fmkstemp() to fix file-descriptor leak
This function creates a temporary file, and returns a FILE pointer to
it.  This avoids dealing with both a file descriptor and a FILE pointer,
and correctly deallocating the resources on error.

The code before this patch was leaking the file descriptor if fdopen(3)
failed.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Alejandro Colomar
a74c4b6ae1 src/useradd.c: De-duplicate code
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Alejandro Colomar
701fe4cf1a src/useradd.c: set_defaults(): Do not free(3) the result of asprintf(3) if it failed
See asprintf(3):

RETURN VALUE
     When successful,  these  functions  return  the  number  of  bytes
     printed, just like sprintf(3).  If memory allocation wasn’t possi‐
     ble,  or  some other error occurs, these functions will return -1,
     and the contents of strp are undefined.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Alejandro Colomar
37ae8827a0 src/useradd.c: set_defaults(): Rename goto label
This will help add other labels in the following commits.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Alejandro Colomar
f8fc6371f6 src/useradd.c: set_defaults(): Fix order of clean-ups
Resources should be freed in the inverse order of the allocation.
This refactor prepares for the following commits, which fix some leaks.

Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-18 01:15:10 +02:00
Iker Pedrosa
4c16416ebc port: fix OVERRUN (CWE-119)
```
shadow-4.15.0/lib/port.c:154:2: alias: Assigning: "port.pt_names" = "ttys". "port.pt_names" now points to element 0 of "ttys" (which consists of 65 8-byte elements).
shadow-4.15.0/lib/port.c:155:2: cond_const: Checking "j < 64" implies that "j" is 64 on the false branch.
shadow-4.15.0/lib/port.c:175:2: overrun-local: Overrunning array of 65 8-byte elements at element index 65 (byte offset 527) by dereferencing pointer "port.pt_names + (j + 1)".
173|           *cp = '\0';
174|           cp++;
175|->         port.pt_names[j + 1] = NULL;
176|
177|           /*
```

Resolves: https://issues.redhat.com/browse/RHEL-35383

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 16:08:26 +02:00
Alejandro Colomar
0066743c49 lib/getrange.c: getrange(): Report an error when min>max
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 15:40:03 +02:00
Alejandro Colomar
29f135777e lib/getrange.c: getrange(): Add missing cast
isdigit(3) requires a cast if the argument is of type 'char'.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 15:40:03 +02:00
Alejandro Colomar
34f431f607 lib/getrange.c: getrange(): Add const to pointer
Now that we have const-generic macros, we can use a const pointer.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 15:40:03 +02:00
Alejandro Colomar
040ba6a853 lib/getrange.c: getrange(): Use a2ul() instead of strtoul_noneg()
It simplifies the error checking.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 15:40:03 +02:00
Alejandro Colomar
b0498564b2 lib/atoi/a2i.[ch]: Add const-generic macros
These overloaded macros allow passing either a const or a non-const
endp, and will call the appropriate function.  This kind of const
overloading has prior art in C23's string functions, such as memchr(3).

Martin suggested using an artificial function pointer in _Generic(3); it
allows switching on various types at the same time.

Also add a comment referring to liba2i's PDF manual for documentation.

Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf#subsubsection.7.26.5.2>
Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114731>
Link: <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf>
Co-developed-by: Martin Uecker <muecker@gwdg.de>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-17 15:40:03 +02:00
Alejandro Colomar
26c9dd3715 lib/alloc.h: Reimplement [X]REALLOC[F]() macros with _Generic(3)
Instead of GNU builtins and extensions, these macros can be implemented
with C11's _Generic(3), and the result is much simpler (and safer, since
it's now an error, not just a warning).

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-15 12:08:00 +02:00
Frans Spiesschaert
18ecf3987e updated Dutch translation 2024-05-09 14:25:19 +02:00
Iker Pedrosa
9b3889696b man: update translations for username length
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-09 10:56:27 +02:00
Iker Pedrosa
03c31bef87 man: update username length
Fixes: 6a1f45d932 ("lib/chkname.c: Support unlimited user name lengths")
Related-To: https://github.com/shadow-maint/shadow/pull/986

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-09 10:56:27 +02:00
Alejandro Colomar
98aefe8772 lib/, src/: Rename some local variables
'endptr' is appropriate internally in strtol(3) because it's a pointer
to 'end', and 'end' itself is a pointer to one-after-the-last character
of the numeric string.  In other words,

	endptr == &end

However, naming the pointer whose address we pass to strtol(3)'s
'endptr' feels wrong, and causes me trouble while parsing the code; I
need to double check the number of dereferences, because something feels
wrong in my head.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
f40bd94856 lib/getrange.c: getrange(): Use goto to deduplicate code
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
7af7361fd6 lib/getrange.c: getrange(): Return early
It's doesn't make much sense to break from a switch() just to return.
Let's return early, to simplify.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
bbb2735cc0 lib/getrange.c: getrange(): Return early to reduce indentation
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
d7ab811a36 lib/getrange.c: getrange(): Don't else after return
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
62a4daa2cd lib/getrange.c: getrange(): Return early to remove an else
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
8d8062c770 lib/getrange.c: getrange(): Remove temporary variable
This means we set the pointees on error, which we didn't do before, but
since we return -1 on error and ignore (don't use) the pointees at call
site, that's fine.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
38a0b0a610 lib/getrange.c: getrange(): Small refactor
All 3 non-error paths in the second part resulted in *has_min = true.
Set in once before the switch(), to simplify.

This means we set this variable on error, which we didn't do before,
but since we return -1 on error and ignore (don't use) the pointees at
call site, that's fine.

Also, move a couple of *has_max = true statements to before a comment,
in preparation for future commits.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Alejandro Colomar
6bf5d6d4f3 lib/getrange.c: getrange(): Small refactor
Set *has_{min,max} = false at the begining, so we only need to set them
to true later.

This means we set these variables on error, which we didn't do before,
but since we return -1 on error and ignore (don't use) the pointees at
call site, that's fine.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-05-04 17:22:57 -05:00
Iker Pedrosa
dbd3527c03 share/containers: update build flags for fedora 40
libpam is enabled to provide `passwd` binary from this package, as there
are several password quality checks that are enabled through a PAM
module. Same reason to disable account-tools-setuid.

sssd is disabled because `files provider` has been removed in sssd, and
the underlying functionality in shadow isn't needed anymore.

libcrack dependency was disabled some time ago, but the upstream repo
wasn't updated. Doing it now.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-02 10:45:03 +02:00
Iker Pedrosa
dbf3b1ad51 share/containers: sort configuration options
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-02 10:45:03 +02:00
Iker Pedrosa
b8f17f9c29 share/containers: fix indentation in fedora
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-05-02 10:45:03 +02:00
Serge Hallyn
2e01b9d7d2 newuidmap and newgidmap manpages: fix fd description
The manpages for newuidmap and newgidmap had a typo "[pid[" instead
of "[pid]".  They were also unclear about what the /proc/pid fd should
be.  Fix both.

Closes #977

Reported-by: igo95862@yandex.ru
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-04-10 09:18:40 +02:00
Tobias Stoeckmann
5f5b21fd5c lib/env.c: treat out of memory condition as error
If not enough memory is available for more environment variables, treat
it exactly like not enough memory for new environment variable content.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-04-04 20:12:03 +02:00
Alejandro Colomar
f7fe4c5978 lib/atoi/: a2*(), str2*(): Add variants for other types
And type-generic macros that wrap them: a2i(), str2i()

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-03-29 14:29:13 -05:00
Alejandro Colomar
f39ac101ff lib/, src/: str2*(): Rename functions and reorder parameters
This makes them compatible with liba2i's functions.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-03-29 14:29:13 -05:00
Alejandro Colomar
b085c3f612 lib/atoi/: Add a2[su]l() and reimplement get[u]long() in terms of them
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-03-29 14:29:13 -05:00
Alejandro Colomar
27e236ca79 lib/, src/, po/: get[u]long(): Move functions to lib/atoi/str2i.h
And make them inline.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-03-29 14:29:13 -05:00
73 changed files with 1241 additions and 1180 deletions

View File

@@ -15,3 +15,4 @@ SUBDIRS += man
endif
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
EXTRA_DIST = tests/

View File

@@ -2,10 +2,10 @@
The following stable branches are kindly maintained by trusted volunteers:
- 4.14.x
- 4.15.x
- git
- [main](https://www.alejandro-colomar.es/src/alx/shadow/stable/shadow.git/log/?h=4.14.x)
- [mirror](https://github.com/shadow-maint/shadow/tree/4.14.x)
- [main](https://www.alejandro-colomar.es/src/alx/shadow/stable/shadow.git/log/?h=4.15.x)
- [mirror](https://github.com/shadow-maint/shadow/tree/4.15.x)
- tarballs
- [main](https://www.alejandro-colomar.es/share/dist/shadow/4/4.14/)
- [main](https://www.alejandro-colomar.es/share/dist/shadow/4/4.15/)
- [mirror](https://github.com/shadow-maint/shadow/releases/)

View File

@@ -1,12 +1,12 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
m4_define([libsubid_abi_major], 4)
m4_define([libsubid_abi_major], 5)
m4_define([libsubid_abi_minor], 0)
m4_define([libsubid_abi_micro], 0)
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
AC_INIT([shadow], [4.15.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
AC_INIT([shadow], [4.16.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
AC_CONFIG_MACRO_DIRS([m4])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS([config.h])
@@ -159,13 +159,6 @@ fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
dnl XXX - quick hack, should disappear before anyone notices :).
dnl XXX - I just read the above message :).
if test "$ac_cv_func_ruserok" = "yes"; then
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
fi
AC_ARG_ENABLE(shadowgrp,
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[case "${enableval}" in
@@ -274,6 +267,7 @@ AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max grou
AC_SUBST(GROUP_NAME_MAX_LENGTH)
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
@@ -310,6 +304,10 @@ dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
AC_SEARCH_LIBS(gethostbyname, nsl)
PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
[AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
if test -n "$LIBECONF"; then
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
@@ -701,10 +699,6 @@ if test "$with_skey" = "yes"; then
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
fi
PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
[AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])

View File

@@ -31,6 +31,10 @@ libshadow_la_SOURCES = \
agetpass.h \
alloc.c \
alloc.h \
atoi/a2i.c \
atoi/a2i.h \
atoi/str2i.c \
atoi/str2i.h \
atoi/strtoi.c \
atoi/strtoi.h \
atoi/strtou_noneg.c \
@@ -74,11 +78,9 @@ libshadow_la_SOURCES = \
getdate.y \
getdef.c \
getdef.h \
getlong.c \
getgr_nam_gid.c \
getrange.c \
gettime.c \
getulong.c \
groupio.c \
groupmem.c \
groupio.h \
@@ -117,7 +119,6 @@ libshadow_la_SOURCES = \
pwdcheck.c \
pwmem.c \
remove_tree.c \
rlogin.c \
root_flag.c \
run_part.h \
run_part.c \

View File

@@ -1,8 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
@@ -27,31 +24,19 @@
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
#define REALLOC(ptr, n, type) \
({ \
__auto_type p_ = (ptr); \
\
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
\
(type *) reallocarray(p_, n, sizeof(type)); \
})
( \
_Generic(ptr, type *: (type *) reallocarray(ptr, n, sizeof(type))) \
)
#define REALLOCF(ptr, n, type) \
({ \
__auto_type p_ = (ptr); \
\
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
\
(type *) reallocarrayf(p_, n, sizeof(type)); \
})
( \
_Generic(ptr, type *: (type *) reallocarrayf(ptr, n, sizeof(type))) \
)
#define XREALLOC(ptr, n, type) \
({ \
__auto_type p_ = (ptr); \
\
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
\
(type *) xreallocarray(p_, n, sizeof(type)); \
})
( \
_Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
)
ATTR_MALLOC(free)

46
lib/atoi/a2i.c Normal file
View File

@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i.h"
extern inline int a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max);
extern inline int a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max);
extern inline int a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max);
extern inline int a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max);
extern inline int a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max);
extern inline int a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max);
extern inline int a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max);
extern inline int a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max);
extern inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
extern inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
extern inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
extern inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
extern inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
extern inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
extern inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
extern inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);

386
lib/atoi/a2i.h Normal file
View File

@@ -0,0 +1,386 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_H_
#include <config.h>
#include <errno.h>
#include "atoi/strtoi.h"
#include "atoi/strtou_noneg.h"
#include "attr.h"
/*
* See the manual of these macros in liba2i's documentation:
* <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf>
*/
#define a2i(TYPE, n, s, ...) \
( \
_Generic((void (*)(TYPE, typeof(s))) 0, \
void (*)(short, const char *): a2sh_c, \
void (*)(short, const void *): a2sh_c, \
void (*)(short, char *): a2sh_nc, \
void (*)(short, void *): a2sh_nc, \
void (*)(int, const char *): a2si_c, \
void (*)(int, const void *): a2si_c, \
void (*)(int, char *): a2si_nc, \
void (*)(int, void *): a2si_nc, \
void (*)(long, const char *): a2sl_c, \
void (*)(long, const void *): a2sl_c, \
void (*)(long, char *): a2sl_nc, \
void (*)(long, void *): a2sl_nc, \
void (*)(long long, const char *): a2sll_c, \
void (*)(long long, const void *): a2sll_c, \
void (*)(long long, char *): a2sll_nc, \
void (*)(long long, void *): a2sll_nc, \
void (*)(unsigned short, const char *): a2uh_c, \
void (*)(unsigned short, const void *): a2uh_c, \
void (*)(unsigned short, char *): a2uh_nc, \
void (*)(unsigned short, void *): a2uh_nc, \
void (*)(unsigned int, const char *): a2ui_c, \
void (*)(unsigned int, const void *): a2ui_c, \
void (*)(unsigned int, char *): a2ui_nc, \
void (*)(unsigned int, void *): a2ui_nc, \
void (*)(unsigned long, const char *): a2ul_c, \
void (*)(unsigned long, const void *): a2ul_c, \
void (*)(unsigned long, char *): a2ul_nc, \
void (*)(unsigned long, void *): a2ul_nc, \
void (*)(unsigned long long, const char *): a2ull_c, \
void (*)(unsigned long long, const void *): a2ull_c, \
void (*)(unsigned long long, char *): a2ull_nc, \
void (*)(unsigned long long, void *): a2ull_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sh(n, s, ...) \
( \
_Generic(s, \
const char *: a2sh_c, \
const void *: a2sh_c, \
char *: a2sh_nc, \
void *: a2sh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2si(n, s, ...) \
( \
_Generic(s, \
const char *: a2si_c, \
const void *: a2si_c, \
char *: a2si_nc, \
void *: a2si_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sl(n, s, ...) \
( \
_Generic(s, \
const char *: a2sl_c, \
const void *: a2sl_c, \
char *: a2sl_nc, \
void *: a2sl_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sll(n, s, ...) \
( \
_Generic(s, \
const char *: a2sll_c, \
const void *: a2sll_c, \
char *: a2sll_nc, \
void *: a2sll_nc \
)(n, s, __VA_ARGS__) \
)
#define a2uh(n, s, ...) \
( \
_Generic(s, \
const char *: a2uh_c, \
const void *: a2uh_c, \
char *: a2uh_nc, \
void *: a2uh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ui(n, s, ...) \
( \
_Generic(s, \
const char *: a2ui_c, \
const void *: a2ui_c, \
char *: a2ui_nc, \
void *: a2ui_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ul(n, s, ...) \
( \
_Generic(s, \
const char *: a2ul_c, \
const void *: a2ul_c, \
char *: a2ul_nc, \
void *: a2ul_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ull(n, s, ...) \
( \
_Generic(s, \
const char *: a2ull_c, \
const void *: a2ull_c, \
char *: a2ull_nc, \
void *: a2ull_nc \
)(n, s, __VA_ARGS__) \
)
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);
inline int
a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max)
{
return a2sh(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max)
{
return a2si(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max)
{
return a2sl(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max)
{
return a2sll(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max)
{
return a2uh(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max)
{
return a2ui(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max)
{
return a2ul(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max)
{
return a2ull(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min,
unsigned short max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
#endif // include guard

18
lib/atoi/str2i.c Normal file
View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/str2i.h"
extern inline int str2sh(short *restrict n, const char *restrict s);
extern inline int str2si(int *restrict n, const char *restrict s);
extern inline int str2sl(long *restrict n, const char *restrict s);
extern inline int str2sll(long long *restrict n, const char *restrict s);
extern inline int str2uh(unsigned short *restrict n, const char *restrict s);
extern inline int str2ui(unsigned int *restrict n, const char *restrict s);
extern inline int str2ul(unsigned long *restrict n, const char *restrict s);
extern inline int str2ull(unsigned long long *restrict n, const char *restrict s);

108
lib/atoi/str2i.h Normal file
View File

@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i.h"
#include "attr.h"
#define str2i(TYPE, ...) \
( \
_Generic((TYPE) 0, \
short: str2sh, \
int: str2si, \
long: str2sl, \
long long: str2sll, \
unsigned short: str2uh, \
unsigned int: str2ui, \
unsigned long: str2ul, \
unsigned long long: str2ull \
)(__VA_ARGS__) \
)
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sh(short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2si(int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sl(long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sll(long long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2uh(unsigned short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ui(unsigned int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ul(unsigned long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ull(unsigned long long *restrict n, const char *restrict s);
inline int
str2sh(short *restrict n, const char *restrict s)
{
return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
}
inline int
str2si(int *restrict n, const char *restrict s)
{
return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
}
inline int
str2sl(long *restrict n, const char *restrict s)
{
return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
}
inline int
str2sll(long long *restrict n, const char *restrict s)
{
return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
}
inline int
str2uh(unsigned short *restrict n, const char *restrict s)
{
return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
}
inline int
str2ui(unsigned int *restrict n, const char *restrict s)
{
return a2ui(n, s, NULL, 0, 0, UINT_MAX);
}
inline int
str2ul(unsigned long *restrict n, const char *restrict s)
{
return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
}
inline int
str2ull(unsigned long long *restrict n, const char *restrict s)
{
return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
}
#endif // include guard

View File

@@ -11,8 +11,3 @@
extern inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);
extern inline unsigned long strtoul_noneg(const char *s,
char **restrict endp, int base);
extern inline unsigned long long strtoull_noneg(const char *s,
char **restrict endp, int base);

View File

@@ -9,8 +9,8 @@
#include <config.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "atoi/strtoi.h"
#include "attr.h"
@@ -20,13 +20,6 @@ ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline unsigned long strtoul_noneg(const char *s,
char **restrict endp, int base);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline unsigned long long strtoull_noneg(const char *s,
char **restrict endp, int base);
inline uintmax_t
strtou_noneg(const char *s, char **restrict endp, int base,
@@ -43,26 +36,4 @@ strtou_noneg(const char *s, char **restrict endp, int base,
}
inline unsigned long
strtoul_noneg(const char *s, char **restrict endp, int base)
{
if (strtol(s, endp, base) < 0) {
errno = ERANGE;
return 0;
}
return strtoul(s, endp, base);
}
inline unsigned long long
strtoull_noneg(const char *s, char **restrict endp, int base)
{
if (strtol(s, endp, base) < 0) {
errno = ERANGE;
return 0;
}
return strtoull(s, endp, base);
}
#endif // include guard

View File

@@ -8,14 +8,8 @@
#include <config.h>
#include "must_be.h"
#define const_cast(T, p) \
({ \
static_assert(is_same_type(typeof(&*(p)), const T), ""); \
(T) (p); \
})
#define const_cast(T, p) _Generic(p, const T: (T) (p))
#endif // include guard

View File

@@ -5,6 +5,7 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
@@ -13,6 +14,7 @@
* false - bad name
*/
#include <config.h>
#ident "$Id$"
@@ -20,11 +22,31 @@
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
#include "defines.h"
#include "chkname.h"
int allow_bad_names = false;
size_t
login_name_max_size(void)
{
long conf;
errno = 0;
conf = sysconf(_SC_LOGIN_NAME_MAX);
if (conf == -1 && errno != 0)
return LOGIN_NAME_MAX;
return conf;
}
static bool is_valid_name (const char *name)
{
if (allow_bad_names) {
@@ -76,18 +98,7 @@ static bool is_valid_name (const char *name)
bool
is_valid_user_name(const char *name)
{
long conf;
size_t maxsize;
errno = 0;
conf = sysconf(_SC_LOGIN_NAME_MAX);
if (conf == -1 && errno != 0)
maxsize = LOGIN_NAME_MAX;
else
maxsize = conf;
if (strlen(name) >= maxsize)
if (strlen(name) >= login_name_max_size())
return false;
return is_valid_name(name);

View File

@@ -11,6 +11,7 @@
#ifndef _CHKNAME_H_
#define _CHKNAME_H_
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
@@ -19,8 +20,14 @@
* false - bad name
*/
#include "defines.h"
#include <config.h>
#include <stdbool.h>
#include <stddef.h>
extern size_t login_name_max_size(void);
extern bool is_valid_user_name (const char *name);
extern bool is_valid_group_name (const char *name);

View File

@@ -127,30 +127,18 @@ void addenv (const char *string, /*@null@*/const char *value)
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
bool update_environ;
char **__newenvp;
/*
* If the resize operation succeeds we can
* happily go on, else print a message.
*/
update_environ = (environ == newenvp);
__newenvp = REALLOC(newenvp, newenvc + NEWENVP_STEP, char *);
newenvp = XREALLOC(newenvp, newenvc + NEWENVP_STEP, char *);
if (NULL != __newenvp) {
/*
* If this is our current environment, update
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
if (update_environ)
environ = __newenvp;
newenvp = __newenvp;
} else {
(void) fputs (_("Environment overflow\n"), log_get_logfd());
newenvc--;
free (newenvp[newenvc]);
}
/*
* If this is our current environment, update
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
if (update_environ)
environ = newenvp;
}
/*

View File

@@ -16,13 +16,13 @@
int
get_gid(const char *gidstr, gid_t *gid)
{
char *end;
long long val;
char *endptr;
errno = 0;
val = strtoll(gidstr, &endptr, 10);
val = strtoll(gidstr, &end, 10);
if ( ('\0' == *gidstr)
|| ('\0' != *endptr)
|| ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
return -1;

View File

@@ -17,15 +17,16 @@
#include "string/sprintf.h"
int get_pid (const char *pidstr, pid_t *pid)
int
get_pid(const char *pidstr, pid_t *pid)
{
char *end;
long long val;
char *endptr;
errno = 0;
val = strtoll(pidstr, &endptr, 10);
val = strtoll(pidstr, &end, 10);
if ( ('\0' == *pidstr)
|| ('\0' != *endptr)
|| ('\0' != *end)
|| (0 != errno)
|| (val < 1)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
@@ -43,15 +44,15 @@ int get_pid (const char *pidstr, pid_t *pid)
*/
int get_pidfd_from_fd(const char *pidfdstr)
{
long long val;
char *endptr;
struct stat st;
char *end;
long long val;
struct stat st;
dev_t proc_st_dev, proc_st_rdev;
errno = 0;
val = strtoll(pidfdstr, &endptr, 10);
val = strtoll(pidfdstr, &end, 10);
if ( ('\0' == *pidfdstr)
|| ('\0' != *endptr)
|| ('\0' != *end)
|| (0 != errno)
|| (val < 0)
|| (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {

View File

@@ -16,13 +16,13 @@
int
get_uid(const char *uidstr, uid_t *uid)
{
char *end;
long long val;
char *endptr;
errno = 0;
val = strtoll(uidstr, &endptr, 10);
val = strtoll(uidstr, &end, 10);
if ( ('\0' == *uidstr)
|| ('\0' != *endptr)
|| ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
return -1;

View File

@@ -23,6 +23,7 @@
#endif
#include "alloc.h"
#include "atoi/str2i.h"
#include "getdef.h"
#include "shadowlog_internal.h"
#include "string/sprintf.h"
@@ -245,7 +246,7 @@ int getdef_num (const char *item, int dflt)
return dflt;
}
if ( (getlong(d->value, &val) == -1)
if ( (str2sl(&val, d->value) == -1)
|| (val > INT_MAX)
|| (val < -1)) {
fprintf (shadow_logfd,
@@ -280,7 +281,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
return dflt;
}
if ( (getlong(d->value, &val) == -1)
if ( (str2sl(&val, d->value) == -1)
|| (val < 0)
|| (val > INT_MAX)) {
fprintf (shadow_logfd,
@@ -315,7 +316,7 @@ long getdef_long (const char *item, long dflt)
return dflt;
}
if (getlong(d->value, &val) == -1 || val < -1) {
if (str2sl(&val, d->value) == -1 || val < -1) {
fprintf (shadow_logfd,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
@@ -347,7 +348,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt)
return dflt;
}
if (getulong(d->value, &val) == -1) {
if (str2ul(&val, d->value) == -1) {
fprintf (shadow_logfd,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);

View File

@@ -23,17 +23,17 @@
*/
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname)
{
char *end;
long long gid;
char *endptr;
if (NULL == grname) {
return NULL;
}
errno = 0;
gid = strtoll(grname, &endptr, 10);
gid = strtoll(grname, &end, 10);
if ( ('\0' != *grname)
&& ('\0' == *endptr)
&& ('\0' == *end)
&& (0 == errno)
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
return xgetgrgid (gid);

View File

@@ -1,36 +0,0 @@
/*
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <stdlib.h>
#include <errno.h>
#include "prototypes.h"
/*
* getlong - extract a long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*/
int
getlong(const char *restrict numstr, long *restrict result)
{
char *endptr;
long val;
errno = 0;
val = strtol(numstr, &endptr, 0);
if (('\0' == *numstr) || ('\0' != *endptr) || (0 != errno))
return -1;
*result = val;
return 0;
}

View File

@@ -1,8 +1,6 @@
/*
* SPDX-FileCopyrightText: 2008 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2008, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
@@ -12,7 +10,7 @@
#include <ctype.h>
#include <stdlib.h>
#include "atoi/strtou_noneg.h"
#include "atoi/a2i.h"
#include "defines.h"
#include "prototypes.h"
@@ -30,65 +28,44 @@ getrange(const char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max)
{
char *endptr;
unsigned long n;
const char *end;
if (NULL == range)
return -1;
*min = 0;
*has_min = false;
*has_max = false;
if ('-' == range[0]) {
if (!isdigit(range[1]))
return -1;
errno = 0;
n = strtoul_noneg(&range[1], &endptr, 10);
if (('\0' != *endptr) || (0 != errno))
return -1;
/* -<long> */
*has_min = false;
*has_max = true;
*max = n;
} else {
errno = 0;
n = strtoul_noneg(range, &endptr, 10);
if (endptr == range || 0 != errno)
return -1;
switch (*endptr) {
case '\0':
/* <long> */
*has_min = true;
*has_max = true;
*min = n;
*max = n;
break;
case '-':
endptr++;
if ('\0' == *endptr) {
/* <long>- */
*has_min = true;
*has_max = false;
*min = n;
} else if (!isdigit (*endptr)) {
return -1;
} else {
*has_min = true;
*min = n;
errno = 0;
n = strtoul_noneg(endptr, &endptr, 10);
if ('\0' != *endptr || 0 != errno)
return -1;
/* <long>-<long> */
*has_max = true;
*max = n;
}
break;
default:
return -1;
}
end = range + 1;
goto parse_max;
}
return 0;
if (a2ul(min, range, &end, 10, 0, ULONG_MAX) == -1 && errno != ENOTSUP)
return -1;
*has_min = true;
switch (*end++) {
case '\0':
*has_max = true;
*max = *min;
return 0; /* <long> */
case '-':
if ('\0' == *end)
return 0; /* <long>- */
parse_max:
if (!isdigit((unsigned char) *end))
return -1;
if (a2ul(max, end, NULL, 10, *min, ULONG_MAX) == -1)
return -1;
*has_max = true;
return 0; /* <long>-<long>, or -<long> */
default:
return -1;
}
}

View File

@@ -1,8 +1,7 @@
/*
* SPDX-FileCopyrightText: 2017, Chris Lamb
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2017, Chris Lamb
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
@@ -12,11 +11,12 @@
#include <limits.h>
#include <stdio.h>
#include "atoi/strtou_noneg.h"
#include "atoi/a2i.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
/*
* gettime() returns the time as the number of seconds since the Epoch
*
@@ -24,13 +24,12 @@
* Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH
* environment variable is exported it will use that instead.
*/
/*@observer@*/time_t gettime (void)
/*@observer@*/time_t
gettime(void)
{
char *endptr;
char *source_date_epoch;
time_t fallback;
unsigned long long epoch;
FILE *shadow_logfd = log_get_logfd();
char *source_date_epoch;
FILE *shadow_logfd = log_get_logfd();
time_t fallback, epoch;
fallback = time (NULL);
source_date_epoch = shadow_getenv ("SOURCE_DATE_EPOCH");
@@ -38,32 +37,11 @@
if (!source_date_epoch)
return fallback;
errno = 0;
epoch = strtoull_noneg(source_date_epoch, &endptr, 10);
if (errno != 0) {
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"),
strerror(errno));
} else if (endptr == source_date_epoch) {
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"),
endptr);
} else if (*endptr != '\0') {
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"),
endptr);
} else if (epoch > ULONG_MAX) {
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"),
ULONG_MAX, epoch);
} else if ((time_t)epoch > fallback) {
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"),
fallback, epoch);
} else {
/* Valid */
return epoch;
if (a2i(time_t, &epoch, source_date_epoch, NULL, 10, 0, fallback) == -1) {
fprintf(shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: a2i(\"%s\"): %s"),
source_date_epoch, strerror(errno));
return fallback;
}
return fallback;
return epoch;
}

View File

@@ -1,37 +0,0 @@
/*
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id: getlong.c 2763 2009-04-23 09:57:03Z nekral-guest $"
#include <stdlib.h>
#include <errno.h>
#include "atoi/strtou_noneg.h"
#include "prototypes.h"
/*
* getulong - extract an unsigned long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*/
int
getulong(const char *restrict numstr, unsigned long *restrict result)
{
char *endptr;
unsigned long val;
errno = 0;
val = strtoul_noneg(numstr, &endptr, 0);
if (('\0' == *numstr) || ('\0' != *endptr) || (0 != errno))
return -1;
*result = val;
return 0;
}

View File

@@ -14,6 +14,7 @@
#include <strings.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "prototypes.h"
#include "string/stpeprintf.h"
#include "idmapping.h"
@@ -24,6 +25,7 @@
#include "shadowlog.h"
#include "sizeof.h"
struct map_range *get_map_ranges(int ranges, int argc, char **argv)
{
struct map_range *mappings, *mapping;
@@ -49,15 +51,15 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
/* Gather up the ranges from the command line */
mapping = mappings;
for (idx = 0, argidx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
if (getulong(argv[argidx + 0], &mapping->upper) == -1) {
if (str2ul(&mapping->upper, argv[argidx + 0]) == -1) {
free(mappings);
return NULL;
}
if (getulong(argv[argidx + 1], &mapping->lower) == -1) {
if (str2ul(&mapping->lower, argv[argidx + 1]) == -1) {
free(mappings);
return NULL;
}
if (getulong(argv[argidx + 2], &mapping->count) == -1) {
if (str2ul(&mapping->count, argv[argidx + 2]) == -1) {
free(mappings);
return NULL;
}

View File

@@ -29,7 +29,11 @@
#include "getdef.h"
#include "shadowlog.h"
#include <sys/resource.h>
#include "atoi/str2i.h"
#include "memzero.h"
#ifndef LIMITS_FILE
#define LIMITS_FILE "/etc/limits"
#endif
@@ -45,7 +49,7 @@ static int setrlimit_value (unsigned int resource,
const char *value,
unsigned int multiplier)
{
char *endptr;
char *end;
long l;
rlim_t limit;
struct rlimit rlim;
@@ -57,15 +61,15 @@ static int setrlimit_value (unsigned int resource,
limit = RLIM_INFINITY;
}
else {
/* We cannot use getlong here because it fails when there
/* We cannot use str2sl() here because it fails when there
* is more to the value than just this number!
* Also, we are limited to base 10 here (hex numbers will not
* work with the limit string parser as is anyway)
*/
errno = 0;
l = strtol(value, &endptr, 10);
l = strtol(value, &end, 10);
if (value == endptr || errno != 0)
if (value == end || errno != 0)
return 0; // FIXME: We could instead throw an error, though.
if (__builtin_mul_overflow(l, multiplier, &limit)) {
@@ -89,7 +93,7 @@ static int set_prio (const char *value)
{
long prio;
if ( (getlong(value, &prio) == -1)
if ( (str2sl(&prio, value) == -1)
|| (prio != (int) prio)) {
return 0;
}
@@ -104,7 +108,7 @@ static int set_umask (const char *value)
{
unsigned long mask;
if ( (getulong(value, &mask) == -1)
if ( (str2ul(&mask, value) == -1)
|| (mask != (mode_t) mask)) {
return 0;
}
@@ -119,7 +123,7 @@ static int check_logins (const char *name, const char *maxlogins)
{
unsigned long limit, count;
if (getulong(maxlogins, &limit) == -1) {
if (str2ul(&limit, maxlogins) == -1) {
return 0;
}
@@ -482,7 +486,7 @@ void setup_limits (const struct passwd *info)
if (strncmp (cp, "pri=", 4) == 0) {
long inc;
if ( (getlong(cp + 4, &inc) == 0)
if ( (str2sl(&inc, cp + 4) == 0)
&& (inc >= -20) && (inc <= 20)) {
errno = 0;
if ( (nice (inc) != -1)
@@ -500,7 +504,7 @@ void setup_limits (const struct passwd *info)
}
if (strncmp (cp, "ulimit=", 7) == 0) {
long blocks;
if ( (getlong(cp + 7, &blocks) == -1)
if ( (str2sl(&blocks, cp + 7) == -1)
|| (blocks != (int) blocks)
|| (set_filesize_limit (blocks) != 0)) {
SYSLOG ((LOG_WARN,
@@ -512,7 +516,7 @@ void setup_limits (const struct passwd *info)
if (strncmp (cp, "umask=", 6) == 0) {
unsigned long mask;
if ( (getulong(cp + 6, &mask) == -1)
if ( (str2ul(&mask, cp + 6) == -1)
|| (mask != (mode_t) mask)) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",

View File

@@ -131,6 +131,11 @@ void nss_init(const char *nsswitch_path) {
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
goto close_lib;
}
subid_nss->free = dlsym(h, "shadow_subid_free");
if (!subid_nss->free) {
fprintf(shadow_logfd, "%s did not provide @subid_free@\n", libname);
goto close_lib;
}
subid_nss->handle = h;
goto done;

View File

@@ -168,7 +168,7 @@ again:
}
*cp = '\0';
cp++;
port.pt_names[j + 1] = NULL;
port.pt_names[j] = NULL;
/*
* Get the list of user names. It is the second colon

View File

@@ -334,9 +334,9 @@ extern void prefix_endgrent(void)
extern struct group *prefix_getgr_nam_gid(const char *grname)
{
long long gid;
char *endptr;
struct group *g;
char *end;
long long gid;
struct group *g;
if (NULL == grname) {
return NULL;
@@ -346,9 +346,9 @@ extern struct group *prefix_getgr_nam_gid(const char *grname)
return getgr_nam_gid(grname);
errno = 0;
gid = strtoll(grname, &endptr, 10);
gid = strtoll(grname, &end, 10);
if ( ('\0' != *grname)
&& ('\0' == *endptr)
&& ('\0' == *end)
&& (0 == errno)
&& (gid == (gid_t)gid))
{

View File

@@ -149,10 +149,6 @@ extern int get_gid (const char *gidstr, gid_t *gid);
/* getgr_nam_gid.c */
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname);
/* getlong.c */
ATTR_ACCESS(write_only, 2)
extern int getlong(const char *restrict numstr, long *restrict result);
/* get_pid.c */
extern int get_pid (const char *pidstr, pid_t *pid);
extern int get_pidfd_from_fd(const char *pidfdstr);
@@ -169,10 +165,6 @@ extern time_t gettime (void);
/* get_uid.c */
extern int get_uid (const char *uidstr, uid_t *uid);
/* getulong.c */
ATTR_ACCESS(write_only, 2)
extern int getulong(const char *restrict numstr, unsigned long *restrict result);
/* fputsx.c */
ATTR_ACCESS(write_only, 1, 2)
extern /*@null@*/char *fgetsx(/*@returned@*/char *restrict, int, FILE *restrict);
@@ -292,6 +284,19 @@ struct subid_nss_ops {
*/
enum subid_status (*find_subid_owners)(unsigned long id, enum subid_type id_type, uid_t **uids, int *count);
/*
* nss_free: free a memory block allocated by a subid plugin.
*
* @ptr - a pointer to a memory block to deallocate
*
* Some routines of subid_nss_ops allocate memory which should be freed by
* caller after use. In order to deallocate that memory block, one should
* use this routine to release that memory. By default, this function
* pointer is set to free(3) for backward compatibility. However, it is
* strongly recommended to define this routine explicitly.
*/
void (*free)(void *ptr);
/* The dlsym handle to close */
void *handle;
};
@@ -364,10 +369,6 @@ unsigned long csrand_interval (unsigned long min, unsigned long max);
/* remove_tree.c */
extern int remove_tree (const char *root, bool remove_root);
/* rlogin.c */
extern int do_rlogin(const char *remote_host, char *name, size_t namesize,
char *term, size_t termsize);
/* root_flag.c */
extern void process_root_flag (const char* short_opt, int argc, char **argv);

View File

@@ -1,132 +0,0 @@
/*
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2008, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ifdef RLOGIN
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include <pwd.h>
#include <netdb.h>
static struct {
int spd_name;
int spd_baud;
} speed_table[] =
{
{ B50, 50},
{ B75, 75},
{ B110, 110},
{ B134, 134},
{ B150, 150},
{ B200, 200},
{ B300, 300},
{ B600, 600},
{ B1200, 1200},
{ B1800, 1800},
{ B2400, 2400},
{ B4800, 4800},
{ B9600, 9600},
{ B19200, 19200},
{ B38400, 38400},
{ -1, -1}
};
static void
get_remote_string(char *buf, size_t size)
{
for (;;) {
if (read (0, buf, 1) != 1) {
exit (EXIT_FAILURE);
}
if ('\0' == *buf) {
return;
}
--size;
if (size > 0) {
++buf;
}
}
/*NOTREACHED*/
}
int
do_rlogin(const char *remote_host, char *name, size_t namesize, char *term,
size_t termsize)
{
struct passwd *pwd;
char remote_name[32];
char *cp;
unsigned long remote_speed = 9600;
int speed_name = B9600;
int i;
TERMIO termio;
get_remote_string(remote_name, sizeof(remote_name));
get_remote_string(name, namesize);
get_remote_string(term, termsize);
cp = strchr (term, '/');
if (NULL != cp) {
*cp = '\0';
cp++;
if (getulong(cp, &remote_speed) == -1) {
remote_speed = 9600;
}
}
for (i = 0;
( (speed_table[i].spd_baud != remote_speed)
&& (speed_table[i].spd_name != -1));
i++);
if (-1 != speed_table[i].spd_name) {
speed_name = speed_table[i].spd_name;
}
/*
* Put the terminal in cooked mode with echo turned on.
*/
GTTY (0, &termio);
termio.c_iflag |= ICRNL | IXON;
termio.c_oflag |= OPOST | ONLCR;
termio.c_lflag |= ICANON | ECHO | ECHOE;
#ifdef CBAUD
termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
#else
termio.c_cflag = (termio.c_cflag) | speed_name;
#endif
STTY (0, &termio);
pwd = getpwnam (name); /* local, no need for xgetpwnam */
if (NULL == pwd) {
return 0;
}
/*
* ruserok() returns 0 for success on modern systems, and 1 on
* older ones. If you are having trouble with people logging
* in without giving a required password, THIS is the culprit -
* go fix the #define in config.h.
*/
#ifndef RUSEROK
return 0;
#else
return ruserok (remote_host, pwd->pw_uid == 0,
remote_name, name) == RUSEROK;
#endif
}
#endif /* RLOGIN */

View File

@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <string.h>
#include "atoi/str2i.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "defines.h"
@@ -97,7 +98,7 @@ sgetspent(const char *string)
if (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else if ( (getlong(fields[2], &spwd.sp_lstchg) == -1)
} else if ( (str2sl(&spwd.sp_lstchg, fields[2]) == -1)
|| (spwd.sp_lstchg < 0)) {
return NULL;
}
@@ -108,7 +109,7 @@ sgetspent(const char *string)
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else if ( (getlong(fields[3], &spwd.sp_min) == -1)
} else if ( (str2sl(&spwd.sp_min, fields[3]) == -1)
|| (spwd.sp_min < 0)) {
return NULL;
}
@@ -119,7 +120,7 @@ sgetspent(const char *string)
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else if ( (getlong(fields[4], &spwd.sp_max) == -1)
} else if ( (str2sl(&spwd.sp_max, fields[4]) == -1)
|| (spwd.sp_max < 0)) {
return NULL;
}
@@ -144,7 +145,7 @@ sgetspent(const char *string)
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else if ( (getlong(fields[5], &spwd.sp_warn) == -1)
} else if ( (str2sl(&spwd.sp_warn, fields[5]) == -1)
|| (spwd.sp_warn < 0)) {
return NULL;
}
@@ -156,7 +157,7 @@ sgetspent(const char *string)
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else if ( (getlong(fields[6], &spwd.sp_inact) == -1)
} else if ( (str2sl(&spwd.sp_inact, fields[6]) == -1)
|| (spwd.sp_inact < 0)) {
return NULL;
}
@@ -168,7 +169,7 @@ sgetspent(const char *string)
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else if ( (getlong(fields[7], &spwd.sp_expire) == -1)
} else if ( (str2sl(&spwd.sp_expire, fields[7]) == -1)
|| (spwd.sp_expire < 0)) {
return NULL;
}
@@ -180,7 +181,7 @@ sgetspent(const char *string)
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else if (getulong(fields[8], &spwd.sp_flag) == -1) {
} else if (str2ul(&spwd.sp_flag, fields[8]) == -1) {
return NULL;
}

View File

@@ -19,6 +19,8 @@
#include "defines.h"
#include <stdio.h>
#include "atoi/str2i.h"
static FILE *shadow;
@@ -116,7 +118,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else {
if (getlong(fields[2], &spwd.sp_lstchg) == -1)
if (str2sl(&spwd.sp_lstchg, fields[2]) == -1)
return 0;
if (spwd.sp_lstchg < 0)
return 0;
@@ -129,7 +131,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else {
if (getlong(fields[3], &spwd.sp_min) == -1)
if (str2sl(&spwd.sp_min, fields[3]) == -1)
return 0;
if (spwd.sp_min < 0)
return 0;
@@ -142,7 +144,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else {
if (getlong(fields[4], &spwd.sp_max) == -1)
if (str2sl(&spwd.sp_max, fields[4]) == -1)
return 0;
if (spwd.sp_max < 0)
return 0;
@@ -169,7 +171,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else {
if (getlong(fields[5], &spwd.sp_warn) == -1)
if (str2sl(&spwd.sp_warn, fields[5]) == -1)
return 0;
if (spwd.sp_warn < 0)
return 0;
@@ -183,7 +185,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else {
if (getlong(fields[6], &spwd.sp_inact) == -1)
if (str2sl(&spwd.sp_inact, fields[6]) == -1)
return 0;
if (spwd.sp_inact < 0)
return 0;
@@ -197,7 +199,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else {
if (getlong(fields[7], &spwd.sp_expire) == -1)
if (str2sl(&spwd.sp_expire, fields[7]) == -1)
return 0;
if (spwd.sp_expire < 0)
return 0;
@@ -211,7 +213,7 @@ static struct spwd *my_sgetspent (const char *string)
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else {
if (getulong(fields[8], &spwd.sp_flag) == -1)
if (str2ul(&spwd.sp_flag, fields[8]) == -1)
return 0;
if (spwd.sp_flag < 0)
return 0;

View File

@@ -13,9 +13,11 @@
#ident "$Id$"
#include "atoi/str2i.h"
#include "prototypes.h"
#include "getdate.h"
/*
* strtoday() now uses get_date() (borrowed from GNU shellutils)
* which can handle many date formats, for example:
@@ -62,9 +64,8 @@ long strtoday (const char *str)
}
if (isnum) {
long retdate;
if (getlong(str, &retdate) == -1) {
if (str2sl(&retdate, str) == -1)
return -2;
}
return retdate;
}

View File

@@ -19,6 +19,7 @@
#include <string.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "string/sprintf.h"
@@ -107,9 +108,9 @@ subordinate_parse(const char *line)
if (i != SUBID_NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0')
return NULL;
range.owner = fields[0];
if (getulong(fields[1], &range.start) == -1)
if (str2ul(&range.start, fields[1]) == -1)
return NULL;
if (getulong(fields[2], &range.count) == -1)
if (str2ul(&range.count, fields[2]) == -1)
return NULL;
return &range;
@@ -1116,6 +1117,16 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
return ret;
}
void free_subid_pointer(void *ptr)
{
struct subid_nss_ops *h = get_subid_nss_handle();
if (h) {
h->free(ptr);
} else {
free(ptr);
}
}
#else /* !ENABLE_SUBIDS */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */

View File

@@ -43,6 +43,9 @@ extern int sub_gid_unlock (void);
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
extern void free_subid_pointer(void *ptr);
#endif /* ENABLE_SUBIDS */
#endif

View File

@@ -42,6 +42,11 @@ bool subid_init(const char *progname, FILE * logfd)
return true;
}
void subid_free(void *ptr)
{
free_subid_pointer(ptr);
}
static
int get_subid_ranges(const char *owner, enum subid_type id_type, struct subid_range **ranges)
{

View File

@@ -55,6 +55,19 @@ extern "C" {
*/
bool subid_init(const char *progname, FILE *logfd);
/*
* subid_free: free memory allocated in any subid_* function
*
* @ptr: Pointer to a memory block to release.
*
* Some functions like @subid_get_uid_ranges allocate memory internally. As
* soon as a result is no longer needed, it should be freed with this routine.
* Initially, default function `free()` was used. Thus for backward
* compatibility this function falls back to `free()` if a plugin does not
* explicitly specify routine to free allocated memory.
*/
void subid_free(void *ptr);
/*
* subid_get_uid_ranges: return a list of UID ranges for a user
*

View File

@@ -211,8 +211,8 @@
to hang as it processes entries with UIDs 171-799).
</para>
<para>
Having high UIDs can create problems when handling the <term><filename>
/var/log/lastlog</filename></term> with external tools. Although the
Having high UIDs can create problems when handling the <filename>
/var/log/lastlog</filename> with external tools. Although the
actual file is sparse and does not use too much space, certain
applications are not designed to identify sparse files by default and may
require a specific option to handle them.

View File

@@ -215,14 +215,6 @@
<para>Preserve environment.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-r</option>
</term>
<listitem>
<para>Perform autologin protocol for rlogin.</para>
</listitem>
</varlistentry>
</variablelist>
<para>

View File

@@ -120,8 +120,8 @@
Instead of an integer process id, the first argument may be
specified as <replaceable>fd:N</replaceable>, where the integer N
is the file descriptor number for the calling process's opened
file for <filename>/proc/[pid[</filename>. In this case,
<command>newgidmap</command> will use
file descriptor for the directory <filename>/proc/[pid]</filename>.
In this case, <command>newgidmap</command> will use
<refentrytitle>openat</refentrytitle><manvolnum>2</manvolnum>
to open the <filename>gid_map</filename> file under that
directory, avoiding a TOCTTOU in case the process exits and

View File

@@ -120,8 +120,8 @@
Instead of an integer process id, the first argument may be
specified as <replaceable>fd:N</replaceable>, where the integer N
is the file descriptor number for the calling process's opened
file for <filename>/proc/[pid[</filename>. In this case,
<command>newuidmap</command> will use
file descriptor for the directory <filename>/proc/[pid]</filename>.
In this case, <command>newuidmap</command> will use
<refentrytitle>openat</refentrytitle><manvolnum>2</manvolnum>
to open the <filename>uid_map</filename> file under that
directory, avoiding a TOCTTOU in case the process exits and

View File

@@ -9021,8 +9021,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "Brugernavne må kun være op til 32 tegn lange."
msgid "Usernames may only be up to 256 characters long."
msgstr "Brugernavne må kun være op til 256 tegn lange."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789

View File

@@ -12462,8 +12462,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "Benutzernamen dürfen nur bis zu 32 Zeichen lang sein."
msgid "Usernames may only be up to 256 characters long."
msgstr "Benutzernamen dürfen nur bis zu 256 Zeichen lang sein."
# type: Plain text
#. (itstool) path: listitem/para

View File

@@ -11888,8 +11888,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "Les noms d'utilisateur sont limités à 32 caractères."
msgid "Usernames may only be up to 256 characters long."
msgstr "Les noms d'utilisateur sont limités à 256 caractères."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789

View File

@@ -12082,8 +12082,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "I nomi utente non possono eccedere i 32 caratteri di lunghezza."
msgid "Usernames may only be up to 256 characters long."
msgstr "I nomi utente non possono eccedere i 256 caratteri di lunghezza."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789

View File

@@ -9334,7 +9334,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para

View File

@@ -12335,8 +12335,8 @@ msgstr ""
# type: Content of: <refentry><refsect1><para>
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "Имена пользователей могут быть длиной не более 32 знаков."
msgid "Usernames may only be up to 256 characters long."
msgstr "Имена пользователей могут быть длиной не более 256 знаков."
# type: Content of: <refentry><refsect1><variablelist><varlistentry><listitem><para>
#. (itstool) path: listitem/para

View File

@@ -9629,7 +9629,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para

View File

@@ -9476,7 +9476,7 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgid "Usernames may only be up to 256 characters long."
msgstr ""
#. (itstool) path: listitem/para

View File

@@ -10023,8 +10023,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "Довжина імен користувачів не може перевищувати 32 символи."
msgid "Usernames may only be up to 256 characters long."
msgstr "Довжина імен користувачів не може перевищувати 256 символи."
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789

View File

@@ -10474,8 +10474,8 @@ msgstr ""
#. (itstool) path: refsect1/para
#: useradd.8.xml.out:724
msgid "Usernames may only be up to 32 characters long."
msgstr "用户名不能超过 32 个字符长。"
msgid "Usernames may only be up to 256 characters long."
msgstr "用户名不能超过 256 个字符长。"
#. (itstool) path: listitem/para
#: useradd.8.xml.out:789

View File

@@ -727,7 +727,7 @@
the <command>ls</command> output.
</para>
<para>
Usernames may only be up to 32 characters long.
Usernames may only be up to 256 characters long.
</para>
</refsect1>

View File

@@ -25,7 +25,6 @@ lib/fputsx.c
lib/get_gid.c
lib/get_uid.c
lib/getdef.c
lib/getlong.c
lib/getgr_nam_gid.c
lib/getrange.c
lib/groupio.c
@@ -54,7 +53,6 @@ lib/pwdcheck.c
lib/pwio.c
lib/pwmem.c
lib/remove_tree.c
lib/rlogin.c
lib/root_flag.c
lib/salt.c
lib/selinux.c

202
po/nl.po
View File

@@ -1,14 +1,14 @@
# dutch po-file for shadow
# Copyright (C) 2004 Free Software Foundation, Inc.
# Bart Cornelis <cobaco@linux.be>, 2004, 2006.
# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2014-2022.
# Frans Spiesschaert <Frans.Spiesschaert@yucom.be>, 2014-2024.
#
msgid ""
msgstr ""
"Project-Id-Version: shadow 4.12.2\n"
"Project-Id-Version: shadow 4.15.1\n"
"Report-Msgid-Bugs-To: pkg-shadow-devel@lists.alioth.debian.org\n"
"POT-Creation-Date: 2024-03-14 18:23-0500\n"
"PO-Revision-Date: 2022-09-27 17:08+0200\n"
"PO-Revision-Date: 2024-05-09 12:30+0200\n"
"Last-Translator: Frans Spiesschaert <Frans.Spiesschaert@yucom.be>\n"
"Language-Team: Debian Dutch l10n Team <debian-l10n-dutch@lists.debian.org>\n"
"Language: nl\n"
@@ -237,10 +237,9 @@ msgstr "%s: Kon seteuid niet op %d instellen\n"
msgid "%s: Could not set caps\n"
msgstr "%s: Kon hoofdletters niet instellen\n"
#, fuzzy, c-format
#| msgid "%s: snprintf failed!\n"
#, c-format
msgid "%s: stpeprintf failed!\n"
msgstr "%s: snprintf is mislukt!\n"
msgstr "%s: stpeprintf is mislukt!\n"
#, c-format
msgid "%s: open of %s failed: %s\n"
@@ -250,10 +249,9 @@ msgstr "%s: openen van %s mislukte: %s\n"
msgid "%s: write to %s failed: %s\n"
msgstr "%s: schrijven naar %s mislukte: %s\n"
#, fuzzy, c-format
#| msgid "%s: open of %s failed: %s\n"
#, c-format
msgid "%s: closing %s failed: %s\n"
msgstr "%s: openen van %s mislukte: %s\n"
msgstr "%s: sluiten van %s mislukte: %s\n"
msgid "Too many logins.\n"
msgstr "Te veel aanmeldingen.\n"
@@ -375,10 +373,9 @@ msgstr "%s: krijg geen toegang tot chroot-map %s: %s\n"
msgid "%s: unable to chroot to directory %s: %s\n"
msgstr "%s: chroot naar map %s lukt niet: %s\n"
#, fuzzy, c-format
#| msgid "%s: cannot chdir to chroot directory %s: %s\n"
#, c-format
msgid "%s: cannot chdir in chroot directory %s: %s\n"
msgstr "%s: kan chdir naar chroot-map %s niet uitvoeren: %s\n"
msgstr "%s: kan chdir in chroot-map %s niet uitvoeren: %s\n"
#, c-format
msgid ""
@@ -435,10 +432,9 @@ msgstr "Kan de SELinux-transactie niet beginnen\n"
msgid "Could not query seuser for %s\n"
msgstr "Kon de seuser van %s niet opvragen\n"
#, fuzzy, c-format
#| msgid "Could not set serange for %s\n"
#, c-format
msgid "Could not set serange for %s to %s\n"
msgstr "Kon de serange van %s niet instellen\n"
msgstr "Kon de serange voor %s niet instellen op %s\n"
#, c-format
msgid "Could not set sename for %s\n"
@@ -517,7 +513,7 @@ msgstr "Kan %s niet uitvoeren"
#, c-format
msgid "Maximum subsystem depth reached\n"
msgstr ""
msgstr "Maximale diepte van het subsysteem bereikt\n"
#, c-format
msgid "Invalid root directory '%s'\n"
@@ -680,8 +676,6 @@ msgstr ""
msgid " -R, --root CHROOT_DIR directory to chroot into\n"
msgstr " -R, --root CHROOT_MAP basismap voor chroot\n"
#, fuzzy
#| msgid " -P, --prefix PREFIX_DI directory prefix\n"
msgid " -P, --prefix PREFIX_DIR directory prefix\n"
msgstr " -P, --prefix PREFIX_MAP map-prefix\n"
@@ -716,7 +710,7 @@ msgid "never"
msgstr "nooit"
msgid "future"
msgstr ""
msgstr "toekomst"
msgid "Last password change\t\t\t\t\t: "
msgstr "Laatste wachtwoordverandering\t\t\t\t: "
@@ -943,10 +937,9 @@ msgstr ""
" -s, --sha-rounds aantal rondes voor de SHA, BCRYPT\n"
" of YESCRYPT encryptie-algoritmes\n"
#, fuzzy, c-format
#| msgid "%s: unsupported crypt method: %s\n"
#, c-format
msgid "%s: no crypt method defined\n"
msgstr "%s: niet-ondersteunde encryptiemethode: %s\n"
msgstr "%s: geen encryptiemethode gedefinieerd\n"
#, c-format
msgid "%s: %s flag is only allowed with the %s flag\n"
@@ -1001,15 +994,13 @@ msgstr ""
msgid "Login Shell"
msgstr "Login-shell"
#, fuzzy, c-format
#| msgid "%s: Cannot get the size of %s: %s\n"
#, c-format
msgid "Cannot parse shell files: %s"
msgstr "%s: kan grootte van %s niet opvragen: %s\n"
msgstr "Kan shell-bestanden niet ontleden: %s"
#, fuzzy, c-format
#| msgid "%s: cannot create new defaults file: %s\n"
#, c-format
msgid "Cannot evaluate entries in shell files: %s"
msgstr "%s: kan geen nieuw bestand met standaardwaarden aanmaken: %s\n"
msgstr "Kan items in shell-bestanden niet evalueren: %s"
#, c-format
msgid "You may not change the shell for '%s'.\n"
@@ -1023,10 +1014,9 @@ msgstr "De login-shell voor %s wordt aangepast\n"
msgid "%s: Invalid entry: %s\n"
msgstr "%s: ongeldig element: %s\n"
#, fuzzy, c-format
#| msgid "%s: %s is an invalid shell\n"
#, c-format
msgid "%s: Warning: %s is an invalid shell\n"
msgstr "%s: %s is geen geldige shell\n"
msgstr "%s: Waarschuwing: %s is geen geldige shell\n"
#, c-format
msgid "%s: %s is an invalid shell\n"
@@ -1286,10 +1276,9 @@ msgstr "Ongeldige lid-gebruikersnaam %s\n"
msgid "%s: '%s' is not a valid group name\n"
msgstr "%s: '%s' is geen geldige groepsnaam\n"
#, fuzzy, c-format
#| msgid "%s: Cannot open %s: %s\n"
#, c-format
msgid "%s: cannot open %s: %s\n"
msgstr "%s: kan bestand %s niet openen: %s\n"
msgstr "%s: kan %s niet openen: %s\n"
#, c-format
msgid "%s: invalid group ID '%s'\n"
@@ -1566,10 +1555,6 @@ msgid ""
msgstr ""
" -b, --before DAGEN enkel lastlog-items ouder dan DAGEN tonen\n"
#, fuzzy
#| msgid ""
#| " -C, --clear clear lastlog record of an user (usable "
#| "only with -u)\n"
msgid ""
" -C, --clear clear lastlog record of a user (usable only "
"with -u)\n"
@@ -1742,15 +1727,12 @@ msgstr "Gebruik: logoutd\n"
msgid "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: gid-bereik [%lu-%lu) -> [%lu-%lu) niet toegestaan\n"
#, fuzzy, c-format
#| msgid ""
#| "usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> "
#| "<count> ] ... \n"
#, c-format
msgid ""
"usage: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> "
"<count> ] ... \n"
msgstr ""
"gebruik: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> "
"gebruik: %s [<pid|fd:<pidfd>] <gid> <lowergid> <count> [ <gid> <lowergid> "
"<count> ] ... \n"
#, c-format
@@ -1773,21 +1755,17 @@ msgstr "%s: setgroups opzoeken mislukte: %s\n"
msgid "%s: failed to setgroups %s policy: %s\n"
msgstr "%s: setgroups-beleid %s mislukte: %s\n"
#, fuzzy, c-format
#| msgid "%s: Could not stat directory for target %u\n"
#, c-format
msgid "%s: Could not stat directory for process\n"
msgstr "%s: Kon status van map voor doel %u niet opvragen\n"
msgstr "%s: Kon status van map voor proces niet opvragen\n"
#, fuzzy, c-format
#| msgid ""
#| "%s: Target process %u is owned by a different user: uid:%lu pw_uid:%lu "
#| "st_uid:%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
#, c-format
msgid ""
"%s: Target process is owned by a different user: uid:%lu pw_uid:%lu st_uid:"
"%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
msgstr ""
"%s: Doelproces %u is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:"
"%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
"%s: Doelproces is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:%lu, "
"gid:%lu pw_gid:%lu st_gid:%lu\n"
msgid "Usage: newgrp [-] [group]\n"
msgstr "Gebruik: newgrp [-] [groep]\n"
@@ -1819,21 +1797,17 @@ msgstr "te veel groepen\n"
msgid "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"
msgstr "%s: uid-bereik [%lu-%lu) -> [%lu-%lu) niet toegestaan\n"
#, fuzzy, c-format
#| msgid ""
#| "usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> "
#| "<count> ] ... \n"
#, c-format
msgid ""
"usage: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> "
"<count> ] ... \n"
msgstr ""
"gebruik: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> "
"gebruik: %s [<pid>|fd:<pidfd>] <uid> <loweruid> <count> [ <uid> <loweruid> "
"<count> ] ... \n"
#, fuzzy, c-format
#| msgid "%s: Could not stat directory for target %u\n"
#, c-format
msgid "%s: Could not stat directory for target process\n"
msgstr "%s: Kon status van map voor doel %u niet opvragen\n"
msgstr "%s: Kon status van map voor doelproces niet opvragen\n"
msgid " -b, --badname allow bad names\n"
msgstr " -b, --badname slechte namen toestaan\n"
@@ -1855,7 +1829,7 @@ msgstr "%s: ongeldige gebruikersnaam '%s': gebruik --badname om te negeren\n"
#, c-format
msgid "%s: Provide '--crypt-method' before number of rounds\n"
msgstr ""
msgstr "%s: Geef '--crypt-method' op vóór het aantal rondes\n"
#, c-format
msgid "%s: line %d: invalid line\n"
@@ -1879,10 +1853,9 @@ msgstr "%s: regel %d: kan de groep niet aanmaken\n"
msgid "%s: line %d: user '%s' does not exist in %s\n"
msgstr "%s: regel %d: gebruiker '%s' bestaat niet in %s\n"
#, fuzzy, c-format
#| msgid "%s: unlink: %s: %s\n"
#, c-format
msgid "%s: line %d: %s\n"
msgstr "%s: ontkoppelen: %s: %s\n"
msgstr "%s: regel: %d: %s\n"
#, c-format
msgid "%s: line %d: can't update password\n"
@@ -1992,11 +1965,9 @@ msgstr ""
"wachtwoordwijziging\n"
" instellen op MAX_DAGEN\n"
#, fuzzy
#| msgid " -l, --list show account aging information\n"
msgid " -s, --stdin read new token from stdin\n"
msgstr ""
" -l, --list verouderingsinformatie over accounts tonen\n"
msgstr " -s, --stdin nieuw token lezen van stdin\n"
msgid "Old password: "
msgstr "Oud wachtwoord: "
@@ -2017,10 +1988,8 @@ msgstr ""
"Voer het nieuwe wachtwoord in (minimaal %d en maximaal %d tekens)\n"
"Gebruik een combinatie van grote en kleine letters en cijfers.\n"
#, fuzzy
#| msgid "%s: fields too long\n"
msgid "Password is too long.\n"
msgstr "%s: velden zijn te lang\n"
msgstr "Wachtwoord is te lang.\n"
msgid "New password: "
msgstr "Nieuw wachtwoord: "
@@ -2067,10 +2036,9 @@ msgstr ""
msgid "%s: repository %s not supported\n"
msgstr "%s: depot %s wordt niet ondersteund\n"
#, fuzzy, c-format
#| msgid "%s: only root can use the -g/--group option\n"
#, c-format
msgid "%s: only root can use --stdin/-s option\n"
msgstr "%s: enkel de systeembeheerder kan de optie -g/--group gebruiken\n"
msgstr "%s: enkel de systeembeheerder kan de optie --stdin/-s gebruiken\n"
#, c-format
msgid "%s: root is not authorized by SELinux to change the password of %s\n"
@@ -2301,10 +2269,9 @@ msgstr "%s: U bent niet gerechtigd om op dat tijdstip 'su' uit te voeren\n"
msgid "No passwd entry for user '%s'\n"
msgstr "Geen wachtwoordregel voor gebruiker '%s'\n"
#, fuzzy, c-format
#| msgid "Invalid member username %s\n"
#, c-format
msgid "Overlong user name '%s'\n"
msgstr "Ongeldige lid-gebruikersnaam %s\n"
msgstr "Te lange gebruikersnaam '%s'\n"
#, c-format
msgid "%s: must be run from a terminal\n"
@@ -2351,12 +2318,13 @@ msgstr "%s: %s was aangemaakt, maar kon niet verwijderd worden\n"
msgid "%s: the %s configuration in %s will be ignored\n"
msgstr "%s: de %s-instellingen in %s zullen genegeerd worden\n"
#, fuzzy, c-format
#| msgid "%s: the %s configuration in %s will be ignored\n"
#, c-format
msgid ""
"%s: the '%s' configuration in %s has an invalid group, ignoring the bad "
"group\n"
msgstr "%s: de %s-instellingen in %s zullen genegeerd worden\n"
msgstr ""
"%s: de configuratie van '%s' in %s heeft een ongeldige groep, deze groep "
"wordt genegeerd\n"
#, c-format
msgid "%s: cannot create new defaults file: %s\n"
@@ -2458,6 +2426,8 @@ msgid ""
" -F, --add-subids-for-system add entries to sub[ud]id even when adding a "
"system user\n"
msgstr ""
" -F, --add-subids-for-system items toevoegen aan sub[ud]id, zelfs bij het "
"toevoegen van een systeemgebruiker\n"
msgid ""
" -g, --gid GROUP name or ID of the primary group of the new\n"
@@ -2537,15 +2507,11 @@ msgstr ""
" -Z, --selinux-user SEUSER een specifieke SEUSER gebruiken om de\n"
" gebruikerskoppeling voor SELinux te maken\n"
#, fuzzy
#| msgid ""
#| " -Z, --selinux-user SEUSER use a specific SEUSER for the SELinux "
#| "user mapping\n"
msgid ""
" --selinux-range SERANGE use a specific MLS range for the SELinux "
"user mapping\n"
msgstr ""
" -Z, --selinux-user SEUSER een specifieke SEUSER gebruiken om de\n"
" --selinux-range SERANGE een specifiek MLS-bereik gebruiken om de\n"
" gebruikerskoppeling voor SELinux te maken\n"
#, c-format
@@ -2680,15 +2646,11 @@ msgstr ""
msgid "Setting mailbox file permissions"
msgstr "Bestandsrechten van postvak-bestand worden ingesteld"
#, fuzzy
#| msgid "Creating mailbox file"
msgid "Synchronize mailbox file"
msgstr "Postvak-bestand wordt aangemaakt"
msgstr "Postvak-bestand synchroniseren"
#, fuzzy
#| msgid "Creating mailbox file"
msgid "Closing mailbox file"
msgstr "Postvak-bestand wordt aangemaakt"
msgstr "Postvak-bestand wordt gesloten"
#, c-format
msgid "%s warning: %s's uid %d is greater than SYS_UID_MAX %d\n"
@@ -2954,14 +2916,10 @@ msgstr ""
" -Z, --selinux-user SEUSER nieuwe koppeling met SELinux-gebruiker voor\n"
" het gebruikersaccount\n"
#, fuzzy
#| msgid ""
#| " -Z, --selinux-user SEUSER new SELinux user mapping for the user "
#| "account\n"
msgid ""
" --selinux-range SERANGE new SELinux MLS range for the user account\n"
msgstr ""
" -Z, --selinux-user SEUSER nieuwe koppeling met SELinux-gebruiker voor\n"
" --selinux-range SERANGE nieuw SELinux MLS-bereik voor\n"
" het gebruikersaccount\n"
#, c-format
@@ -3045,16 +3003,13 @@ msgstr ""
msgid "%s: cannot rename directory %s to %s\n"
msgstr "%s: kan map %s niet hernoemen naar %s\n"
#, fuzzy, c-format
#| msgid ""
#| "%s: The previous home directory (%s) was not a directory. It is not "
#| "removed and no home directories are created.\n"
#, c-format
msgid ""
"%s: The previous home directory (%s) does not exist or is inaccessible. Move "
"cannot be completed.\n"
msgstr ""
"%s: De vroegere persoonlijke map (%s) was geen map. Ze werd niet verwijderd "
"en er werden geen persoonlijke mappen aangemaakt.\n"
"%s: De vroegere persoonlijke map (%s) bestaat niet of is ontoegankelijk. Het "
"verplaatsen kan niet worden voltooid.\n"
#, c-format
msgid "%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"
@@ -3062,11 +3017,10 @@ msgstr ""
"%s: kopiëren van het lastlog-item van gebruiker %lu naar gebruiker %lu is "
"mislukt: %s\n"
#, fuzzy, c-format
#| msgid "%s: failed to copy the lastlog entry of user %lu to user %lu: %s\n"
#, c-format
msgid "%s: failed to copy the lastlog entry of user %ju to user %ju: %s\n"
msgstr ""
"%s: kopiëren van het lastlog-item van gebruiker %lu naar gebruiker %lu is "
"%s: kopiëren van het lastlog-item van gebruiker %ju naar gebruiker %ju is "
"mislukt: %s\n"
#, c-format
@@ -3075,11 +3029,10 @@ msgstr ""
"%s: kopiëren van het faillog-item van gebruiker %lu naar gebruiker %lu is "
"mislukt: %s\n"
#, fuzzy, c-format
#| msgid "%s: failed to copy the faillog entry of user %lu to user %lu: %s\n"
#, c-format
msgid "%s: failed to copy the faillog entry of user %ju to user %ju: %s\n"
msgstr ""
"%s: kopiëren van het faillog-item van gebruiker %lu naar gebruiker %lu is "
"%s: kopiëren van het faillog-item van gebruiker %ju naar gebruiker %ju is "
"mislukt: %s\n"
#, c-format
@@ -3183,10 +3136,8 @@ msgstr "ontkoppelen van initieel bestand is mislukt"
msgid "failed to stat edited file"
msgstr "opvragen van status van bewerkt bestand is mislukt"
#, fuzzy
#| msgid "%s: snprintf failed!\n"
msgid "asprintf(3) failed"
msgstr "%s: snprintf is mislukt!\n"
msgstr "asprintf(3) is mislukt"
msgid "failed to create backup file"
msgstr "maken van reservekopie is mislukt"
@@ -3198,34 +3149,3 @@ msgstr "%s: kan %s niet herstellen: %s (uw aanpassingen staan in %s)\n"
#, c-format
msgid "%s: failed to find tcb directory for %s\n"
msgstr "%s: tcb-map van %s vinden is mislukt\n"
#, c-format
#~ msgid "%s: Not enough arguments to form %u mappings\n"
#~ msgstr "%s: Onvoldoende argumenten om %u-toewijzingen te vormen\n"
#~ msgid "too simple"
#~ msgstr "te simpel"
#, c-format
#~ msgid "Unable to obtain random bytes.\n"
#~ msgstr "Kan geen willekeurige bytes verkrijgen.\n"
#~ msgid "No utmp entry. You must exec \"login\" from the lowest level \"sh\""
#~ msgstr ""
#~ "Er is geen utmp-item. U dient \"login\" uit te voeren vanaf het laagste "
#~ "niveau \"sh\""
#, c-format
#~ msgid "%s: Could not open proc directory for target %u\n"
#~ msgstr "%s: Kon proc-map voor doel %u niet openen\n"
#, c-format
#~ msgid ""
#~ "%s: Target %u is owned by a different user: uid:%lu pw_uid:%lu st_uid:"
#~ "%lu, gid:%lu pw_gid:%lu st_gid:%lu\n"
#~ msgstr ""
#~ "%s: Doel %u is van een andere gebruiker: uid:%lu pw_uid:%lu st_uid:%lu, "
#~ "gid:%lu pw_gid:%lu st_gid:%lu\n"
#~ msgid "failed to allocate memory"
#~ msgstr "geheugen toekennen is mislukt"

View File

@@ -12,19 +12,22 @@ COPY ./ /usr/local/src/shadow/
WORKDIR /usr/local/src/shadow/
RUN ./autogen.sh \
--enable-shadowgrp \
--enable-man \
--with-audit \
--with-sha-crypt \
--with-bcrypt \
--with-yescrypt \
--with-selinux \
--without-libpam \
--enable-shared \
--without-libbsd \
--with-group-name-max-length=32 \
--disable-account-tools-setuid \
--enable-lastlog \
--enable-logind=no
--enable-logind=no \
--enable-man \
--enable-shadowgrp \
--enable-shared \
--with-audit \
--with-bcrypt \
--with-group-name-max-length=32 \
--with-libpam \
--with-selinux \
--with-sha-crypt \
--with-yescrypt \
--without-libbsd \
--without-libcrack \
--without-sssd
RUN make -Orecurse -j4
RUN bash -c "trap 'cat <tests/unit/test-suite.log >&2' ERR; make check;"
RUN make install

View File

@@ -27,6 +27,7 @@
#include <pwd.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "defines.h"
#include "memzero.h"
#include "prototypes.h"
@@ -170,14 +171,14 @@ static int new_fields (void)
SNPRINTF(buf, "%ld", mindays);
change_field (buf, sizeof buf, _("Minimum Password Age"));
if ( (getlong(buf, &mindays) == -1)
if ( (str2sl(&mindays, buf) == -1)
|| (mindays < -1)) {
return 0;
}
SNPRINTF(buf, "%ld", maxdays);
change_field (buf, sizeof buf, _("Maximum Password Age"));
if ( (getlong(buf, &maxdays) == -1)
if ( (str2sl(&maxdays, buf) == -1)
|| (maxdays < -1)) {
return 0;
}
@@ -200,14 +201,14 @@ static int new_fields (void)
SNPRINTF(buf, "%ld", warndays);
change_field (buf, sizeof buf, _("Password Expiration Warning"));
if ( (getlong(buf, &warndays) == -1)
if ( (str2sl(&warndays, buf) == -1)
|| (warndays < -1)) {
return 0;
}
SNPRINTF(buf, "%ld", inactdays);
change_field (buf, sizeof buf, _("Password Inactive"));
if ( (getlong(buf, &inactdays) == -1)
if ( (str2sl(&inactdays, buf) == -1)
|| (inactdays < -1)) {
return 0;
}
@@ -396,7 +397,7 @@ static void process_flags (int argc, char **argv)
break;
case 'I':
Iflg = true;
if ( (getlong(optarg, &inactdays) == -1)
if ( (str2sl(&inactdays, optarg) == -1)
|| (inactdays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -409,7 +410,7 @@ static void process_flags (int argc, char **argv)
break;
case 'm':
mflg = true;
if ( (getlong(optarg, &mindays) == -1)
if ( (str2sl(&mindays, optarg) == -1)
|| (mindays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -419,7 +420,7 @@ static void process_flags (int argc, char **argv)
break;
case 'M':
Mflg = true;
if ( (getlong(optarg, &maxdays) == -1)
if ( (str2sl(&maxdays, optarg) == -1)
|| (maxdays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -433,7 +434,7 @@ static void process_flags (int argc, char **argv)
break;
case 'W':
Wflg = true;
if ( (getlong(optarg, &warndays) == -1)
if ( (str2sl(&warndays, optarg) == -1)
|| (warndays < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),

View File

@@ -13,7 +13,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include "atoi/strtou_noneg.h"
#include "atoi/str2i.h"
#include "defines.h"
#include "prototypes.h"
#include "subordinateio.h"
@@ -36,11 +36,9 @@ int main(int argc, char **argv)
owner = argv[1];
check_uids = argv[2][0] == 'u';
errno = 0;
start = strtoul_noneg(argv[3], NULL, 10);
if (errno != 0)
if (str2ul(&start, argv[3]) == -1)
exit(1);
count = strtoul_noneg(argv[4], NULL, 10);
if (errno != 0)
if (str2ul(&count, argv[4]) == -1)
exit(1);
if (check_uids) {
if (have_sub_uids(owner, start, count))

View File

@@ -16,11 +16,13 @@
#include <pwd.h>
#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/str2i.h"
#include "defines.h"
#include "nscd.h"
#include "sssd.h"
@@ -33,6 +35,7 @@
#include "exitcodes.h"
#include "shadowlog.h"
/*
* Global variables
*/
@@ -195,19 +198,19 @@ static void process_flags (int argc, char **argv)
}
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (-1 == getlong(optarg, &sha_rounds)))) {
&& (-1 == str2sl(&sha_rounds, optarg)))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (-1 == getlong(optarg, &bcrypt_rounds)))) {
&& (-1 == str2sl(&bcrypt_rounds, optarg)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (-1 == getlong(optarg, &yescrypt_cost)))) {
&& (-1 == str2sl(&yescrypt_cost, optarg)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */

View File

@@ -16,9 +16,11 @@
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef USE_PAM
#include "pam_defs.h"
#endif /* USE_PAM */
#include "atoi/str2i.h"
#include "defines.h"
#include "nscd.h"
#include "sssd.h"
@@ -30,6 +32,7 @@
#include "exitcodes.h"
#include "shadowlog.h"
#define IS_CRYPT_METHOD(str) ((crypt_method != NULL && strcmp(crypt_method, str) == 0) ? true : false)
/*
@@ -190,19 +193,19 @@ static void process_flags (int argc, char **argv)
bad_s = 0;
#if defined(USE_SHA_CRYPT)
if ((IS_CRYPT_METHOD("SHA256") || IS_CRYPT_METHOD("SHA512"))
&& (-1 == getlong(optarg, &sha_rounds))) {
&& (-1 == str2sl(&sha_rounds, optarg))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (IS_CRYPT_METHOD("BCRYPT")
&& (-1 == getlong(optarg, &bcrypt_rounds))) {
&& (-1 == str2sl(&bcrypt_rounds, optarg))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (IS_CRYPT_METHOD("YESCRYPT")
&& (-1 == getlong(optarg, &yescrypt_cost))) {
&& (-1 == str2sl(&yescrypt_cost, optarg))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */

View File

@@ -19,6 +19,7 @@
#include <time.h>
#include <assert.h>
#include "atoi/str2i.h"
#include "defines.h"
#include "faillog.h"
#include "memzero.h"
@@ -29,6 +30,7 @@
#include "string/strftime.h"
/* local function prototypes */
NORETURN static void usage (int status);
static void print_one (/*@null@*/const struct passwd *pw, bool force);
@@ -545,7 +547,7 @@ int main (int argc, char **argv)
usage (E_SUCCESS);
/*@notreached@*/break;
case 'l':
if (getlong(optarg, &fail_locktime) == -1) {
if (str2sl(&fail_locktime, optarg) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -557,7 +559,7 @@ int main (int argc, char **argv)
{
long lmax;
if ( (getlong(optarg, &lmax) == -1)
if ( (str2sl(&lmax, optarg) == -1)
|| ((long)(short) lmax != lmax)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -574,7 +576,7 @@ int main (int argc, char **argv)
case 'R': /* no-op, handled in process_root_flag () */
break;
case 't':
if (getlong(optarg, &days) == -1) {
if (str2sl(&days, optarg) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);

View File

@@ -44,5 +44,6 @@ int main(int argc, char *argv[])
printf("%d: %s %lu %lu\n", i, owner,
ranges[i].start, ranges[i].count);
}
subid_free(ranges);
return 0;
}

View File

@@ -250,8 +250,6 @@ static void grp_update (void)
if (!aflg) {
// requested to replace the existing groups
if (NULL != grp.gr_mem[0])
gr_free_members(&grp);
grp.gr_mem = XMALLOC(1, char *);
grp.gr_mem[0] = NULL;
} else {

View File

@@ -23,6 +23,7 @@
#include <net/if.h>
#endif
#include "atoi/str2i.h"
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
@@ -33,6 +34,7 @@
#include "string/strftime.h"
/*
* Needed for MkLinux DR1/2/2.1 - J.
*/
@@ -326,7 +328,7 @@ int main (int argc, char **argv)
case 'b':
{
unsigned long inverse_days;
if (getulong(optarg, &inverse_days) == -1) {
if (str2ul(&inverse_days, optarg) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);
@@ -354,7 +356,7 @@ int main (int argc, char **argv)
case 't':
{
unsigned long days;
if (getulong(optarg, &days) == -1) {
if (str2ul(&days, optarg) == -1) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
Prog, optarg);

View File

@@ -27,6 +27,7 @@
#include "alloc.h"
#include "attr.h"
#include "chkname.h"
#include "defines.h"
#include "faillog.h"
#include "failure.h"
@@ -84,11 +85,6 @@ static struct lastlog ll;
static bool pflg = false;
static bool fflg = false;
#ifdef RLOGIN
static bool rflg = false;
#else /* RLOGIN */
#define rflg false
#endif /* !RLOGIN */
static bool hflg = false;
static bool preauth_flag = false;
@@ -133,7 +129,6 @@ static void exit_handler (int);
* usage - print login command usage and exit
*
* login [ name ]
* login -r hostname (for rlogind)
* login -h hostname (for telnetd, etc.)
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
*/
@@ -144,9 +139,6 @@ static void usage (void)
exit (1);
}
fprintf (stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
#ifdef RLOGIN
fprintf (stderr, _(" %s [-p] -r host\n"), Prog);
#endif /* RLOGIN */
exit (1);
}
@@ -270,7 +262,7 @@ static void process_flags (int argc, char *const *argv)
/*
* Check the flags for proper form. Every argument starting with
* "-" must be exactly two characters long. This closes all the
* clever rlogin, telnet, and getty holes.
* clever telnet, and getty holes.
*/
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] == '-' && strlen (argv[arg]) > 2) {
@@ -297,13 +289,6 @@ static void process_flags (int argc, char *const *argv)
hostname = optarg;
reason = PW_TELNET;
break;
#ifdef RLOGIN
case 'r':
rflg = true;
hostname = optarg;
reason = PW_RLOGIN;
break;
#endif /* RLOGIN */
case 'p':
pflg = true;
break;
@@ -312,21 +297,11 @@ static void process_flags (int argc, char *const *argv)
}
}
#ifdef RLOGIN
/*
* Neither -h nor -f should be combined with -r.
*/
if (rflg && (hflg || fflg)) {
usage ();
}
#endif /* RLOGIN */
/*
* Allow authentication bypass only if real UID is zero.
*/
if ((rflg || fflg || hflg) && !amroot) {
if ((fflg || hflg) && !amroot) {
fprintf (stderr, _("%s: Permission denied.\n"), Prog);
exit (1);
}
@@ -341,11 +316,6 @@ static void process_flags (int argc, char *const *argv)
++optind;
}
#ifdef RLOGIN
if (rflg && (NULL != username)) {
usage ();
}
#endif /* RLOGIN */
if (fflg && (NULL == username)) {
usage ();
}
@@ -473,7 +443,6 @@ static /*@observer@*/const char *get_failent_user (/*@returned@*/const char *use
* the flags which login supports are
*
* -p - preserve the environment
* -r - perform autologin protocol for rlogin
* -f - do not perform authentication, user is preauthenticated
* -h - the name of the remote host
*/
@@ -504,9 +473,6 @@ int main (int argc, char **argv)
# if defined(ENABLE_LASTLOG)
char ptime[80];
# endif
#endif
#if defined(RLOGIN)
char term[128] = "";
#endif
/*
@@ -558,7 +524,7 @@ int main (int argc, char **argv)
is_console = console (tty);
#endif
if (rflg || hflg) {
if (hflg) {
/*
* Add remote hostname to the environment. I think
* (not sure) I saw it once on Irix. --marekm
@@ -571,22 +537,6 @@ int main (int argc, char **argv)
if (hflg) {
reason = PW_RLOGIN;
}
#ifdef RLOGIN
if (rflg) {
size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
assert (NULL == username);
username = XMALLOC(max_size, char);
username[max_size - 1] = '\0';
if (do_rlogin(hostname, username, max_size, term, sizeof(term)))
{
preauth_flag = true;
} else {
free (username);
username = NULL;
}
}
#endif /* RLOGIN */
OPENLOG (Prog);
@@ -621,18 +571,11 @@ int main (int argc, char **argv)
}
}
#ifdef RLOGIN
if (term[0] != '\0') {
addenv ("TERM", term);
} else
#endif /* RLOGIN */
{
/* preserve TERM from getty */
if (!pflg) {
tmp = getenv ("TERM");
if (NULL != tmp) {
addenv ("TERM", tmp);
}
/* preserve TERM from getty */
if (!pflg) {
tmp = getenv ("TERM");
if (NULL != tmp) {
addenv ("TERM", tmp);
}
}
@@ -642,7 +585,7 @@ int main (int argc, char **argv)
set_env (argc - optind, &argv[optind]);
}
if (rflg || hflg) {
if (hflg) {
cp = hostname;
} else if ((host != NULL) && (host[0] != '\0')) {
cp = host;
@@ -882,8 +825,9 @@ int main (int argc, char **argv)
failed = false; /* haven't failed authentication yet */
if (NULL == username) { /* need to get a login id */
size_t max_size = sysconf(_SC_LOGIN_NAME_MAX);
size_t max_size;
max_size = login_name_max_size();
if (subroot) {
closelog ();
exit (1);
@@ -951,7 +895,7 @@ int main (int argc, char **argv)
}
/*
* The -r and -f flags provide a name which has already
* The -f flag provides a name which has already
* been authenticated by some server.
*/
if (preauth_flag) {
@@ -1040,8 +984,8 @@ int main (int argc, char **argv)
(void) puts (_("Login incorrect"));
/* allow only one attempt with -r or -f */
if (rflg || fflg || (retries <= 0)) {
/* allow only one attempt with -f */
if (fflg || (retries <= 0)) {
closelog ();
exit (1);
}

View File

@@ -31,6 +31,7 @@
#include <string.h>
#include "alloc.h"
#include "atoi/str2i.h"
#ifdef ACCT_TOOLS_SETUID
#ifdef USE_PAM
#include "pam_defs.h"
@@ -673,19 +674,19 @@ static void process_flags (int argc, char **argv)
}
#if defined(USE_SHA_CRYPT)
if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512")))
&& (-1 == getlong(optarg, &sha_rounds)))) {
&& (-1 == str2sl(&sha_rounds, optarg)))) {
bad_s = 1;
}
#endif /* USE_SHA_CRYPT */
#if defined(USE_BCRYPT)
if (( (0 == strcmp (crypt_method, "BCRYPT"))
&& (-1 == getlong(optarg, &bcrypt_rounds)))) {
&& (-1 == str2sl(&bcrypt_rounds, optarg)))) {
bad_s = 1;
}
#endif /* USE_BCRYPT */
#if defined(USE_YESCRYPT)
if (( (0 == strcmp (crypt_method, "YESCRYPT"))
&& (-1 == getlong(optarg, &yescrypt_cost)))) {
&& (-1 == str2sl(&yescrypt_cost, optarg)))) {
bad_s = 1;
}
#endif /* USE_YESCRYPT */

View File

@@ -22,6 +22,7 @@
#include "agetpass.h"
#include "alloc.h"
#include "atoi/str2i.h"
#include "defines.h"
#include "getdef.h"
#include "memzero.h"
@@ -36,6 +37,7 @@
#include "time/day_to_str.h"
/*
* exit status values
*/
@@ -799,7 +801,7 @@ int main (int argc, char **argv)
usage (E_SUCCESS);
/*@notreached@*/break;
case 'i':
if ( (getlong(optarg, &inact) == -1)
if ( (str2sl(&inact, optarg) == -1)
|| (inact < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -818,7 +820,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'n':
if ( (getlong(optarg, &age_min) == -1)
if ( (str2sl(&age_min, optarg) == -1)
|| (age_min < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -853,7 +855,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'w':
if ( (getlong(optarg, &warn) == -1)
if ( (str2sl(&warn, optarg) == -1)
|| (warn < -1)) {
(void) fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -864,7 +866,7 @@ int main (int argc, char **argv)
anyflag = true;
break;
case 'x':
if ( (getlong(optarg, &age_max) == -1)
if ( (str2sl(&age_max, optarg) == -1)
|| (age_max < -1)) {
(void) fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),

View File

@@ -37,6 +37,7 @@
#include <unistd.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "chkname.h"
#include "defines.h"
#include "faillog.h"
@@ -237,6 +238,9 @@ static void create_home (void);
static void create_mail (void);
static void check_uid_range(int rflg, uid_t user_id);
static FILE *fmkstemp(char *template);
/*
* fail_exit - undo as much as possible
*/
@@ -415,7 +419,7 @@ static void get_defaults (void)
* Default Password Inactive value
*/
else if (MATCH (buf, DINACT)) {
if ( (getlong(ccp, &def_inactive) == -1)
if ( (str2sl(&def_inactive, ccp) == -1)
|| (def_inactive < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -523,7 +527,6 @@ static void show_defaults (void)
*/
static int set_defaults (void)
{
int ofd;
int ret = -1;
bool out_group = false;
bool out_groups = false;
@@ -557,7 +560,7 @@ static int set_defaults (void)
fprintf(stderr,
_("%s: cannot create new defaults file: %s\n"),
Prog, strerror(errno));
goto setdef_err;
goto err_free_new;
}
}
@@ -566,36 +569,27 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: cannot create directory for defaults file\n"),
Prog);
goto setdef_err;
goto err_free_def;
}
ret = mkdir(dirname(new_file_dup), 0755);
free(new_file_dup);
if (-1 == ret && EEXIST != errno) {
fprintf (stderr,
_("%s: cannot create directory for defaults file\n"),
Prog);
free(new_file_dup);
goto setdef_err;
goto err_free_def;
}
free(new_file_dup);
/*
* Create a temporary file to copy the new output to.
*/
ofd = mkstemp (new_file);
if (-1 == ofd) {
fprintf (stderr,
_("%s: cannot create new defaults file\n"),
Prog);
goto setdef_err;
}
ofp = fdopen (ofd, "w");
ofp = fmkstemp(new_file);
if (NULL == ofp) {
fprintf (stderr,
_("%s: cannot open new defaults file\n"),
Prog);
goto setdef_err;
goto err_free_def;
}
/*
@@ -621,8 +615,9 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: line too long in %s: %s..."),
Prog, default_file, buf);
(void) fclose (ifp);
goto setdef_err;
fclose(ifp);
fclose(ofp);
goto err_free_def;
}
}
@@ -701,9 +696,10 @@ static int set_defaults (void)
(void) fflush (ofp);
if ( (ferror (ofp) != 0)
|| (fsync (fileno (ofp)) != 0)
|| (fclose (ofp) != 0)) {
|| (fclose (ofp) != 0))
{
unlink (new_file);
goto setdef_err;
goto err_free_def;
}
/*
@@ -717,7 +713,7 @@ static int set_defaults (void)
_("%s: Cannot create backup file (%s): %s\n"),
Prog, buf, strerror (err));
unlink (new_file);
goto setdef_err;
goto err_free_def;
}
/*
@@ -728,7 +724,7 @@ static int set_defaults (void)
fprintf (stderr,
_("%s: rename: %s: %s\n"),
Prog, new_file, strerror (err));
goto setdef_err;
goto err_free_def;
}
#ifdef WITH_AUDIT
audit_logger (AUDIT_USYS_CONFIG, Prog,
@@ -743,11 +739,12 @@ static int set_defaults (void)
def_inactive, def_expire, def_template,
def_create_mail_spool, def_log_init));
ret = 0;
setdef_err:
free(new_file);
if (prefix[0]) {
err_free_def:
if (prefix[0])
free(default_file);
}
err_free_new:
free(new_file);
return ret;
}
@@ -856,14 +853,14 @@ static int get_groups (char *list)
*/
static struct group * get_local_group(char * grp_name)
{
char *end;
const struct group *grp;
struct group *result_grp = NULL;
long long gid;
char *endptr;
gid = strtoll (grp_name, &endptr, 10);
gid = strtoll(grp_name, &end, 10);
if ( ('\0' != *grp_name)
&& ('\0' == *endptr)
&& ('\0' == *end)
&& (ERANGE != errno)
&& (gid == (gid_t)gid)) {
grp = gr_locate_gid (gid);
@@ -1301,7 +1298,7 @@ static void process_flags (int argc, char **argv)
eflg = true;
break;
case 'f':
if ( (getlong(optarg, &def_inactive) == -1)
if ( (str2sl(&def_inactive, optarg) == -1)
|| (def_inactive < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),
@@ -2750,3 +2747,23 @@ int main (int argc, char **argv)
return E_SUCCESS;
}
static FILE *
fmkstemp(char *template)
{
int fd;
FILE *fp;
fd = mkstemp(template);
if (fd == -1)
return NULL;
fp = fdopen(fd, "w");
if (fp == NULL) {
close(fd);
unlink(template);
return NULL;
}
return fp;
}

View File

@@ -33,6 +33,7 @@
#include <time.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "chkname.h"
#include "defines.h"
#include "faillog.h"
@@ -177,10 +178,12 @@ NORETURN static void usage (int status);
static void new_pwent (struct passwd *);
static void new_spent (struct spwd *);
NORETURN static void fail_exit (int);
static void update_group (void);
static void update_group_file(void);
static void update_group(const struct group *grp);
#ifdef SHADOWGRP
static void update_gshadow (void);
static void update_gshadow_file(void);
static void update_gshadow(const struct sgrp *sgrp);
#endif
static void grp_update (void);
@@ -684,263 +687,277 @@ fail_exit (int code)
}
static void update_group (void)
static void
update_group_file(void)
{
bool is_member;
bool was_member;
bool changed;
const struct group *grp;
struct group *ngrp;
changed = false;
const struct group *grp;
/*
* Scan through the entire group file looking for the groups that
* the user is a member of.
*/
while ((grp = gr_next ()) != NULL) {
/*
* See if the user specified this group as one of their
* concurrent groups.
*/
was_member = is_on_list (grp->gr_mem, user_name);
is_member = Gflg && ( (was_member && aflg)
|| is_on_list (user_groups, grp->gr_name));
while ((grp = gr_next()) != NULL)
update_group(grp);
}
if (!was_member && !is_member) {
continue;
}
/*
* If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes
* mentioned groups while leaving the others.
*/
if (Gflg && rflg) {
is_member = !is_member;
}
static void
update_group(const struct group *grp)
{
bool changed;
bool is_member;
bool was_member;
struct group *ngrp;
ngrp = __gr_dup (grp);
if (NULL == ngrp) {
fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
changed = false;
if (was_member) {
if ((!Gflg) || is_member) {
/* User was a member and is still a member
* of this group.
* But the user might have been renamed.
*/
if (lflg) {
ngrp->gr_mem = del_list (ngrp->gr_mem,
user_name);
ngrp->gr_mem = add_list (ngrp->gr_mem,
user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing group member",
user_newname, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"change '%s' to '%s' in group '%s'",
user_name, user_newname,
ngrp->gr_name));
}
} else {
/* User was a member but is no more a
* member of this group.
*/
ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
/*
* See if the user specified this group as one of their
* concurrent groups.
*/
was_member = is_on_list (grp->gr_mem, user_name);
is_member = Gflg && ( (was_member && aflg)
|| is_on_list (user_groups, grp->gr_name));
if (!was_member && !is_member)
return;
/*
* If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes
* mentioned groups while leaving the others.
*/
if (Gflg && rflg) {
is_member = !is_member;
}
ngrp = __gr_dup (grp);
if (NULL == ngrp) {
fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
if (was_member) {
if ((!Gflg) || is_member) {
/* User was a member and is still a member
* of this group.
* But the user might have been renamed.
*/
if (lflg) {
ngrp->gr_mem = del_list (ngrp->gr_mem,
user_name);
ngrp->gr_mem = add_list (ngrp->gr_mem,
user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"removing group member",
user_name, AUDIT_NO_ID, 1);
"changing group member",
user_newname, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"delete '%s' from group '%s'",
user_name, ngrp->gr_name));
"change '%s' to '%s' in group '%s'",
user_name, user_newname,
ngrp->gr_name));
}
} else if (is_member) {
/* User was not a member but is now a member this
* group.
} else {
/* User was a member but is no more a
* member of this group.
*/
ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname);
ngrp->gr_mem = del_list (ngrp->gr_mem, user_name);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"adding user to group",
user_name, AUDIT_NO_ID, 1);
"removing group member",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO, "add '%s' to group '%s'",
user_newname, ngrp->gr_name));
SYSLOG ((LOG_INFO,
"delete '%s' from group '%s'",
user_name, ngrp->gr_name));
}
if (!changed) {
continue;
}
changed = false;
if (gr_update (ngrp) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"),
Prog, gr_dbname (), ngrp->gr_name);
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name));
fail_exit (E_GRP_UPDATE);
}
gr_free(ngrp);
} else if (is_member) {
/* User was not a member but is now a member this
* group.
*/
ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"adding user to group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO, "add '%s' to group '%s'",
user_newname, ngrp->gr_name));
}
if (!changed)
goto free_ngrp;
if (gr_update (ngrp) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"),
Prog, gr_dbname (), ngrp->gr_name);
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name));
fail_exit (E_GRP_UPDATE);
}
free_ngrp:
gr_free(ngrp);
}
#ifdef SHADOWGRP
static void update_gshadow (void)
{
bool is_member;
bool was_member;
bool was_admin;
bool changed;
const struct sgrp *sgrp;
struct sgrp *nsgrp;
changed = false;
#ifdef SHADOWGRP
static void
update_gshadow_file(void)
{
const struct sgrp *sgrp;
/*
* Scan through the entire shadow group file looking for the groups
* that the user is a member of.
*/
while ((sgrp = sgr_next ()) != NULL) {
while ((sgrp = sgr_next()) != NULL)
update_gshadow(sgrp);
}
#endif /* SHADOWGRP */
/*
* See if the user was a member of this group
#ifdef SHADOWGRP
static void
update_gshadow(const struct sgrp *sgrp)
{
bool changed;
bool is_member;
bool was_member;
bool was_admin;
struct sgrp *nsgrp;
changed = false;
/*
* See if the user was a member of this group
*/
was_member = is_on_list (sgrp->sg_mem, user_name);
/*
* See if the user was an administrator of this group
*/
was_admin = is_on_list (sgrp->sg_adm, user_name);
/*
* See if the user specified this group as one of their
* concurrent groups.
*/
is_member = Gflg && ( (was_member && aflg)
|| is_on_list (user_groups, sgrp->sg_name));
if (!was_member && !was_admin && !is_member)
return;
/*
* If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted
* groups while leaving the user apart of groups not mentioned
*/
if (Gflg && rflg) {
is_member = !is_member;
}
nsgrp = __sgr_dup (sgrp);
if (NULL == nsgrp) {
fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
if (was_admin && lflg) {
/* User was an admin of this group but the user
* has been renamed.
*/
was_member = is_on_list (sgrp->sg_mem, user_name);
nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing admin name in shadow group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"change admin '%s' to '%s' in shadow group '%s'",
user_name, user_newname, nsgrp->sg_name));
}
/*
* See if the user was an administrator of this group
*/
was_admin = is_on_list (sgrp->sg_adm, user_name);
/*
* See if the user specified this group as one of their
* concurrent groups.
*/
is_member = Gflg && ( (was_member && aflg)
|| is_on_list (user_groups, sgrp->sg_name));
if (!was_member && !was_admin && !is_member) {
continue;
}
/*
* If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted
* groups while leaving the user apart of groups not mentioned
*/
if (Gflg && rflg) {
is_member = !is_member;
}
nsgrp = __sgr_dup (sgrp);
if (NULL == nsgrp) {
fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
if (was_admin && lflg) {
/* User was an admin of this group but the user
* has been renamed.
if (was_member) {
if ((!Gflg) || is_member) {
/* User was a member and is still a member
* of this group.
* But the user might have been renamed.
*/
nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name);
nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing admin name in shadow group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"change admin '%s' to '%s' in shadow group '%s'",
user_name, user_newname, nsgrp->sg_name));
}
if (was_member) {
if ((!Gflg) || is_member) {
/* User was a member and is still a member
* of this group.
* But the user might have been renamed.
*/
if (lflg) {
nsgrp->sg_mem = del_list (nsgrp->sg_mem,
user_name);
nsgrp->sg_mem = add_list (nsgrp->sg_mem,
user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"changing member in shadow group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"change '%s' to '%s' in shadow group '%s'",
user_name, user_newname,
nsgrp->sg_name));
}
} else {
/* User was a member but is no more a
* member of this group.
*/
nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
if (lflg) {
nsgrp->sg_mem = del_list (nsgrp->sg_mem,
user_name);
nsgrp->sg_mem = add_list (nsgrp->sg_mem,
user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"removing user from shadow group",
user_name, AUDIT_NO_ID, 1);
"changing member in shadow group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO,
"delete '%s' from shadow group '%s'",
user_name, nsgrp->sg_name));
"change '%s' to '%s' in shadow group '%s'",
user_name, user_newname,
nsgrp->sg_name));
}
} else if (is_member) {
/* User was not a member but is now a member this
* group.
} else {
/* User was a member but is no more a
* member of this group.
*/
nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname);
nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"adding user to shadow group",
user_newname, AUDIT_NO_ID, 1);
"removing user from shadow group",
user_name, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'",
user_newname, nsgrp->sg_name));
SYSLOG ((LOG_INFO,
"delete '%s' from shadow group '%s'",
user_name, nsgrp->sg_name));
}
if (!changed) {
continue;
}
changed = false;
/*
* Update the group entry to reflect the changes.
} else if (is_member) {
/* User was not a member but is now a member this
* group.
*/
if (sgr_update (nsgrp) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"),
Prog, sgr_dbname (), nsgrp->sg_name);
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'",
sgr_dbname (), nsgrp->sg_name));
fail_exit (E_GRP_UPDATE);
}
free (nsgrp);
nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname);
changed = true;
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
"adding user to shadow group",
user_newname, AUDIT_NO_ID, 1);
#endif
SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'",
user_newname, nsgrp->sg_name));
}
if (!changed)
goto free_nsgrp;
/*
* Update the group entry to reflect the changes.
*/
if (sgr_update (nsgrp) == 0) {
fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"),
Prog, sgr_dbname (), nsgrp->sg_name);
SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'",
sgr_dbname (), nsgrp->sg_name));
fail_exit (E_GRP_UPDATE);
}
free_nsgrp:
free (nsgrp);
}
#endif /* SHADOWGRP */
/*
* grp_update - add user to secondary group set
*
@@ -949,10 +966,10 @@ static void update_gshadow (void)
*/
static void grp_update (void)
{
update_group ();
update_group_file();
#ifdef SHADOWGRP
if (is_shadow_grp) {
update_gshadow ();
update_gshadow_file();
}
#endif
}
@@ -1061,7 +1078,7 @@ static void process_flags (int argc, char **argv)
eflg = true;
break;
case 'f':
if ( (getlong(optarg, &user_newinactive) == -1)
if ( (str2sl(&user_newinactive, optarg) == -1)
|| (user_newinactive < -1)) {
fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"),

View File

@@ -1,61 +0,0 @@
#!/usr/bin/expect -f
# This is a script for repeatedly logging into the localhost
# using `rlogin` in order to apparently see a symptoms described
# in bug #332198.
# As described in the bug log, sometimes `rlogind` will fail to
# establish a connection, because it starts "login" process and
# the latter fails with "unable to determine TTY name, got /dev/pts/1"
# message.
#
# BUGS
#
# * the script rlogins to localhost
# * the script doesn't handle passwdord prompt, because it's intended
# to use .rhosts auth and expects shell prompt immediately after
# `rlogin`
# * the regexp for shell prompt is hardcoded
log_user 0
match_max 8192
while {1} {
set rlogin_spawn [spawn rlogin localhost]
if { $rlogin_spawn == 0 } { exit 1 }
expect {
-timeout 10 -re "^.*(Last login\[^\r\n\]*).*\n(\[^\r\n\]*\[#$\] )$" {
send_error "$expect_out(1,string)\n"
send_error "$expect_out(2,string)\n"
# send_error "$expect_out(0,string)\n"
}
timeout {
send_error "TIMEOUT/prompt\n"
send_error "$expect_out(buffer)\n"
send_error "RETRYING\n"
log_user 1
send "tty /\r"
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
send "tty /\r"
expect -timeout 2 -re "^.*\r?\n(\[^\r\n\]*# )$" {}
send_error "\n"
exit 2
}
}
send "tty\r"
expect {
-timeout 4 -re "tty\r?\n(\[^\r\n\]*)\r?\n(\[^\r\n\]*\[#$\] )$" {
send_error "$expect_out(2,string)$expect_out(1,string)\n"
# send_error "$expect_out(0,string)\n"
}
timeout { send_error "TIMEOUT/tty\n" ; exit 3 }
}
send "exit\r"
expect {
-timeout 2 eof {
# send_error "OK4: EOF\n"
}
timeout { send_error "TIMEOUT/eof\n" ; exit 4 }
}
wait
}
# vi: set sw=4:

View File

@@ -138,3 +138,8 @@ enum subid_status shadow_subid_list_owner_ranges(const char *owner, enum subid_t
return SUBID_STATUS_SUCCESS;
}
void shadow_subid_free(void *ptr)
{
free(ptr);
}

View File

@@ -6,7 +6,6 @@ TESTS = $(check_PROGRAMS)
check_PROGRAMS = \
test_adds \
test_atoi_strtoi \
test_atoi_strtou_noneg \
test_chkname \
test_sprintf \
test_strncpy \
@@ -48,19 +47,6 @@ test_atoi_strtoi_LDADD = \
$(CMOCKA_LIBS) \
$(NULL)
test_atoi_strtou_noneg_SOURCES = \
../../lib/atoi/strtou_noneg.c \
test_atoi_strtou_noneg.c \
$(NULL)
test_atoi_strtou_noneg_CFLAGS = \
$(AM_CFLAGS) \
$(NULL)
test_atoi_strtou_noneg_LDFLAGS = \
$(NULL)
test_atoi_strtou_noneg_LDADD = \
$(CMOCKA_LIBS) \
$(NULL)
test_chkname_SOURCES = \
../../lib/chkname.c \
test_chkname.c \

View File

@@ -1,76 +0,0 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h> // Required by <cmocka.h>
#include <stddef.h> // Required by <cmocka.h>
#include <setjmp.h> // Required by <cmocka.h>
#include <stdint.h> // Required by <cmocka.h>
#include <cmocka.h>
#include "atoi/strtou_noneg.h"
static void test_strtoul_noneg(void **state);
static void test_strtoull_noneg(void **state);
int
main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_strtoul_noneg),
cmocka_unit_test(test_strtoull_noneg),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}
static void
test_strtoul_noneg(void **state)
{
errno = 0;
assert_true(strtoul_noneg("42", NULL, 0) == 42);
assert_true(errno == 0);
assert_true(strtoul_noneg("-1", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoul_noneg("-3", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoul_noneg("-0xFFFFFFFFFFFFFFFF", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoul_noneg("-0x10000000000000000", NULL, 0) == 0);
assert_true(errno == ERANGE);
}
static void
test_strtoull_noneg(void **state)
{
errno = 0;
assert_true(strtoull_noneg("42", NULL, 0) == 42);
assert_true(errno == 0);
assert_true(strtoull_noneg("-1", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoull_noneg("-3", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoull_noneg("-0xFFFFFFFFFFFFFFFF", NULL, 0) == 0);
assert_true(errno == ERANGE);
errno = 0;
assert_true(strtoull_noneg("-0x10000000000000000", NULL, 0) == 0);
assert_true(errno == ERANGE);
}