Compare commits

..

249 Commits

Author SHA1 Message Date
Serge Hallyn
2bbe1af294 Release 4.17.1
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-12-31 13:23:26 -06:00
Tobias Stoeckmann
e3d051e4a8 su: Fix su - regression
Launch a login shell again if requested through "su -" or "su -l".

Fixes: d9923431eb ("src/: Use xasprintf() instead of its pattern")
Closes: <https://github.com/shadow-maint/shadow/issues/1160>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-12-31 19:06:00 +01:00
Serge Hallyn
e2512d5741 Release 4.17.0
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-12-25 16:32:40 -06:00
Pranav Lawate
881a506ce4 Added information in lastlog man page for new option '-a'
Signed-off-by: Pranav Lawate <pran.lawate@gmail.com>
2024-12-25 08:40:46 -06:00
Alejandro Colomar
8821d3ff2d lib/fs/readlink/: readlinknul(): Fix return type
Fixes: 419ce14b6f (2024-11-01, "lib/fs/readlink/: readlinknul(): Add function")
Cc: Serge Halyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-09 21:26:00 -06:00
Alejandro Colomar
b9d00b64a1 lib/fs/readlink/readlinknul.h: readlinknul(): Silence warning
Use a temporary variable to silence a sign-mismatch diagnostic.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-09 21:26:00 -06:00
Pranav Lawate
205c23bff2 Added option -a for listing active users only, optimized using if aflg,return
Signed-off-by: Pranav Lawate <pran.lawate@gmail.com>
2024-12-09 21:04:21 -06:00
Alejandro Colomar
c39305569b lib/, src/: Use !streq() instead of its pattern
Except for the added (and sorted) includes, the removal of redundant
parentheses, and a few non-string cases that I've left out of the
change, this patch can be approximated with the following semantic
patch:

	$ cat ~/tmp/spatch/strneq.sp
	@@
	expression s;
	@@

	- '\0' != *s
	+ !streq(s, "")

	@@
	expression s;
	@@

	- '\0' != s[0]
	+ !streq(s, "")

	@@
	expression s;
	@@

	- *s != '\0'
	+ !streq(s, "")

	@@
	expression s;
	@@

	- s[0] != '\0'
	+ !streq(s, "")

	$ find contrib/ lib* src/ -type f \
	| xargs spatch --in-place --sp-file ~/tmp/spatch/strneq.sp;

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-09 20:54:42 -06:00
Alejandro Colomar
7182d6402f lib/, src/: Use streq() instead of its pattern
Except for the added (and sorted) includes, the removal of redundant
parentheses, a few cases that have been refactored for readability, and
a couple of non-string cases that I've left out of the change, this
patch can be approximated with the following semantic patch:

	$ cat ~/tmp/spatch/streq.sp
	@@
	expression s;
	@@

	- '\0' == *s
	+ streq(s, "")

	@@
	expression s;
	@@

	- '\0' == s[0]
	+ streq(s, "")

	@@
	expression s;
	@@

	- *s == '\0'
	+ streq(s, "")

	@@
	expression s;
	@@

	- s[0] == '\0'
	+ streq(s, "")

	$ find contrib/ lib* src/ -type f \
	| xargs spatch --in-place --sp-file ~/tmp/spatch/streq.sp;

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-09 20:54:42 -06:00
Alejandro Colomar
8424d7c494 lib/sgetgrent.c: sgetgrent(): Fix use-after-free bug
We were reusing a leftover from parsing a previous line if
(i == NFIELDS-1).  A few lines below this check, we use read the element
in [3] (that is, [NFIELDS-1]), without having written it in this call.

Be stricter, and require that all NFIELDS fields are found.

Fixes: 45c6603cc8 (2007-10-07, "[svn-upgrade] Integrating new upstream version, shadow (19990709)")
Closes: <https://github.com/shadow-maint/shadow/issues/1144>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-09 19:46:29 -06:00
Serge Hallyn
b75ea29821 Release 4.17.0-rc1
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-12-05 23:52:36 -06:00
Alejandro Colomar
2f74389334 lib/gshadow.c: build_list(): Transform while loop into for loop
And 'n' is now an iterator.  Rename it to 'i' as usual.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
512deecca5 lib/gshadow.c: build_list(): Allocate at once
Instead of reallocating 1 more meber per iteration, calculate the total
amount that we want by counting the number of commas (delimiters) in the
string, plus one for the last element, plus one for the terminating
NULL.

This might result in overallocation of one element if the string is an
empty string, or if there's a trailing comma; however, that's not an
issue.  We can afford overallocating one element in certain cases, and
we get in exchange a much simpler function.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
2f4b5f5d80 lib/gshadow.c: Remove redundant variables
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
5ba62265b3 lib/gshadow.c: build_list(): Remove second parameter
We've simplified the function so much in the previous commits, that now
$2 is rather useless.  It only sets the output parameter to the same
value that the function returns.  It's simpler if the caller just sets
it itself after the call.

This removes the only 3-star pointer in the entire project.  :)

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
c1d597acbb lib/gshadow.c: sgetsgent(): Be consistent using NULL
0 is a horrible null-pointer constant.  Don't use it.
Especially, when just a few lines above, in the same function,
we've used NULL for the same thing.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
64ab7221fb lib/gshadow.c: build_list(): Compact ++ into previous statement
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
3feff7ae5b lib/gshadow.c: build_list(): Minimize use of pointer parameters
Use instead automatic variables as much as possible.
This reduces the number of dereferences, enhancing readability.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
30bcd185c3 lib/gshadow.c: Remove dead code
Nothing is using that value outside of build_list().
Keep it as an local variable.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
ecce8f098d lib/gshadow.c: Move zeroing to within build_list()
This makes build_list() less dependent on the context.
It starts from clean, whatever the state before the call was.
I was having a hard time understanding the reallocation,
until I saw that we were zeroing everything right before the call.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
712278add1 lib/gshadow.c: sgetsgent(): Remove superfluous condition
If n was 0, it doesn't hurt to set it again to 0;
and the list would be NULL, so it doesn't hurt free(3)ing it
and setting to NULL again either.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
de4715d978 lib/gshadow.c: build_list(): Remove dead assignment
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
f3464103fb lib/gshadow.c: build_list(): Improve variable and parameter names
It was hard to understand what each variable is.  Use a consistent
scheme, where a 'p' means a pointer, 'l' means list, and 'n' means
number of elements.  Those should be obvious from the name of the
function and the context, and will make it easier to read the code.
Also, the shorter names will allow focusing on the rest of the code.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
93887b4de6 lib/gshadow.c: build_list(): Remove unused variable
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
960947135c lib/gshadow.c: build_list(): Fix type of parameter
list ($2) is a pointer to a list of strings.  We were declaring it as an
array of pointers to strings, which was bogus.  It worked out of luck,
because array parameters are transformed into pointers by the compiler,
but it was incorrect.  Just look at how we're calling this function.

	$ grep build_list lib/gshadow.c
	build_list(char *s, char ***list, size_t *nlist)
		sgroup.sg_adm = build_list (fields[2], &admins, &nadmins);
		sgroup.sg_mem = build_list (fields[3], &members, &nmembers);
	$ grep '^static .*\<admins\>' lib/gshadow.c
	static /*@null@*//*@only@*/char **admins = NULL;
	$ grep '^static .*\<members\>' lib/gshadow.c
	static /*@null@*//*@only@*/char **members = NULL;

Fixes: 8e167d28af ("[svn-upgrade] Integrating new upstream version, shadow (4.0.8)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
c8c1059384 src/: Transform do-while into while
list cannot be NULL in the first iteration, so we don't need a do-while.

Just in case it's not obvious: we know it's not NULL in the first
iteration because right above, in line 772, we've already dereferenced
it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 21:20:59 -06:00
Alejandro Colomar
90afe61003 lib/, src/: Use strsep(3) instead of strtok(3)
strsep(3) is stateless, and so is easier to reason about.

It also has a slight difference: strtok(3) jumps over empty fields,
while strsep(3) respects them as empty fields.  In most of the cases
where we were using strtok(3), it makes more sense to respect empty
fields, and this commit probably silently fixes a few bugs.

In other cases (most notably filesystem paths), contiguous delimiters
("//") should be collapsed, so strtok(3) still makes more sense there.
This commit doesn't replace such strtok(3) calls.

While at this, remove some useless variables used by these calls, and
reduce the scope of others.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-05 15:33:32 -06:00
Iker Pedrosa
bdb5e2b79f CI: update artifacts action
v3 of upload-artifact actions is being deprecated, so let's move to v4.

Link: https://github.com/actions/upload-artifact
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-12-05 14:31:23 +01:00
Dennis Baurichter
f220407144 groupadd, groupmod: Update gshadow file with -U
When running groupadd or groupmod with the -U|--user option, also update
the group shadow database if it is used.

Fixes: 342c934a (2020-08-09, "add -U option to groupadd and groupmod")
Closes: <https://github.com/shadow-maint/shadow/issues/1124>
2024-12-03 11:16:13 +01:00
Alejandro Colomar
9f129146ff lib/, src/: Use !streq() instead of its pattern
Except for the added (and sorted) includes, and the removal of redundant
parentheses, and one special case, this patch can be approximated with
the following semantic patch:

	$ cat ~/tmp/spatch/strneq.sp;
	@@
	expression a, b;
	@@

	- strcmp(a, b) != 0
	+ !streq(a, b)

	@@
	expression a, b;
	@@

	- 0 != strcmp(a, b)
	+ !streq(a, b)

	$ find contrib/ lib* src/ -type f \
	| xargs spatch --sp-file ~/tmp/spatch/strneq.sp --in-place;

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-01 22:23:19 -06:00
Alejandro Colomar
5581e74188 contrib/, lib/, src/: Use streq() instead of its pattern
Except for the added (and sorted) includes, and the removal of redundant
parentheses, this patch can be approximated with the following semantic
patch:

	$ cat ~/tmp/spatch/streq.sp;
	@@
	expression a, b;
	@@

	- strcmp(a, b) == 0
	+ streq(a, b)

	@@
	expression a, b;
	@@

	- 0 == strcmp(a, b)
	+ streq(a, b)

	@@
	expression a, b;
	@@

	- !strcmp(a, b)
	+ streq(a, b)

	$ find contrib/ lib* src/ -type f \
	| xargs spatch --sp-file ~/tmp/spatch/streq.sp --in-place;
	$ git restore lib/string/strcmp/streq.h;

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-01 22:23:19 -06:00
Alejandro Colomar
212ef97449 lib/gshadow_.h: __STDC__ is always 1
We require C11 since a long time ago.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-01 22:04:24 -06:00
Alejandro Colomar
1d6456542c lib/csrand.c: csrand(): Use read(2) instead of fread(2)
We don't need the heavy stdio for getting a few bytes from
</dev/urandom>.  Let's use the simpler POSIX API.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-01 21:43:25 -06:00
Alejandro Colomar
627b7364b5 src/login_nopam.c: resolve_hostname(): Use NI_MAXHOST instead of MAXHOSTNAMELEN with getnameinfo(3)
That's what the getnameinfo(3) manual page recommends.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-12-01 20:59:28 -06:00
Volker Theile
a65fccf199 Allow setting an empty homedir
With the PR 352 it is not possible anymore to run `usermod --home "" <USERNAME>`. This PR will fix that regression.

Related to: https://github.com/shadow-maint/shadow/pull/352

Signed-off-by: Volker Theile <votdev@gmx.de>
2024-11-27 09:51:06 -06:00
Alejandro Colomar
365279ea95 share/container-build.sh: Fix path
The instructions are written so that this script should be run from the
root of the repository.  Specify the path from the root of the repo.
Before this fix, the command needed to be run from within <share/>.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-25 16:23:43 +01:00
Iker Pedrosa
742a230e30 CI: avoid cancelling all jobs when one fails
If a job in a matrix fails we don't want to cancel all jobs, thus we
need to set `fail-fast: false` as a strategy property.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-11-23 01:04:19 +01:00
Tobias Stoeckmann
929e61d604 lib/idmapping.c: Fix get_map_ranges range check
The get_map_ranges function shall support the whole accepted range
as specified in user_namespaces(7), i.e. upper and lower from 0 to
UINT_MAX - 1 as well as range from 1 to UINT_MAX. The actual limit of
range depends on values of upper and lower and adding the range
to either upper or lower shall never overflow UINT_MAX.

Fixes: 7c43eb2c4e (2024-07-11, "lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call")
Fixes: ff2baed5db (2016-08-14, "idmapping: add more checks for overflow")
Fixes: 94da3dc5c8 (2016-08-14, "also check upper for wrap")
Fixes: 7f5a14817d (2016-07-31, "get_map_ranges: check for overflow")
Co-authored-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-13 18:17:03 +01:00
Alejandro Colomar
0b8c0c893c lib/, src/: Use NULL instead of 0 as a null pointer constant
GCC 15 will add -Wzero-as-null-pointer-constant for deprecating it,
and I'm working on a paper for deprecating it from ISO C too.
Let's remove any uses in our code base.

I've done this change by building GCC from master, adding
-Werror=zero-as-null-pointer-constant to ./autogen.sh, and fixing every
error that showed up.

Closes: <https://github.com/shadow-maint/shadow/issues/1120>
Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
Link: <https://software.codidact.com/posts/292718/292759#answer-292759>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-13 09:44:54 -06:00
Alejandro Colomar
8296e62957 lib/shadow.c: my_sgetspent(): There can be only one!
We already have sgetspent(), with identical semantics, defined in
<lib/sgetspent.c>.

	$ diff -u <(grepc sgetspent .) <(grepc my_sgetspent .)
	--- /dev/fd/63	2024-11-11 11:56:55.444055921 +0100
	+++ /dev/fd/62	2024-11-11 11:56:55.444055921 +0100
	@@ -1,23 +1,19 @@
	-./lib/sgetspent.c:struct spwd *
	-sgetspent(const char *string)
	+./lib/shadow.c:static struct spwd *my_sgetspent (const char *string)
	 {
	-	static char spwbuf[PASSWD_ENTRY_MAX_LENGTH];
	-	static struct spwd spwd;
	-	char *fields[FIELDS];
	-	char *cp;
	-	int i;
	+	int                 i;
	+	char                *fields[FIELDS];
	+	char                *cp;
	+	static char         spwbuf[BUFSIZ];
	+	static char         empty[] = "";
	+	static struct spwd  spwd;

		/*
		 * Copy string to local buffer.  It has to be tokenized and we
		 * have to do that to our private copy.
		 */

	-	if (strlen (string) >= sizeof spwbuf) {
	-		fprintf (shadow_logfd,
	-		         "%s: Too long passwd entry encountered, file corruption?\n",
	-		         shadow_progname);
	-		return NULL;	/* fail if too long */
	-	}
	+	if (strlen (string) >= sizeof spwbuf)
	+		return 0;
		strcpy (spwbuf, string);
		stpsep(spwbuf, "\n");

	@@ -30,14 +26,16 @@
			fields[i] = strsep(&cp, ":");

		if (i == (FIELDS - 1))
	-		fields[i++] = "";
	+		fields[i++] = empty;

		if (cp != NULL || (i != FIELDS && i != OFIELDS))
	-		return NULL;
	+		return 0;

		/*
		 * Start populating the structure.  The fields are all in
	-	 * static storage, as is the structure we pass back.
	+	 * static storage, as is the structure we pass back.  If we
	+	 * ever see a name with '+' as the first character, we try
	+	 * to turn on NIS processing.
		 */

		spwd.sp_namp = fields[0];
	@@ -46,13 +44,13 @@
		/*
		 * Get the last changed date.  For all of the integer fields,
		 * we check for proper format.  It is an error to have an
	-	 * incorrectly formatted number.
	+	 * incorrectly formatted number, unless we are using NIS.
		 */

		if (fields[2][0] == '\0')
			spwd.sp_lstchg = -1;
		else if (a2sl(&spwd.sp_lstchg, fields[2], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * Get the minimum period between password changes.
	@@ -61,7 +59,7 @@
		if (fields[3][0] == '\0')
			spwd.sp_min = -1;
		else if (a2sl(&spwd.sp_min, fields[3], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * Get the maximum number of days a password is valid.
	@@ -70,7 +68,7 @@
		if (fields[4][0] == '\0')
			spwd.sp_max = -1;
		else if (a2sl(&spwd.sp_max, fields[4], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
	@@ -93,7 +91,7 @@
		if (fields[5][0] == '\0')
			spwd.sp_warn = -1;
		else if (a2sl(&spwd.sp_warn, fields[5], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * Get the number of days of inactivity before an account is
	@@ -103,7 +101,7 @@
		if (fields[6][0] == '\0')
			spwd.sp_inact = -1;
		else if (a2sl(&spwd.sp_inact, fields[6], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * Get the number of days after the epoch before the account is
	@@ -113,7 +111,7 @@
		if (fields[7][0] == '\0')
			spwd.sp_expire = -1;
		else if (a2sl(&spwd.sp_expire, fields[7], NULL, 0, 0, LONG_MAX) == -1)
	-		return NULL;
	+		return 0;

		/*
		 * This field is reserved for future use.  But it isn't supposed
	@@ -123,8 +121,7 @@
		if (fields[8][0] == '\0')
			spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
		else if (str2ul(&spwd.sp_flag, fields[8]) == -1)
	-		return NULL;
	+		return 0;

		return (&spwd);
	 }
	-./lib/prototypes.h:extern struct spwd *sgetspent (const char *string);

Closes: <https://github.com/shadow-maint/shadow/issues/1114>
Link: <https://www.youtube.com/watch?v=IpbvtSQvgWM>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-11 16:47:57 -06:00
Alejandro Colomar
19ce8b0abc src/login_nopam.c: Rely on the system's MAXHOSTNAMELEN
The reason for that code seems to be some ancient AIX version that
defined a value that was too small (32).  We don't support such systems.
In the link below, I found the following comment and code:

	 /*
	  * Some AIX versions advertise a too small MAXHOSTNAMELEN value (32).
	  * Result: long hostnames would be truncated, and connections would be
	  * dropped because of host name verification failures. Adrian van Bloois
	  * (A.vanBloois@info.nic.surfnet.nl) figured out what was the problem.
	  */

	#if (MAXHOSTNAMELEN < 64)
	#undef MAXHOSTNAMELEN
	#endif

	/* In case not defined in <sys/param.h>. */

	#ifndef MAXHOSTNAMELEN
	#define MAXHOSTNAMELEN  256             /* storage for host name */
	#endif

Today's systems seem to be much better regarding this macro.  Rely on
them.

Link: <https://sources.debian.org/src/tcp-wrappers/7.6.q-33/workarounds.c/?hl=36#L36>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-10 23:17:41 -06:00
Alejandro Colomar
9d8145acfc lib/gshadow.c: endsgent(): Invert logic to reduce indentation
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-10 23:11:43 -06:00
Alejandro Colomar
99a3ca17df lib/list.c: comma_to_list(): Use strchrcnt() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-10 23:07:19 -06:00
Alejandro Colomar
9efce1ac85 lib/string/strchr/: strchrcnt(): Add function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-10 23:07:19 -06:00
Alejandro Colomar
67c42427a0 lib/string/strcmp/: streq(): Add function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-10 23:07:19 -06:00
frostb1te
73e58adc6b src/gpasswd.c: is_valid_user_list(): Fix invalid free(3)
This fix addresses an issue in is_valid_user_list() where the free
operation was attempted on an address not allocated with malloc().  By
duplicating the pointer with xstrdup(users) into dup, and using dup as
the original pointer, we ensure that only the valid pointer is freed,
avoiding an invalid free operation.

This bug was introduced when changing some code that used strchrnul(3)
to use strsep(3) instead.  strsep(3) advances the pointer, unlike the
previous code.

This unconditionally leads to a bug:

-  Passing NULL to free(3), if the last field in the
   colon-separated-value list is non-empty.  This results in a memory
   leak.

-  Passing a pointer to the null byte ('\0') that terminates the string,
   if the last element of the colon-separated-value list is empty.  The
   most obvious reproducer of such a bogus free(3) call is:

       free(strdup("foo:") + 4);

   This results in Undefined Behavior, and could result in allocator
   data corruption.

Fixes: 16cb664865 (2024-07-01, "lib/, src/: Use strsep(3) instead of its pattern")
Suggested-by: <https://github.com/frostb1ten>
Reported-by: <https://github.com/frostb1ten>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Christian Brauner <christian@brauner.io>
2024-11-08 13:42:23 +01:00
Miroslav Cimerman
a0771fc01a man/shadow,man/gshadow: Fix grammar
Signed-off-by: Miroslav Cimerman <mc@doas.su>
2024-11-04 14:17:49 +01:00
Alejandro Colomar
86451e374b lib/fs/readlink/areadlink.h: areadlink(): Use PATH_MAX instead of a magic value
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
ed569088cc lib/fs/readlink/areadlink.h: Cosmetic changes
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
32f10c3dec lib/fs/readlink/, lib/: areadlink(): Move and rename function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
f8c7955bbb lib/: Use READLINKNUL() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
5d5ab18890 lib/: Use readlinknul() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
d78d1c2fd7 lib/fs/readlink/readlinknul.h: READLINKNUL(): Add macro
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Alejandro Colomar
419ce14b6f lib/fs/readlink/: readlinknul(): Add function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-11-01 21:25:50 -05:00
Iker Pedrosa
c8c3731e05 CI: fix fedora build problems
The new fedora 41 has been released and some things have changed. Make
sure to install python and python3-dnf and specify the dnf version in
the roles.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-31 09:52:54 -05:00
Serge Hallyn
cd8a8da7de CI: fix handling of sources.list
Closes #1088

We can't be sure whether a github runner will have new- or old-
style sources.list, so check whether the new exists, else use
the old style.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-10-31 09:46:51 +01:00
Alejandro Colomar
6266a916c2 lib/loginprompt.c: login_prompt(): Use strtcpy() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-30 21:52:21 -05:00
Alejandro Colomar
3daf3f0cc4 lib/getdef.c: Remove dead code
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-30 21:15:30 -05:00
Alejandro Colomar
0589cbc135 lib/fields.c: Remove dead code
A few lines above, we've removed the '\n' already.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-30 21:15:30 -05:00
sgakerru
feead2f639 src/useradd.c: get_groups(): Fix memory leak 2024-10-30 12:58:55 +01:00
Marcin Nowakowski
326889ca81 Fix coverity unbound buffer issues
During coverity scan, there are reported four issues
with unbounded source buffer for each usage of input arg
directly with syslog function.

Sample coverity test report for chsh.c file:

 1. string_size_argv: argv contains strings with unknown size.
 int main (int argc, char **argv)
[...]
 4. var_assign_var: Assigning: user = argv[optind]. Both are now tainted.
 user = argv[optind];
[...]
CID 5771784: (#1 of 1): Unbounded source buffer (STRING_SIZE)
15. string_size: Passing string user of unknown size to syslog.
 SYSLOG ((LOG_INFO, "changed user '%s' shell to '%s'", user, loginsh));

Similar issue is reported three times more:
File: chfn.c, function: main, variable: user
File: passwd.c, function: main, variable: name
File: newgrp.c, function: main, variable: group

This commit is the first approach to fix the reported issues.
The proposed changes add conditions, which verify
the user and group names arguments, including their lengths.
This will not silence the coverity reports, but the change causes
that they are irrelevant and could be ignored.
2024-10-22 15:31:19 +02:00
Alejandro Colomar
afc4b574b7 lib/alloc/realloc*.h: Always reallocate at least 1 byte
glibc's realloc(3) is broken.  It was originally good (I believe) until
at some point, when it was changed to conform to C89, which had a bogus
specification that required that it returns NULL.  C99 fixed the mistake
from C89, and so glibc's realloc(3) is non-conforming to
C99/C11/POSIX.1-2008.  C17 broke again the definition of realloc(3).

Link: <https://github.com/shadow-maint/shadow/pull/1095>
Link: <https://nabijaczleweli.xyz/content/blogn_t/017-malloc0.html>
Link: <https://inbox.sourceware.org/libc-alpha/5gclfbrxfd7446gtwd2x2gfuquy7ukjdbrndphyfmfszxlft76@wwjz7spd4vd7/T/#t>
Co-developed-by: наб <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: наб <nabijaczleweli@nabijaczleweli.xyz>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Acked-by: Paul Eggert <eggert@cs.ucla.edu>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-22 10:53:06 +02:00
Alejandro Colomar
12aa29b576 lib/alloc/realloc*.h: Rename macro parameter
This is in preparation for the following commit, which will need this
shorter parameter name to avoid breaking long lines.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-22 10:53:06 +02:00
Alejandro Colomar
30ab822cf3 doc/contributions/introduction.md: Fix typo in link
Fixes: 981bb8f9d1 ("doc: add contributions introduction")
Reported-by: наб <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-17 17:09:26 +02:00
Iker Pedrosa
0d1faafd3c CI: install libltdl-dev
Required to manage an autoconf macro.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-15 10:43:24 +02:00
Iker Pedrosa
c8600f1359 CI: run command as non-root user
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-15 10:43:24 +02:00
Iker Pedrosa
339a596374 CI: run Install dependencies workflow
Run this workflow instead of replicating the script every time we need
to install the dependencies.

Reviewed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-15 10:43:24 +02:00
Iker Pedrosa
99c4f445c7 CI: update Ubuntu repositories configuration
Recently Ubuntu updated its repositories configuration file from
`/etc/apt/sources.list` to `/etc/apt/sources.list.d/ubuntu.source`.
Thus, we need to update its location to be able to install all the
package dependencies.

In addition, the CI script was trying to uncomment the lines starting
with `deb-src`, but there is none in the new configuration file format.
Replace `Types: deb` by `Types: deb deb-src` at the beginning of the
line instead.

This commit merges all dependency installation scripts into a single
workflow, which will be called from all sites that have to install
dependencies.

Link: https://linuxconfig.org/ubuntus-repository-configuration-ubuntu-sources-have-moved-to-etc-apt-sources-list-d-ubuntu-sources
Closes: https://github.com/shadow-maint/shadow/issues/1088
Reported-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-15 10:43:24 +02:00
Alejandro Colomar
4a15739408 src/suauth.c: check_su_auth(): Use pointers to simplify
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-13 20:40:02 -05:00
Alejandro Colomar
fb731369fd src/suauth.c: check_su_auth(): Use strspn(3) instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-13 20:40:02 -05:00
Alejandro Colomar
276f3fde26 lib/gshadow.c: endsgent(): Remove dead assignment
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-13 20:40:02 -05:00
Alejandro Colomar
02d4af7f6f lib/port.c: portcmp(): Use strcmp(3) instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-13 20:40:02 -05:00
Alejandro Colomar
f45adadd28 lib/, src/: Use stpspn() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-13 20:40:02 -05:00
Iker Pedrosa
9035932496 useradd: fix comparison sign for write_full() return
I forgot to change the comparison sign that checks the return value of
write_full()

Closes: https://github.com/shadow-maint/shadow/issues/1072
Fixes: 8903b94c86 ("useradd: fix write_full() return value")
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2313559

Reported-by: <https://github.com/brown-midas>
Suggested-by: <https://github.com/brown-midas>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-10-04 21:01:58 -05:00
kugarocks
6c9e80165b src/useradd.c: Add the missing equals sign
Fixes: a7b169be18 ("src/useradd.c: Use stpsep() to simplify")
Reviewed-by: Alejandro Colomar <alx@kernel.org>
2024-10-04 20:59:23 -05:00
Alejandro Colomar
7a796897e5 src/check_subid_range.c: Remove dead code
I forgot to remove the setting of errno when I switched from
strtoul_noneg() to str2ul().  strtoul(3) needs errno for determining
success, but str2ul() does not.

Fixes: f3a1e1cf09 ("src/check_subid_range.c: Call str2ul() instead of strtoul_noneg()")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-03 10:38:56 +02:00
Tobias Stoeckmann
af66ffea33 man/subgid,man/subuid: Fix program list
The groupadd utility does not set information in subgid. Instead, list
all programs which actually can do so.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-10-02 13:03:38 +02:00
Tobias Stoeckmann
e7a970a189 man/passwd: Fix typo
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-10-02 13:03:38 +02:00
Alejandro Colomar
759d2373e4 src/useradd.c: Add fmkomstemp() to fix mode of </etc/default/useradd>
The mode of the file should be 644, but mkstemp(2) was transforming it
to 600.

To do this, we need a function that accepts a mode parameter.  While we
don't need a flags parameter, to avoid confusion with mkostemp(2), let's
add both a flags and a mode parameter.

Link: <https://github.com/shadow-maint/shadow/pull/1080>
Reported-by: kugarocks <kugacola@gmail.com>
Suggested-by: kugarocks <kugacola@gmail.com>
Tested-by: kugarocks <kugacola@gmail.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-10-01 14:38:59 -05:00
Tobias Stoeckmann
e6a5484ced lib: Eliminate dead code
The tz function is only called if ENV_TZ starts with a slash.

If the specified file cannot be read, the code implies that ENV_TZ
would be returned if it does not start with a slash.

Since we know that it DOES start with a slash, the code can be
simplified to state that "TZ=CST6CDT" is returned as a default if
the specified file cannot be read.

Benefit of this change is that strcpy's use case here can be
easier verified.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-29 12:23:05 +02:00
Tobias Stoeckmann
dd6cddd481 lib/run_part: Adjust style
Remove some of these whitespaces.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
76c97ed7ec lib/run_part: Unify error messages
At least if they can be assigned directly to a function call.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
62bd261fbe lib: Fix typo
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
6b4487e173 lib/run_part: Reduce visibility
The run_part function is only used in run_part.c itself, so no
need to expose it to other files.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
db395130d1 lib/run_part: Unify logging
Use shadow_logfd for logging instead of fixed stderr to use
shadow's own logging infrastructure.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
3ac50e1d02 lib/run_part: Use correct data types
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-18 14:52:05 +02:00
Tobias Stoeckmann
81078c57fb Fix typos
Typos in comments and configure output, i.e. no functional change.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
2024-09-13 22:27:08 +02:00
Iker Pedrosa
8903b94c86 useradd: fix write_full() return value
write_full() returns -1 on error and useradd was checking another value.

Closes: https://github.com/shadow-maint/shadow/issues/1072
Fixes: f45498a6c2 ("libmisc/write_full.c: Improve write_full()")

Reported-by: <https://github.com/brown-midas>
Suggested-by: <https://github.com/brown-midas>
Reviewed-by: Alejandro Colomar <alx@kernel.org>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-09-13 09:44:51 +02:00
Pino Toscano
b2b37863a6 lib/user_busy.c: Include <utmpx.h>
Since:
- utmpx APIs are used in non-Linux code blocks
- <utmpx.h> is already unconditionally included in Linux parts in other
  files
then unconditionally include it in this file as well.

Signed-off-by: Pino Toscano <toscano.pino@tiscali.it>
2024-09-12 11:43:39 +02:00
Alejandro Colomar
1f11a5ce5a src/: Recommend --badname only if it is useful
(Review with -w (--ignore-all-space).)

Closes: <https://github.com/shadow-maint/shadow/issues/1067>
Reported-by: Anselm Schüler <mail@anselmschueler.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-09-01 08:17:11 -05:00
Alejandro Colomar
0663c91f80 src/: Invert logic to improve readability
And remove the (now) redundant comments.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-09-01 08:17:11 -05:00
Alejandro Colomar
1c127bd173 lib/chkname.c: is_valid_{user,group}_name(): Set errno to distinguish the reasons
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-09-01 08:17:11 -05:00
Alejandro Colomar
56d52997c3 man/userdel.8.xml: Reword '-f'
The previous wording seemed to say that -f implied -r.  It doesn't; -f
only skips safety checks, so reword accordingly.

Closes: <https://github.com/shadow-maint/shadow/issues/1062>
Reported-by: Martin von Wittich <martin.von.wittich@iserv.eu>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-09-01 07:45:30 -05:00
Alejandro Colomar
f5806e0511 lib/: Chain free(strzero(s))
This reduces the repetition of the argument, which could be error-prone.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-30 21:44:07 -05:00
Alejandro Colomar
dab8de8a72 lib/string/memset/: memzero(), strzero(): Return the pointer
This allows chaining with free(3) on the same line.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-30 21:44:07 -05:00
Alejandro Colomar
87a5145719 lib/: Move memzero.[ch] under lib/string/memset/
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-30 21:44:07 -05:00
Alejandro Colomar
5c0b99c77e po/es.po: wsfix
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-22 22:51:57 -05:00
Alejandro Colomar
3dc840a56a lib/string/strftime.h: STRFTIME(): Tighten macro definition
strftime(3) is not a variadic function; there's exactly one argument
after the format string.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-22 22:51:57 -05:00
Alejandro Colomar
60da937c2f src/chage.c: print_day_as_date(): Handle errors from strfime(3)
Just like we do in day_to_str().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-22 22:51:57 -05:00
Alejandro Colomar
6a2e298a5b src/chage.c: print_day_as_date(): Simplify error handling
If localtime_r(3) fails, just print future, as we do in day_to_str().
It should only fail for unrealistic dates, if at all.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-22 22:51:57 -05:00
Alejandro Colomar
683b3caa62 lib/, src/: Use %F instead of %Y-%m-%d with strftime(3)
%F is specified by ISO C99.  It adds semantic meaning as printing an
ISO 8601 date.

Scripted change:

	$ cat ~/tmp/spatch/strftime_F.sp
	@@
	@@

	- "%Y-%m-%d"
	+ "%F"
	$ find contrib/ lib* src/ -type f \
	| xargs spatch --sp-file ~/tmp/spatch/strftime_F.sp --in-place

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-22 22:51:57 -05:00
Chris Hofstaedtler
04592e4cc7 Remove references to cppw, cpgr
cppw, cpgr were Debian-only tools, which I've dropped in a recent upload.

Upstream should have never had tests for them.

Signed-off-by: Chris Hofstaedtler <zeha@debian.org>
2024-08-12 10:08:45 +02:00
Carles Pina i Estany
e04e493234 Update Catalan translation 2024-08-11 23:22:04 +02:00
Alejandro Colomar
3f5b4b5626 lib/, src/: Use local time for human-readable dates
That is, use localtime_r(3) instead of gmtime_r(3).

Closes: <https://github.com/shadow-maint/shadow/issues/1057>
Reported-by: Gus Kenion <https://github.com/kenion>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Paul Eggert <eggert@cs.ucla.edu>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-08-01 10:12:44 +02:00
Eisuke Kawashima
f3f501c81c doc(login.defs): fix type of TTYPERM 2024-07-18 10:21:21 -05:00
Iker Pedrosa
fffa4d3e27 share/containers: remove unused dockerfiles
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
28ffa634d8 CI: use Ansible build in Github Action
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
4bc0c5b0b8 doc: update documentation to use Ansible build
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
f56e79a2b7 share/container-build.sh: update to use Ansible build
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
d8fb10f7b7 share/ansible: implement distribution selection
Distribution to run can be selected when running `ansible-playbook` by
appending `-e 'distribution=fedora'` to the command.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
80c4e70da0 share/ansible: convert alpine dockerfile to ansible
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
1d6f578f3e share/ansible: convert debian dockerfile to ansible
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
9a53a8aebd share/ansible: move fedora ci_run to its own file
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
36e8015e2b share/.gitignore: add build-out folder
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
df50348a28 share/ansible: create roles
Create `build_container` and `ci_run` roles and move the fedora target
to them.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Iker Pedrosa
9a0cd7a231 share/ansible: convert fedora dockerfile to ansible
Using a dockerfile to build, install and test the code can be
problematic as we can't capture the log files to check what failed in
case of failure. This PR converts the fedora dockerfile to Ansible, an
open source IT automation tool. The tool can be used on the developers
and the CI system to check whether a piece of code can be built,
installed and tested.

This is the first patch in a series, where I will convert the existing
PR workflows to use Ansible instead of dockerfiles.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
2024-07-18 10:17:29 -05:00
Chris Hofstaedtler
dfbc0db895 Makefile.am: avoid warning: EXTRA_DIST multiply defined
automake complained about duplicate definitions of EXTRA_DIST:

autoreconf: running: automake --add-missing --copy --no-force
Makefile.am:19: warning: EXTRA_DIST multiply defined in condition TRUE ...
Makefile.am:3: ... 'EXTRA_DIST' previously defined here
autoreconf: Leaving directory '.'

Signed-off-by: Chris Hofstaedtler <zeha@debian.org>
2024-07-18 09:21:57 -05:00
Chris Hofstaedtler
11e9627658 tests/libsubid/04_nss: fix setting basedir
Align on variable name BUILD_BASE_DIR for overriding the toplevel
directory. This is the same name as accepted by tests/common/config.sh.

Without this, the test libsubid/04_nss fails in Debian's autopkgtests.

Signed-off-by: Chris Hofstaedtler <zeha@debian.org>
2024-07-18 08:52:35 -05:00
Sebastian Gross
34f213211f man: groupmod: remove misleading -N option
The extra paragraph for --users mentions a -N option. groupmod has no -N
option.

Prevent confusion and remove its appearance.

Signed-off-by: Sebastian Gross <sgross@emlix.com>
2024-07-17 15:48:22 +02:00
Sebastian Gross
48b36a03e8 man: group(add|mod): clarify list format
The --users list option expect a string of comma separated values.
While this might be obvious to some others it is certainly not for others.

Remove this ambiguity.

Closes #848

Signed-off-by: Sebastian Gross <sgross@emlix.com>
2024-07-17 15:48:22 +02:00
Sebastian Gross
9176206a7c man: groupmod: fix misleading param
--append has no argument in groupmod.c but the man pages states GID as
parameter.

In order to avoid confusion remove it from man page.

Signed-off-by: Sebastian Gross <sgross@emlix.com>
2024-07-17 15:48:22 +02:00
Alejandro Colomar
8a93576ff9 lib/chkname.c: An object cannot expand further than the universe in which it resides
If you want a larger object, you'll have to wait at least until the
universe expands so much.

If an implementation doesn't recognize its own limitations, its a bug,
not a feature.

Closes: <https://github.com/shadow-maint/shadow/issues/1052>
Cc: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-15 15:01:11 +02:00
Alejandro Colomar
63297e836d lib/atoi/strtoi/, tests/: strto[iu]_(): 1 is an invalid base
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
745281f295 lib/atoi/, *: Split files 2024-07-11 22:42:58 -05:00
Alejandro Colomar
2dda45a390 src/usermod.c: Use id_t for parsing uid_t and gid_t
Use a static_assert(3) to make sure that id_t == uid_t == gid_t.

And use uintmax_t to print it, since on Linux they are unsigned types.

Link: <https://github.com/shadow-maint/shadow/pull/951>
Reviewed-by: Tycho Andersen <tycho@tycho.pizza>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
cfb8df4a91 src/usermod.c: Rename identifiers ralated to [ug]id's
It was unclear why this code is using ulong.  Since these only handle
uid's and gid's, rename the identifiers accordingly, after id_t.

Link: <https://github.com/shadow-maint/shadow/pull/951>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
b73c78581c lib/idmapping.c: get_map_ranges(): Don't exit() from a library function
Fixes: ff2baed5db ("idmapping: add more checks for overflow")
Link: <ff2baed5db (r136635300)>
Reported-by: Alejandro Colomar <alx@kernel.org>
Suggested-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
c46c6a6e5a lib/idmapping.c: get_map_ranges(): Simplify iterator variables
Merge two iterator variables into one, and reduce its scope.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
a184c2b555 lib/idmapping.c: get_map_ranges(): Remove dead code
This test is impossible.  The limits specified in a2ul() already cover
this.

Link: <ff2baed5db (r136635300)>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
7c43eb2c4e lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call
Link: <ff2baed5db (r136635300)>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
57aa813c73 lib/idmapping.c: get_map_ranges(): Move range check to a2ul() call
Link: <ff2baed5db (r136635300)>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
5586f43d48 lib/idmapping.c: get_map_ranges(): Move range check to a2ul() calls
Link: <ff2baed5db (r136635300)>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
f89925c219 lib/idmapping.c: get_map_ranges(): Rename local variable
For a pointer iterator used often, a single-letter identifier is more
appropriate.  That reduces the length of lines considerably, avoiding
unnecessary line breaks.  And since we initialize it with

	m = mappings;

it's clear what it is.

Link: <ff2baed5db (r136635300)>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
c2ebd210e7 lib/limits.c: check_logins(): Report LOGIN_ERROR_LOGIN if str2ul() ERANGE
Fixes: 10396f9536 ("* libmisc/limits.c: Parse the limits, umask, nice, maxlogin, file limit with getlog() / getulong().")
Link: <882cf59459>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-11 22:42:58 -05:00
Alejandro Colomar
568d26d7ed src/login_nopam.c: login_access(): Use stpsep() to simplify
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
a7b169be18 src/useradd.c: Use stpsep() to simplify
This allows using plain strcmp(3) instead of MATCH().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
d95b899bfc lib/nss.c: nss_init(): Use stpsep() instead of strtok_r(3)
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
8714ac0cd6 src/suauth.c: check_su_auth(): Use stpsep() to simplify
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
64409c28b7 lib/string/strchr/stpcspn.[ch]: stpcspn(): Remove unused function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
a33d7430ed lib/attr.h: ATTR_STRING(): It only accepts one argument
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
d91b22cc2f lib/, src/: Use stpsep() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Alejandro Colomar
39da15614e lib/string/strtok/stpsep.[ch]: stpsep(): Add function
This function is somewhat simpler to use than strsep(3) in some cases.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-08 20:25:01 -05:00
Chris Hofstaedtler
843c151f2c lib/find_new_[gu]id.c: include stdint.h for UINT16_MAX/UINT32_MAX
Signed-off-by: Chris Hofstaedtler <zeha@debian.org>
2024-07-08 01:19:49 +02:00
Alejandro Colomar
cee79c215a lib/port.c: getportent(): Use strsep(3) instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
882db57f24 lib/port.c: getportent(): Align variables
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
b4b4ff633a lib/port.c: getttyuser(): Use pointer arithmetic to simplify
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
d9d0117e80 lib/port.c: getportent(): Use equivalent code to parse equally-formatted fields
The tty names field and the user names field have the same formatting:
a CSV terminated by a ':'.  Thus, we can --and should-- use the same
exact code for parsing both.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
a198054456 lib/port.c: getportent(): Make sure the aren't too many fields in the CSV
Otherwise, the line is invalidly formatted, and we ignore it.

Detailed explanation:

There are two conditions on which we break out of the loops that precede
these added checks:

-  j is too big (we've exhausted the space in the static arrays)

	$ grep -r -e PORT_TTY -e PORT_IDS lib/port.*
	lib/port.c:	static char *ttys[PORT_TTY + 1];	/* some pointers to tty names     */
	lib/port.c:	static char *users[PORT_IDS + 1];	/* some pointers to user ids     */
	lib/port.c:	for (cp = buf, j = 0; j < PORT_TTY; j++) {
	lib/port.c:			if ((',' == *cp) && (j < PORT_IDS)) {
	lib/port.h: * PORT_IDS - Allowable number of IDs per entry.
	lib/port.h: * PORT_TTY - Allowable number of TTYs per entry.
	lib/port.h:#define	PORT_IDS	64
	lib/port.h:#define	PORT_TTY	64

-  strpbrk(3) found a ':', which signals the end of the comma-sepatated
   list, and the start of the next colon-separated field.

If the first character in the remainder of the string is not a ':', it
means we've exhausted the array size, but the CSV list was longer, so
we'd be truncating it.  Consider the entire line invalid, and skip it.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
c3f97e251e lib/port.c: getportent(): Make sure there are at least 2 ':' in the line
Otherwise, the line is invalidly formatted, and we ignore it.

Closes: <https://github.com/shadow-maint/shadow/issues/1036>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
f1f82c2105 lib/port.c: getportent(): Remove obvious comments
And do some style changes on the corresponding code.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
e790993c5d lib/port.c: getportent(): Rename goto label
This label means we detected a bogus line, and want to skip it and jump
to the next one; rename it accordingly.  'again' seemed to say that it
was somehow looping on the same line.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
bf84b3a855 lib/port.c: getttyuser(): Use goto to break out of nested loops
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
a4b91048e9 lib/port.c: getttyuser(): Remove dead code
port.pt_names cannot be NULL; it always points to the static array ttys.

$ grep -rn pt_names
lib/port.c:157:	port.pt_names = ttys;
lib/port.c:159:		port.pt_names[j] = cp;
lib/port.c:172:	port.pt_names[j] = NULL;
lib/port.c:344:		for (i = 0; NULL != port->pt_names[i]; i++) {
lib/port.c:345:			if (portcmp (port->pt_names[i], tty) == 0) {
lib/port.c:350:		if (port->pt_names[i] == 0) {
lib/port.h:39: *	pt_names - pointer to array of device names in /dev/
lib/port.h:45:	char **pt_names;

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-06 07:44:02 -05:00
Alejandro Colomar
53ea42e67f contrib/adduser.c: main(): Use strcpy/cat(3) instead of their pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
59e5eef38f contrib, lib/, src/, tests/: Use stpcpy(3) instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
c6018240f8 lib/, src/: Use strrspn() instead of its pattern
This requires changing isspace(3) calls to an explicit accept string,
and I chose " \t\n" for it (as is done in other parts of this project),
which isn't exactly the same, but we probably don't want other
isspace(3) characters in those files, so it should work.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
7c9da42db0 lib/sssd.c: Style fixes
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
813c3ec6c5 src/login_nopam.c: login_access(): Simplify, calling strchr(3)
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
9174697469 lib/getdef.c: def_load(): Use stp[c]spn() instead of their patterns
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
2fcf520184 lib/string/strchr/: stp[c]spn(), strrspn(), strnul(): Add macros and functions
Often, a pointer is more useful than a length when calling these.

Link: <https://docs.oracle.com/cd/E86824_01/html/E54769/strrspn-3gen.html>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-03 10:03:12 -05:00
Alejandro Colomar
b38ee0c6d0 src/chage.c: Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
ab9f4da83f src/faillog.c: Simplify, by calling str2sh() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
0464c1abf1 src/usermod.c: Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
e341291f99 src/passwd.c: Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
b178fed180 src/useradd.c: Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
ebdeb8f22a src/: Use get_[ug]id() where appropriate
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
a11ae5cf29 lib/shadow.c: my_sgetspent(): Simplify error handling
Handle negative values as errors from a2sl(), and reuse its
error-handling code.

Cc: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
7e754cc447 lib/shadow.c: my_sgetspent(): Remove dead code
spwd.sp_flag is an unsigned long, which can never be negative.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
e9cc053df7 lib/shadow.c: my_sgetspent(): Merge 'else {if}' into 'else if'
This reduces indentation.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
326bdfe70b lib/sgetspent.c: sgetspent(): Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
03521bccce lib/limits.c: setup_limits(): Simplify, by calling str2i(mode_t, ) instead of str2ul()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
3fd1d62e29 lib/limits.c: setup_limits(): Simplify, by calling str2si() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
312c3b1389 lib/limits.c: setup_limits(): Simplify, by calling a2si() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
169cbe1f56 lib/limits.c: set_umask(): Simplify, by calling str2i(mode_t, ) instead of str2ul()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
dba5600cef lib/limits.c: set_prio(): Simplify, by calling str2si() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
5f2055c395 lib/getdef.c: getdef_long(): Simplify, by calling a2sl() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
45d4472c92 lib/getdef.c: getdef_unum(): Fix wrong limit check
The limit, since it's an unsigned int, should have been UINT_MAX, not
INT_MAX.  By calling a2ui() we can fix that and simplify too.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
9415ce4a14 lib/getdef.c: getdef_num(): Simplify, by calling a2si() instead of str2sl()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 22:52:31 +02:00
Alejandro Colomar
866d911655 Remove groups(1)
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 13:32:13 -05:00
Alejandro Colomar
c7981fdd00 Remove id(1)
Distributions use id(1) from GNU coreutils or BusyBox.  Drop ours.

Closes: <https://github.com/shadow-maint/shadow/issues/1005>
Suggested-by: dkwo <nicolopiazzalunga@gmail.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Michael Vetter <jubalh@iodoru.org>
Cc: Sam James <sam@gentoo.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 13:32:13 -05:00
Alejandro Colomar
379e9c32f7 lib/idmapping.c: Use long constants in prctl(2), and remove 0s
The prctl(2) system-call wrapper is implemented as a variadic function.
This makes it important to pass arguments to it of the right type (and
more importantly of the right width), to avoid undefined behavior.

While at it, check errors with ==-1, not <0, which is more explicit.

Also, PR_SET_KEEPCAPS(2const) doesn't need all arguments, so it can be
called with just two of them; remove unnecessary 0s.

See-also: prctl(2), PR_SET_KEEPCAPS(2const)
Link: <https://lore.kernel.org/linux-man/ddbdyaiptesjalgfmztxideej67e3yaob7ucsmbf6qvriwxiif@dohhxrqgwhrf/T/#med306b5b003f9cc7cc2de69fcdd7ee2d056d0954>
Cc: Xi Ruoyao <xry111@xry111.site>
Cc: Lukas Slebodnik <lslebodn@fedoraproject.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-02 13:12:22 -05:00
Alejandro Colomar
060b0849a6 lib/attr.h: Use C23-style attributes
They're stricter.  The GNU attributes are too lazy, and can be misused
more easily.  Also, mixing both has its own problems.

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
4eed3e84a1 lib/gshadow.c: Use XREALLOC() instead of silently continuing on ENOMEM
We should do better, and correctly handle errors, since this is library
code.  However, I'm lazy right now, so let's die hard, and let us
improve this later.

Link: <https://github.com/shadow-maint/shadow/pull/991#discussion_r1660308154>
Reported-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
53e1eb4045 src/: Remove dead code
FIRST_MEMBER_IS_ADMIN was never enabled.  And BTW, that code had been
broken for a long time, so probably nobody should manually enable it.

Link: <https://github.com/shadow-maint/shadow/pull/991#discussion_r1660308748>
Reported-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
ba3a51e90f lib/: Use [[gnu::alloc_size(...)]] on allocation functions
Suggested-by: Martin Uecker <uecker@tugraz.at>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
5111e5ed1b lib/: Use multi-line macro definitions
This reduces the complexity of those nested parentheses.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
3049bef9c3 lib/alloc/, lib/, src/, tests/: Organize the allocation APIs in a new subdirectory
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
883bf71fc8 lib/alloc.[ch]: xmalloc(): Remove unused function
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
29f4f03def lib/string/strdup/xstrdup.[ch], lib/, src/: Move xstrdup() to its own file
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
2cf73c99a6 lib/string/strcpy/zustr2stp.[ch], tests/: Remove ZUSTR2STP()
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
85a2f36992 src/logoutd.c: Use STRNCAT() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
cb3e2fbdcf src/logoutd.c: Use STRNDUPA() instead of its pattern
STRNDUPA() is equivalent to automatic storage allocation (alloca(3))
+ ZUSTR2STP().

The benefits of this refactor are:

-  The allocation size is always correct, and needs no comments, since
   it's now automatically calculated by the macro.

-  STRNDUPA() is probably more familiar, since
   -  strndupa(3) is a libc function,
   -  STRNDUPA() is the obvious wrapper that
      calculates the size based on the input array.

-  We can remove ZUSTR2STP().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
ac591763fe src/newusers.c: Exit on ENOMEM, by calling xstrdup() instead of strdup(3)
The program was happily ignoring ENOMEM errors.

Fixes: 7f9e196903 ("* NEWS, src/newusers.c, src/Makefile.am: Added support for")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
103ffc5b1d lib/utmp.c: prepare_utmp(): Use xstrdup() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
3c09e40a1f lib/utmp.c: Use XSTRNDUP() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
2a0c0dd24b lib/string/strdup/: XSTRNDUP(), STRNDUPA(): Add macros
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
9a9faf86f0 lib/string/strcpy/strncat.[ch]: STRNCAT(): Add macro
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
d9923431eb src/: Use xasprintf() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
44ba094766 src/groupmems.c: Fix number of elements in allocation
We are setting `sgrent.sg_adm[1] = NULL;`, so we need 2 elements.

Fixes: 87b56b19fb ("* NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for [...]")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
c287317075 lib/gshadow.c: build_list(): Fix REALLOC() nmemb calculation
Fixes: efbbcade43 ("Use safer allocation macros")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
056f1d03ee lib/gshadow.c: build_list(): Fix forever loop on ENOMEM
Before this patch, the function looped while (s != NULL && *s != '\0').
However, nothing was modifying that string if REALLOC() failed, so the
loop was forever.

Fixes: 8e167d28af ("[svn-upgrade] Integrating new upstream version, shadow (4.0.8)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
16cb664865 lib/, src/: Use strsep(3) instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
8176e309ed src/useradd.c: tallylog_reset(): Use Basename() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
964df6ed6e lib/, src/: Use strchrnul(3) instead of its pattern
In the files where #include <string.h> is missing, add it, and sort the
includes.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
077f7b6ade lib/commonio.c: commonio_open(): MALLOC() and REALLOCF() already set ENOMEM
We don't need to set ENOMEM on failure of those functions.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
d611d1a947 lib/: Use REALLOCF() instead of its pattern
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
23663a1607 lib/, src/: Add missing include
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
bdf00dca44 lib/failure.c: failprint(): Remove dead code
This should have gone into the #else'd branch in 8451bed8b0, and
should have been removed in 3e602b58a2.

Fixes: 8451bed8b0 ("[svn-upgrade] Integrating new upstream version, shadow (4.0.13)")
Fixes: 3e602b58a2 ("Remove HAVE_STRFTIME ifdefs")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
bfb6aad7cb lib/, src/: Always pass NULL to time(2)
See time(2):

BUGS
     Error returns from this system  call  are  indistinguishable  from
     successful  reports  that  the  time  is  a few seconds before the
     Epoch, so the C library wrapper function never sets errno as a re‐
     sult of this call.

     The tloc argument is obsolescent and should always be NULL in  new
     code.  When tloc is NULL, the call cannot fail.

Fixes: 45c6603cc8 ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
761eb07016 lib/getdate.y: NULL doesn't need a cast
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
2cb3deec72 lib/shadow.c: my_sgetspent(): Clarify that we're assigning an empty string
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
5e11e89fd9 lib/, src/: Reduce scope of local variables
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
847a19e7a3 src/login.c: Remove dead code
The functions that set these strings --do_rlogin() and login_prompt()--
make sure to terminate them with a NUL.

Fixes: 3704745289 ("* lib/defines.h: Define USER_NAME_MAX_LENGTH, based on utmp and [...]")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
e5d40a1863 src/logoutd.c: Remove unused variable
wait(2) accepts NULL if the status won't be read.  Simplify.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
89402f5171 src/su.c: save_caller_context(): Remove unused parameter
Fixes: e6c2e43937 ("Hardcoding Prog to known value")
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
40ab806066 lib/string/strcpy/, lib/, src/, tests/: Move all copying APIs to a subdirectory
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
22272347b6 lib/string/sprintf/, lib/, src/, tests/: Move all sprintf(3)-like APIs to a subdirectory
And have a separate file for each pair of APIs.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-07-01 21:40:11 -05:00
Alejandro Colomar
89e4be3957 src/get_subid_owners.c: Use uid_t for holding UIDs (and GIDs)
Suggested-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
1f7c00b8f7 src/usermod.c: Fix const correctness
Now that we use liba2i's const-generic macros, we can (and must) use a
'const char **' endp where the input string is 'const char *'.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
7f3ab84714 lib/limits.c: setrlimit_value(): Reimplement in terms of a2i()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
7f86f893ab lib/, po/, src/: get_uid(): Move function to "atoi/getnum.h"
Implement it as an inline function, and add restrict and ATTR_STRING()
and ATTR_ACCESS() as appropriate.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
6093c93e81 lib/get_uid.c: get_uid(): Reimplement in terms of a2i()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
8ad2768472 src/usermod.c: getulong_range(): Reimplement in terms of a2ul()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
b198c1e782 lib/get_pid.c: get_pidfd_from_fd(): Don't open-code get_fd()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
a80715448b lib/atoi/getnum.[ch]: get_fd(): Add function for parsing a file descriptor from a string
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
1557fac0a5 lib/: get_pid(): Move function to "atoi/getnum.h"
Implement it as an inline function, and add restrict and ATTR_STRING()
and ATTR_ACCESS() as appropriate.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
6fd56468c3 lib/get_pid.c: get_pid(): Reimplement in terms of a2i()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
509e3bcbf8 lib/: Don't open-code get_gid()
These functions were open-coding get_gid().  Use the actual function.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
f85a07f140 lib/, libsubid/, po/, src/: get_gid(): Move function to "atoi/getnum.h"
Implement it as an inline function, and add restrict and ATTR_STRING()
and ATTR_ACCESS() as appropriate.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
74a2ed4537 lib/get_gid.c: get_gid(): Reimplement in terms of a2i()
Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
678c2a23ee src/: Use str2[u]l() instead of atoi(3)
atoi(3) easily triggers Undefined Behavior.  Replace it by str2[u]l(),
which are safe from that, and add type safety too.

Reviewed-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
24695e6f38 tests/unit/test_typetraits.c: Add tests for typetraits.h macros
Suggested-by: "Serge E. Hallyn" <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Alejandro Colomar
500ec3f8f3 lib/typetraits.h: Add macros that give information about a type
In the case of is_unsigned() and is_signed(), the natural thing would be
to compare to 0:

	#define is_unsigned(x)  (((typeof(x)) -1) > 0)
	#define is_signed(x)    (((typeof(x)) -1) < 0)

However, that would trigger -Wtype-limits, so we compare against 1,
which silences that, and does the same job.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-29 20:00:18 +02:00
Serge Hallyn
2457fc7c6b tests/run_some: make sure unshared root user can descend build dir
This was causing errors in my local testing in vms.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-28 14:45:25 -05:00
Alejandro Colomar
488bf4a519 Makefile.am: Use 'dist-hook' to clean up <tests/unit/Makefile>
Closes: <https://github.com/shadow-maint/shadow/issues/1027>
Reported-by: Chris Hofstaedtler <zeha@debian.org>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Co-developed-by: Serge Hallyn <shallyn@cisco.com>
Signed-off-by: Serge Hallyn <shallyn@cisco.com>
Co-developed-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-28 09:37:27 -05:00
Serge Hallyn
75ea679799 have_range: open the subid db if needed
When we run for instance

  check_subid_range ubuntu u 100000 65536

when ubuntu user is defined and has that range, it returns no entries
because the subid db is not opened.  Open it in have_range if needed.

I haven't figured out why this ever worked.

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-28 16:16:33 +02:00
Serge Hallyn
81b5b26925 libsubid test makefile: fix a typo
Fix a missing space after the -I path

Signed-off-by: Serge Hallyn <serge@hallyn.com>
2024-06-28 16:16:33 +02:00
Alejandro Colomar
6e57238bf9 tests/unit/test_xasprintf.c: Fix use of volatile pointer
volatile needs to be casted away behind a [[gnu::noipa]] function, to
make that invisible to the compiler.  Otherwise, the compiler can see
that it is being discarded, and is free to abuse Undefined Behavior.

Closes: <https://github.com/shadow-maint/shadow/issues/1028>
Reported-by: Chris Hofstaedtler <zeha@debian.org>
Tested-by: Chris Hofstaedtler <zeha@debian.org>
Reviewed-by: Chris Hofstaedtler <zeha@debian.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-28 08:57:01 -05:00
Alejandro Colomar
3307a8f4f0 tests/unit/test_xasprintf.c: Cosmetic
This is in preparation for the following commit.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-28 08:57:01 -05:00
Serge Hallyn
d55367bb16 tests/: Support run_some from exported tarball
common/config.sh currently tries to find the top directory by looking
for .git.  There are also many places under tests/ where we use
hard-coded ../../.. to find things like ${TOP_DIR}/lib.

We don't actually ship the tests with 'make dist'.  So we will
be exporting tests/ as a separate tarball.  In particular, I want
to then import this in the debian package.  However, there it will
be under shadow.git/debian/tests, not shadow.git/tests.

To support this, accept the environment variable BUILD_BASE_DIR,
which should point to shadow.git.

An alternative would be to move the tests to their own git
tree.  However, keeping tests in separate git tree tends to
lead to repos getting out of sync.  And we'd still need to accept
something like BUILD_BASE_DIR.

Note there are a lot of tests under run-all, which I'm not converting
as they currently are not being run in CI, so I'm more likely to
break something.

Changelog:
  2024 05 26: Incorporate feedback from alejandro-colomar

Link: <https://salsa.debian.org/debian/shadow/-/merge_requests/21>
Link: <https://salsa.debian.org/debian/shadow/-/merge_requests/22>
Cc: Chris Hofstaedtler <zeha@debian.org>
Signed-off-by: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-26 23:59:07 +02:00
Alejandro Colomar
47edcd3045 lib/csrand.c: Fix the lower part of the domain of csrand_uniform()
I accidentally broke this code during an un-optimization.  We need to
start from a random value of the width of the limit, that is, 32 bits.

Thanks to Jason for pointing to his similar code in the kernel, which
made me see my mistake.

Fixes: 2a61122b5e ("Unoptimize the higher part of the domain of csrand_uniform()")
Closes: <https://github.com/shadow-maint/shadow/issues/1015>
Reported-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Link: <https://git.zx2c4.com/linux-rng/tree/drivers/char/random.c#n535>
Cc: "Jason A. Donenfeld" <Jason@zx2c4.com>
Link: <https://github.com/shadow-maint/shadow/pull/638>
Link: <https://github.com/shadow-maint/shadow/issues/634>
Link: <https://github.com/shadow-maint/shadow/pull/624>
Tested-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Reviewed-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
2024-06-20 21:38:58 -05:00
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
412 changed files with 5114 additions and 8796 deletions

View File

@@ -5,8 +5,21 @@ runs:
steps:
- shell: bash
run: |
sudo apt-get update -y
sudo apt-get install -y ubuntu-dev-tools libbsd-dev
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
sudo apt-get update -y
if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then
echo "Found new-style sources.list.d"
cat /etc/apt/sources.list.d/ubuntu.sources
sudo sed -i 's/^Types: deb/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources
else
echo "Found legacy sources.list"
cat /etc/apt/sources.list
sudo sed -i '/deb-src/d' /etc/apt/sources.list
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
fi
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
# let's try to work around upgrade breakage in a pkg we don't care about
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev libltdl-dev pkgconf
sudo apt-get -y build-dep shadow

View File

@@ -25,18 +25,8 @@ jobs:
cat /proc/self/status
systemd-detect-virt
- name: Install dependencies
run: |
sudo cat /etc/apt/sources.list
sudo sed -i '/deb-src/d' /etc/apt/sources.list
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
# let's try to work around upgrade breakage in a pkg we don't care about
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf libcmocka-dev
sudo apt-get -y build-dep shadow
id: dependencies
uses: ./.github/actions/install-dependencies
- name: configure
run: |
autoreconf -v -f --install
@@ -61,18 +51,8 @@ jobs:
uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo cat /etc/apt/sources.list
sudo sed -i '/deb-src/d' /etc/apt/sources.list
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
# let's try to work around upgrade breakage in a pkg we don't care about
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf
sudo apt-get -y build-dep shadow
id: dependencies
uses: ./.github/actions/install-dependencies
- name: Test make dist
run: |
@@ -89,6 +69,7 @@ jobs:
container-build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [alpine, debian, fedora]
@@ -96,15 +77,25 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install Ansible
run: |
sudo apt-get update
sudo apt-get -y install ansible
- name: Build container
run: |
docker buildx build -f ./share/containers/${{ matrix.os }}.dockerfile . --output build-out
pushd share/ansible/
ansible-playbook playbook.yml -i inventory.ini -e 'distribution=${{ matrix.os }}'
popd
- name: Store artifacts
uses: actions/upload-artifact@v3
if: always()
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.os }}-build
path: |
./build-out/config.log
./build-out/config.h
./share/ansible/build-out/config.log
./share/ansible/build-out/config.h
./share/ansible/build-out/build.log
./share/ansible/build-out/test-suite.log
if-no-files-found: ignore

View File

@@ -1,7 +1,5 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = NEWS README
SUBDIRS = lib
if ENABLE_SUBIDS
@@ -16,7 +14,7 @@ endif
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
EXTRA_DIST = tests/
EXTRA_DIST = NEWS README tests/
dist-hook:
chmod -R u+w $(distdir)/tests

View File

@@ -1,10 +1,10 @@
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.3], [pkg-shadow-devel@lists.alioth.debian.org], [],
AC_INIT([shadow], [4.17.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
AC_CONFIG_MACRO_DIRS([m4])
@@ -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
@@ -696,7 +689,7 @@ AC_SUBST(LIBMD)
if test "$with_skey" = "yes"; then
AC_CHECK_LIB(md, MD5Init, [LIBMD=-lmd])
AC_CHECK_LIB(skey, skeychallenge, [LIBSKEY=-lskey],
[AC_MSG_ERROR([liskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
[AC_MSG_ERROR([libskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
AC_DEFINE(SKEY, 1, [Define to support S/Key logins.])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>

View File

@@ -118,6 +118,9 @@
#include <sys/stat.h>
#include <syslog.h>
#include "string/strcmp/streq.h"
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
* immediately upon next login */
#define HAVE_QUOTAS /* Obvious */
@@ -291,12 +294,10 @@ main (void)
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
fflush (stdout);
safeget (dir, sizeof (dir));
if (!strlen (dir))
{ /* hit return */
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
if (!strlen(dir)) /* hit return */
sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
else if (dir[strlen (dir) - 1] == '/')
sprintf (dir+strlen(dir), "%s", usrname);
strcat(dir, usrname);
}
else
{
@@ -308,7 +309,7 @@ main (void)
fflush (stdout);
safeget (shell, sizeof (shell));
if (!strlen (shell))
sprintf (shell, "%s", DEFAULT_SHELL);
strcpy(shell, DEFAULT_SHELL);
else
{
char *sh;
@@ -316,7 +317,7 @@ main (void)
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((sh = getusershell ()) != NULL)
if (!strcmp (shell, sh))
if (streq(shell, sh))
ok = 1;
endusershell ();
#endif
@@ -327,7 +328,7 @@ main (void)
else
{
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
sprintf (shell, "%s", DEFAULT_SHELL);
strcpy(shell, DEFAULT_SHELL);
}
}
}
@@ -491,12 +492,12 @@ safeget (char *buf, int maxlen)
bad = (!isalnum (c) && (c != '_') && (c != ' '));
*(buf++) = c;
}
*buf = '\0';
stpcpy(buf, "");
if (bad)
{
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
*bstart = '\0';
stpcpy(bstart, "");
}
}

View File

@@ -471,12 +471,12 @@
The Shadow Suite contains replacement programs for:
su, login, passwd, newgrp, chfn, chsh, and id
su, login, passwd, newgrp, chfn, chsh
The package also contains the new programs:
chage, newusers, dpasswd, gpasswd, useradd, userdel, usermod,
groupadd, groupdel, groupmod, groups, pwck, grpck, lastlog, pwconv,
groupadd, groupdel, groupmod, pwck, grpck, lastlog, pwconv,
and pwunconv
Additionally, the library: libshadow.a is included for writing and/or
@@ -586,8 +586,6 @@
· /usr/bin/chsh
· /usr/bin/id
The BETA package has a save target in the Makefile, but it's commented
out because different distributions place the programs in different
places.
@@ -637,8 +635,6 @@
· /usr/man/man1/chsh.1.gz
· /usr/man/man1/id.1.gz
· /usr/man/man1/login.1.gz
· /usr/man/man1/passwd.1.gz
@@ -1377,7 +1373,7 @@
users or changing the group password, the /etc/gshadow file will be
changed.
The programs groups, groupadd, groupmod, and groupdel are provided as
The programs groupadd, groupmod, and groupdel are provided as
part of the Shadow Suite to modify groups.
The format of the /etc/group file is as follows:

View File

@@ -62,9 +62,11 @@ You can either generate a single image by running the following command from
the root folder of the project (i.e. Alpine):
```
docker build -f share/containers/alpine.dockerfile . --output build-out/alpine
ansible-playbook share/ansible/playbook.yml -i share/ansible/inventory.ini -e 'distribution=alpine'
```
**Note**: you'll need to install ansible to run this automation.
Or generate all of the images with the `container-build.sh` script, as if you
were running some of the CI checks locally:

View File

@@ -72,6 +72,6 @@ understand the project's development model:
* [Build & install](build_install.md)
* [Coding style](coding_style.md)
* [Tests](tests.md)
* [Continuous Integration](CI.md)
* [Continuous Integration](ci.md)
* [Releases](releases.md)
* [License](license.md)

View File

@@ -29,16 +29,48 @@ libshadow_la_SOURCES = \
age.c \
agetpass.c \
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 \
atoi/strtou_noneg.h \
alloc/calloc.c \
alloc/calloc.h \
alloc/malloc.c \
alloc/malloc.h \
alloc/realloc.c \
alloc/realloc.h \
alloc/reallocf.c \
alloc/reallocf.h \
alloc/x/xcalloc.c \
alloc/x/xcalloc.h \
alloc/x/xmalloc.c \
alloc/x/xmalloc.h \
alloc/x/xrealloc.c \
alloc/x/xrealloc.h \
atoi/a2i/a2i.c \
atoi/a2i/a2i.h \
atoi/a2i/a2s.c \
atoi/a2i/a2s.h \
atoi/a2i/a2s_c.c \
atoi/a2i/a2s_c.h \
atoi/a2i/a2s_nc.c \
atoi/a2i/a2s_nc.h \
atoi/a2i/a2u.c \
atoi/a2i/a2u.h \
atoi/a2i/a2u_c.c \
atoi/a2i/a2u_c.h \
atoi/a2i/a2u_nc.c \
atoi/a2i/a2u_nc.h \
atoi/getnum.c \
atoi/getnum.h \
atoi/str2i/str2i.c \
atoi/str2i/str2i.h \
atoi/str2i/str2s.c \
atoi/str2i/str2s.h \
atoi/str2i/str2u.c \
atoi/str2i/str2u.h \
atoi/strtoi/strtoi.c \
atoi/strtoi/strtoi.h \
atoi/strtoi/strtou.c \
atoi/strtoi/strtou.h \
atoi/strtoi/strtou_noneg.c \
atoi/strtoi/strtou_noneg.h \
attr.h \
audit_help.c \
basename.c \
@@ -71,9 +103,11 @@ libshadow_la_SOURCES = \
find_new_sub_gids.c \
find_new_sub_uids.c \
fputsx.c \
get_gid.c \
fs/readlink/areadlink.c \
fs/readlink/areadlink.h \
fs/readlink/readlinknul.c \
fs/readlink/readlinknul.h \
get_pid.c \
get_uid.c \
getdate.h \
getdate.y \
getdef.c \
@@ -94,8 +128,6 @@ libshadow_la_SOURCES = \
lockpw.c \
loginprompt.c \
mail.c \
memzero.c \
memzero.h \
motd.c \
must_be.h \
myname.c \
@@ -119,7 +151,6 @@ libshadow_la_SOURCES = \
pwdcheck.c \
pwmem.c \
remove_tree.c \
rlogin.c \
root_flag.c \
run_part.h \
run_part.c \
@@ -145,18 +176,42 @@ libshadow_la_SOURCES = \
spawn.c \
sssd.c \
sssd.h \
string/sprintf.c \
string/sprintf.h \
string/stpecpy.c \
string/stpecpy.h \
string/stpeprintf.c \
string/stpeprintf.h \
string/memset/memzero.c \
string/memset/memzero.h \
string/sprintf/snprintf.c \
string/sprintf/snprintf.h \
string/sprintf/stpeprintf.c \
string/sprintf/stpeprintf.h \
string/sprintf/xasprintf.c \
string/sprintf/xasprintf.h \
string/strchr/strchrcnt.c \
string/strchr/strchrcnt.h \
string/strchr/stpspn.c \
string/strchr/stpspn.h \
string/strchr/strnul.c \
string/strchr/strnul.h \
string/strchr/strrspn.c \
string/strchr/strrspn.h \
string/strcmp/streq.c \
string/strcmp/streq.h \
string/strcpy/stpecpy.c \
string/strcpy/stpecpy.h \
string/strcpy/strncat.c \
string/strcpy/strncat.h \
string/strcpy/strncpy.c \
string/strcpy/strncpy.h \
string/strcpy/strtcpy.c \
string/strcpy/strtcpy.h \
string/strdup/strndupa.c \
string/strdup/strndupa.h \
string/strdup/xstrdup.c \
string/strdup/xstrdup.h \
string/strdup/xstrndup.c \
string/strdup/xstrndup.h \
string/strftime.c \
string/strftime.h \
string/strncpy.h \
string/strtcpy.c \
string/strtcpy.h \
string/zustr2stp.h \
string/strtok/stpsep.c \
string/strtok/stpsep.h \
strtoday.c \
sub.c \
subordinateio.h \
@@ -165,6 +220,7 @@ libshadow_la_SOURCES = \
time/day_to_str.c \
time/day_to_str.h \
ttytype.c \
typetraits.h \
tz.c \
ulimit.c \
user_busy.c \

View File

@@ -14,28 +14,30 @@
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include <grp.h>
#include <errno.h>
#include <grp.h>
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "alloc/malloc.h"
#include "alloc/reallocf.h"
#include "shadowlog.h"
#ident "$Id$"
#define SEP ",:"
/*
* Add groups with names from LIST (separated by commas or colons)
* to the supplementary group set. Silently ignore groups which are
* already there. Warning: uses strtok().
* already there.
*/
int add_groups (const char *list)
int
add_groups(const char *list)
{
GETGROUPS_T *grouplist;
size_t i;
int ngroups;
bool added;
char *token;
char *g, *p;
char buf[1024];
int ret;
FILE *shadow_logfd = log_get_logfd();
@@ -70,13 +72,13 @@ int add_groups (const char *list)
}
added = false;
for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) {
p = buf;
while (NULL != (g = strsep(&p, ",:"))) {
struct group *grp;
grp = getgrnam (token); /* local, no need for xgetgrnam */
grp = getgrnam(g); /* local, no need for xgetgrnam */
if (NULL == grp) {
fprintf (shadow_logfd, _("Warning: unknown group %s\n"),
token);
fprintf(shadow_logfd, _("Warning: unknown group %s\n"), g);
continue;
}

View File

@@ -16,7 +16,7 @@
#ident "$Id$"
#include "alloc.h"
#include "alloc/malloc.h"
#if WITH_LIBBSD == 0
#include "freezero.h"

View File

@@ -1,73 +0,0 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 , Nicolas François
* SPDX-FileCopyrightText: 2023 , Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Replacements for malloc and strdup with error checking. Too trivial
to be worth copyrighting :-). I did that because a lot of code used
malloc and strdup without checking for NULL pointer, and I like some
message better than a core dump... --marekm
Yeh, but. Remember that bailing out might leave the system in some
bizarre state. You really want to put in error checking, then add
some back-out failure recovery code. -- jfh */
#include <config.h>
#ident "$Id$"
#include "alloc.h"
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
extern inline void *xmalloc(size_t size);
extern inline void *xmallocarray(size_t nmemb, size_t size);
extern inline void *mallocarray(size_t nmemb, size_t size);
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
extern inline char *xstrdup(const char *str);
void *
xcalloc(size_t nmemb, size_t size)
{
void *p;
p = calloc(nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}
void *
xreallocarray(void *p, size_t nmemb, size_t size)
{
p = reallocarrayf(p, nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}

View File

@@ -1,101 +0,0 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
#define SHADOW_INCLUDE_LIB_MALLOC_H_
#include <config.h>
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "attr.h"
#include "defines.h"
#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
#define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type)))
#define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
#define REALLOC(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) reallocarray(ptr, n, sizeof(type))) \
)
#define REALLOCF(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) reallocarrayf(ptr, n, sizeof(type))) \
)
#define XREALLOC(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
)
ATTR_MALLOC(free)
inline void *xmalloc(size_t size);
ATTR_MALLOC(free)
inline void *xmallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *mallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline char *xstrdup(const char *str);
ATTR_MALLOC(free)
void *xcalloc(size_t nmemb, size_t size);
ATTR_MALLOC(free)
void *xreallocarray(void *p, size_t nmemb, size_t size);
inline void *
xmalloc(size_t size)
{
return xmallocarray(1, size);
}
inline void *
xmallocarray(size_t nmemb, size_t size)
{
return xreallocarray(NULL, nmemb, size);
}
inline void *
mallocarray(size_t nmemb, size_t size)
{
return reallocarray(NULL, nmemb, size);
}
inline void *
reallocarrayf(void *p, size_t nmemb, size_t size)
{
void *q;
q = reallocarray(p, nmemb, size);
/* realloc(p, 0) is equivalent to free(p); avoid double free. */
if (q == NULL && nmemb != 0 && size != 0)
free(p);
return q;
}
inline char *
xstrdup(const char *str)
{
return strcpy(XMALLOC(strlen(str) + 1, char), str);
}
#endif // include guard

11
lib/alloc/calloc.c Normal file
View File

@@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/calloc.h"

20
lib/alloc/calloc.h Normal file
View File

@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_CALLOC_H_
#define SHADOW_INCLUDE_LIB_ALLOC_CALLOC_H_
#include <config.h>
#include <stdlib.h>
#define CALLOC(n, type) \
( \
(type *) calloc(n, sizeof(type)) \
)
#endif // include guard

16
lib/alloc/malloc.c Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/malloc.h"
#include <stddef.h>
extern inline void *mallocarray(size_t nmemb, size_t size);

34
lib/alloc/malloc.h Normal file
View File

@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_MALLOC_H_
#define SHADOW_INCLUDE_LIB_ALLOC_MALLOC_H_
#include <config.h>
#include <stdlib.h>
#include "attr.h"
#define MALLOC(n, type) \
( \
(type *) mallocarray(n, sizeof(type)) \
)
ATTR_ALLOC_SIZE(1, 2)
ATTR_MALLOC(free)
inline void *mallocarray(size_t nmemb, size_t size);
inline void *
mallocarray(size_t nmemb, size_t size)
{
return reallocarray(NULL, nmemb, size);
}
#endif // include guard

11
lib/alloc/realloc.c Normal file
View File

@@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/realloc.h"

20
lib/alloc/realloc.h Normal file
View File

@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_REALLOC_H_
#define SHADOW_INCLUDE_LIB_ALLOC_REALLOC_H_
#include <config.h>
#include <stdlib.h>
#define REALLOC(p, n, type) \
( \
_Generic(p, type *: (type *) reallocarray(p, (n) ?: 1, sizeof(type))) \
)
#endif // include guard

16
lib/alloc/reallocf.c Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/reallocf.h"
#include <stddef.h>
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);

41
lib/alloc/reallocf.h Normal file
View File

@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_REALLOCF_H_
#define SHADOW_INCLUDE_LIB_ALLOC_REALLOCF_H_
#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include "attr.h"
#define REALLOCF(p, n, type) \
( \
_Generic(p, type *: (type *) reallocarrayf(p, (n) ?: 1, sizeof(type)))\
)
ATTR_ALLOC_SIZE(2, 3)
ATTR_MALLOC(free)
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
inline void *
reallocarrayf(void *p, size_t nmemb, size_t size)
{
void *q;
q = reallocarray(p, nmemb ?: 1, size ?: 1);
if (q == NULL)
free(p);
return q;
}
#endif // include guard

36
lib/alloc/x/xcalloc.c Normal file
View File

@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/x/xcalloc.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "defines.h"
#include "shadowlog.h"
void *
xcalloc(size_t nmemb, size_t size)
{
void *p;
p = calloc(nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}

28
lib/alloc/x/xcalloc.h Normal file
View File

@@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_X_XCALLOC_H_
#define SHADOW_INCLUDE_LIB_ALLOC_X_XCALLOC_H_
#include <config.h>
#include <stddef.h>
#include <stdlib.h>
#include "attr.h"
#define XCALLOC(n, type) \
( \
(type *) xcalloc(n, sizeof(type)) \
)
ATTR_ALLOC_SIZE(1, 2)
ATTR_MALLOC(free)
void *xcalloc(size_t nmemb, size_t size);
#endif // include guard

16
lib/alloc/x/xmalloc.c Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/x/xmalloc.h"
#include <stddef.h>
extern inline void *xmallocarray(size_t nmemb, size_t size);

35
lib/alloc/x/xmalloc.h Normal file
View File

@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ALLOC_X_XMALLOC_H_
#define SHADOW_INCLUDE_LIB_ALLOC_X_XMALLOC_H_
#include <config.h>
#include <stddef.h>
#include "alloc/x/xrealloc.h"
#include "attr.h"
#define XMALLOC(n, type) \
( \
(type *) xmallocarray(n, sizeof(type)) \
)
ATTR_ALLOC_SIZE(1, 2)
ATTR_MALLOC(free)
inline void *xmallocarray(size_t nmemb, size_t size);
inline void *
xmallocarray(size_t nmemb, size_t size)
{
return xreallocarray(NULL, nmemb, size);
}
#endif // include guard

35
lib/alloc/x/xrealloc.c Normal file
View File

@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2008 , Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "alloc/x/xrealloc.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "alloc/reallocf.h"
#include "defines.h"
#include "shadowlog.h"
void *
xreallocarray(void *p, size_t nmemb, size_t size)
{
p = reallocarrayf(p, nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}

31
lib/alloc/x/xrealloc.h Normal file
View File

@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
#define SHADOW_INCLUDE_LIB_MALLOC_H_
#include <config.h>
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "attr.h"
#define XREALLOC(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
)
ATTR_ALLOC_SIZE(2, 3)
ATTR_MALLOC(free)
void *xreallocarray(void *p, size_t nmemb, size_t size);
#endif // include guard

View File

@@ -1,46 +0,0 @@
// 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);

View File

@@ -1,386 +0,0 @@
// 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

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

@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2i.h"

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

@@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2I_H_
#include <config.h>
#include "atoi/a2i/a2s_c.h"
#include "atoi/a2i/a2s_nc.h"
#include "atoi/a2i/a2u_c.h"
#include "atoi/a2i/a2u_nc.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__) \
)
#endif // include guard

7
lib/atoi/a2i/a2s.c Normal file
View File

@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2s.h"

56
lib/atoi/a2i/a2s.h Normal file
View File

@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_H_
#include <config.h>
#include "atoi/a2i/a2s_c.h"
#include "atoi/a2i/a2s_nc.h"
#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__) \
)
#endif // include guard

17
lib/atoi/a2i/a2s_c.c Normal file
View File

@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2s_c.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);

64
lib/atoi/a2i/a2s_c.h Normal file
View File

@@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_C_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_C_H_
#include <config.h>
#include <errno.h>
#include <inttypes.h>
#include "atoi/a2i/a2s_nc.h"
#include "attr.h"
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);
inline int
a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max)
{
return a2sh_nc(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_nc(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_nc(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_nc(n, (char *) s, (char **) endp, base, min, max);
}
#endif // include guard

17
lib/atoi/a2i/a2s_nc.c Normal file
View File

@@ -0,0 +1,17 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2s_nc.h"
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);

91
lib/atoi/a2i/a2s_nc.h Normal file
View File

@@ -0,0 +1,91 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_NC_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2S_NC_H_
#include <config.h>
#include <errno.h>
#include "atoi/strtoi/strtoi.h"
#include "attr.h"
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);
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;
}
#endif // include guard

7
lib/atoi/a2i/a2u.c Normal file
View File

@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2u.h"

56
lib/atoi/a2i/a2u.h Normal file
View File

@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_H_
#include <config.h>
#include "atoi/a2i/a2u_c.h"
#include "atoi/a2i/a2u_nc.h"
#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__) \
)
#endif // include guard

19
lib/atoi/a2i/a2u_c.c Normal file
View File

@@ -0,0 +1,19 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2u_c.h"
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);

65
lib/atoi/a2i/a2u_c.h Normal file
View File

@@ -0,0 +1,65 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_C_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_C_H_
#include <config.h>
#include "atoi/a2i/a2u_nc.h"
#include "attr.h"
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);
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_nc(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_nc(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_nc(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_nc(n, (char *) s, (char **) endp, base, min, max);
}
#endif // include guard

18
lib/atoi/a2i/a2u_nc.c Normal file
View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i/a2u_nc.h"
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);

94
lib/atoi/a2i/a2u_nc.h Normal file
View File

@@ -0,0 +1,94 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_NC_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_A2U_NC_H_
#include <config.h>
#include <errno.h>
#include "atoi/strtoi/strtou_noneg.h"
#include "attr.h"
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
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

16
lib/atoi/getnum.c Normal file
View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include <sys/types.h>
#include "atoi/getnum.h"
extern inline int get_fd(const char *restrict fdstr, int *restrict fd);
extern inline int get_gid(const char *restrict gidstr, gid_t *restrict gid);
extern inline int get_pid(const char *restrict pidstr, pid_t *restrict pid);
extern inline int get_uid(const char *restrict uidstr, uid_t *restrict uid);

60
lib/atoi/getnum.h Normal file
View File

@@ -0,0 +1,60 @@
// SPDX-FileCopyrightText: 2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_GETNUM_H_
#define SHADOW_INCLUDE_LIB_ATOI_GETNUM_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include <sys/types.h>
#include "atoi/a2i/a2i.h"
#include "atoi/a2i/a2s.h"
#include "attr.h"
#include "typetraits.h"
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline int get_fd(const char *restrict fdstr, int *restrict fd);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline int get_gid(const char *restrict gidstr, gid_t *restrict gid);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline int get_pid(const char *restrict pidstr, pid_t *restrict pid);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
inline int get_uid(const char *restrict uidstr, uid_t *restrict uid);
inline int
get_fd(const char *restrict fdstr, int *restrict fd)
{
return a2si(fd, fdstr, NULL, 10, 0, INT_MAX);
}
inline int
get_gid(const char *restrict gidstr, gid_t *restrict gid)
{
return a2i(gid_t, gid, gidstr, NULL, 10, type_min(gid_t), type_max(gid_t));
}
inline int
get_pid(const char *restrict pidstr, pid_t *restrict pid)
{
return a2i(pid_t, pid, pidstr, NULL, 10, 1, type_max(pid_t));
}
inline int
get_uid(const char *restrict uidstr, uid_t *restrict uid)
{
return a2i(uid_t, uid, uidstr, NULL, 10, type_min(uid_t), type_max(uid_t));
}
#endif // include guard

View File

@@ -1,108 +0,0 @@
// 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

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

@@ -0,0 +1,8 @@
// 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/str2i.h"

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

@@ -0,0 +1,31 @@
// 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_STR2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
#include <config.h>
#include "atoi/str2i/str2s.h"
#include "atoi/str2i/str2u.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__) \
)
#endif // include guard

14
lib/atoi/str2i/str2s.c Normal file
View File

@@ -0,0 +1,14 @@
// 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/str2s.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);

57
lib/atoi/str2i/str2s.h Normal file
View File

@@ -0,0 +1,57 @@
// 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_STR2S_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i/a2s.h"
#include "attr.h"
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);
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);
}
#endif // include guard

View File

@@ -5,13 +5,9 @@
#include <config.h>
#include "atoi/str2i.h"
#include "atoi/str2i/str2u.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);

57
lib/atoi/str2i/str2u.h Normal file
View File

@@ -0,0 +1,57 @@
// 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_STR2U_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i/a2u.h"
#include "attr.h"
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
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

@@ -1,15 +0,0 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtoi.h"
#include <stdint.h>
extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);
extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);

View File

@@ -1,96 +0,0 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
#include <config.h>
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include "attr.h"
#define strtoNmax(TYPE, ...) \
( \
_Generic((TYPE) 0, \
intmax_t: strtoimax, \
uintmax_t: strtoumax \
)(__VA_ARGS__) \
)
#define strtoN(s, endp, base, min, max, status, TYPE) \
({ \
const char *s_ = s; \
char **endp_ = endp; \
int base_ = base; \
TYPE min_ = min; \
TYPE max_ = max; \
int *status_ = status; \
\
int e_, st_; \
char *end_; \
TYPE n_; \
\
if (endp_ == NULL) \
endp_ = &end_; \
if (status_ == NULL) \
status_ = &st_; \
\
if (base_ != 0 && (base_ < 0 || base_ > 36)) { \
*status_ = EINVAL; \
n_ = 0; \
\
} else { \
e_ = errno; \
errno = 0; \
n_ = strtoNmax(TYPE, s_, endp_, base_); \
\
if (*endp_ == s_) \
*status_ = ECANCELED; \
else if (errno == ERANGE || n_ < min_ || n_ > max_) \
*status_ = ERANGE; \
else if (**endp_ != '\0') \
*status_ = ENOTSUP; \
else \
*status_ = 0; \
\
errno = e_; \
} \
MAX(min_, MIN(max_, n_)); \
})
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);
inline intmax_t
strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status)
{
return strtoN(s, endp, base, min, max, status, intmax_t);
}
inline uintmax_t
strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status)
{
return strtoN(s, endp, base, min, max, status, uintmax_t);
}
#endif // include guard

13
lib/atoi/strtoi/strtoi.c Normal file
View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtoi/strtoi.h"
#include <stdint.h>
extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);

64
lib/atoi/strtoi/strtoi.h Normal file
View File

@@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOI_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOI_H_
#include <config.h>
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include "attr.h"
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);
inline intmax_t
strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status)
{
int e, st;
char *end;
intmax_t n;
if (endp == NULL)
endp = &end;
if (status == NULL)
status = &st;
if (base != 0 && (base < 2 || base > 36)) {
*status = EINVAL;
return MAX(min, MIN(max, 0));
}
e = errno;
errno = 0;
n = strtoimax(s, endp, base);
if (*endp == s)
*status = ECANCELED;
else if (errno == ERANGE || n < min || n > max)
*status = ERANGE;
else if (**endp != '\0')
*status = ENOTSUP;
else
*status = 0;
errno = e;
return MAX(min, MIN(max, n));
}
#endif // include guard

13
lib/atoi/strtoi/strtou.c Normal file
View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtoi/strtou.h"
#include <stdint.h>
extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);

64
lib/atoi/strtoi/strtou.h Normal file
View File

@@ -0,0 +1,64 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_H_
#include <config.h>
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include "attr.h"
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);
inline uintmax_t
strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status)
{
int e, st;
char *end;
uintmax_t n;
if (endp == NULL)
endp = &end;
if (status == NULL)
status = &st;
if (base != 0 && (base < 2 || base > 36)) {
*status = EINVAL;
return MAX(min, 0);
}
e = errno;
errno = 0;
n = strtoumax(s, endp, base);
if (*endp == s)
*status = ECANCELED;
else if (errno == ERANGE || n < min || n > max)
*status = ERANGE;
else if (**endp != '\0')
*status = ENOTSUP;
else
*status = 0;
errno = e;
return MAX(min, MIN(max, n));
}
#endif // include guard

View File

@@ -1,10 +1,10 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtou_noneg.h"
#include "atoi/strtoi/strtou_noneg.h"
#include <stdint.h>

View File

@@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_NONEG_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_NONEG_H_
#include <config.h>
@@ -12,7 +12,8 @@
#include <stddef.h>
#include <stdint.h>
#include "atoi/strtoi.h"
#include "atoi/strtoi/strtoi.h"
#include "atoi/strtoi/strtou.h"
#include "attr.h"

View File

@@ -6,15 +6,17 @@
#if defined(__GNUC__)
# define MAYBE_UNUSED __attribute__((unused))
# define NORETURN __attribute__((__noreturn__))
# define format_attr(type, fmt, va) __attribute__((format(type, fmt, va)))
# define ATTR_ACCESS(...) __attribute__((access(__VA_ARGS__)))
# define MAYBE_UNUSED [[gnu::unused]]
# define NORETURN [[gnu::__noreturn__]]
# define format_attr(type, fmt, va) [[gnu::format(type, fmt, va)]]
# define ATTR_ACCESS(...) [[gnu::access(__VA_ARGS__)]]
# define ATTR_ALLOC_SIZE(...) [[gnu::alloc_size(__VA_ARGS__)]]
#else
# define MAYBE_UNUSED
# define NORETURN
# define format_attr(type, fmt, va)
# define ATTR_ACCESS(...)
# define ATTR_ALLOC_SIZE(...)
#endif
#if (__GNUC__ >= 11) && !defined(__clang__)
@@ -24,9 +26,9 @@
#endif
#if (__GNUC__ >= 14)
# define ATTR_STRING(...) [[gnu::null_terminated_string_arg(__VA_ARGS__)]]
# define ATTR_STRING(i) [[gnu::null_terminated_string_arg(i)]]
#else
# define ATTR_STRING(...)
# define ATTR_STRING(i)
#endif

View File

@@ -12,6 +12,9 @@
* return values:
* true - OK
* false - bad name
* errors:
* EINVAL Invalid name characters or sequences
* EOVERFLOW Name longer than maximum size
*/
@@ -24,10 +27,13 @@
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/param.h>
#include <unistd.h>
#include "defines.h"
#include "chkname.h"
#include "string/strcmp/streq.h"
int allow_bad_names = false;
@@ -43,11 +49,12 @@ login_name_max_size(void)
if (conf == -1 && errno != 0)
return LOGIN_NAME_MAX;
return conf;
return MIN(conf, PTRDIFF_MAX);
}
static bool is_valid_name (const char *name)
static bool
is_valid_name(const char *name)
{
if (allow_bad_names) {
return true;
@@ -71,13 +78,15 @@ static bool is_valid_name (const char *name)
(*name >= 'A' && *name <= 'Z') ||
(*name >= '0' && *name <= '9') ||
*name == '_' ||
*name == '.')) {
*name == '.'))
{
errno = EINVAL;
return false;
}
numeric = isdigit(*name);
while ('\0' != *++name) {
while (!streq(++name, "")) {
if (!((*name >= 'a' && *name <= 'z') ||
(*name >= 'A' && *name <= 'Z') ||
(*name >= '0' && *name <= '9') ||
@@ -85,34 +94,46 @@ static bool is_valid_name (const char *name)
*name == '.' ||
*name == '-' ||
(*name == '$' && name[1] == '\0')
)) {
))
{
errno = EINVAL;
return false;
}
numeric &= isdigit(*name);
}
return !numeric;
if (numeric) {
errno = EINVAL;
return false;
}
return true;
}
bool
is_valid_user_name(const char *name)
{
if (strlen(name) >= login_name_max_size())
if (strlen(name) >= login_name_max_size()) {
errno = EOVERFLOW;
return false;
}
return is_valid_name(name);
}
bool is_valid_group_name (const char *name)
bool
is_valid_group_name(const char *name)
{
/*
* Arbitrary limit for group names.
* HP-UX 10 limits to 16 characters
*/
if ( (GROUP_NAME_MAX_LENGTH > 0)
&& (strlen (name) > GROUP_NAME_MAX_LENGTH)) {
&& (strlen (name) > GROUP_NAME_MAX_LENGTH))
{
errno = EOVERFLOW;
return false;
}

View File

@@ -13,12 +13,15 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "prototypes.h"
#include "defines.h"
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "defines.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
static int chown_tree_at (int at_fd,
const char *path,
uid_t old_uid,
@@ -56,8 +59,8 @@ static int chown_tree_at (int at_fd,
/*
* Skip the "." and ".." entries
*/
if ( (strcmp (ent->d_name, ".") == 0)
|| (strcmp (ent->d_name, "..") == 0)) {
if ( streq(ent->d_name, ".")
|| streq(ent->d_name, "..")) {
continue;
}

View File

@@ -44,7 +44,7 @@ void do_cleanups (void)
{
unsigned int i;
/* Make sure there were no overflow */
/* Make sure there were no overflows */
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]);
if (getpid () != cleanup_pid) {

View File

@@ -11,28 +11,33 @@
#ident "$Id$"
#include "defines.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <limits.h>
#include <utime.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include "alloc.h"
#include "memzero.h"
#include "alloc/malloc.h"
#include "alloc/reallocf.h"
#include "atoi/getnum.h"
#include "commonio.h"
#include "defines.h"
#include "nscd.h"
#include "sssd.h"
#ifdef WITH_TCB
#include <tcb.h>
#endif /* WITH_TCB */
#include "prototypes.h"
#include "commonio.h"
#include "shadowlog_internal.h"
#include "string/sprintf.h"
#include "sssd.h"
#include "string/memset/memzero.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
/* local function prototypes */
@@ -194,7 +199,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
errno = EINVAL;
return 0;
}
buf[len] = '\0';
stpcpy(&buf[len], "");
if (get_pid(buf, &pid) == -1) {
if (log) {
(void) fprintf (shadow_logfd,
@@ -573,9 +578,7 @@ static void add_one_entry_nis (struct commonio_db *db,
int commonio_open (struct commonio_db *db, int mode)
{
char *buf;
char *cp;
char *line;
struct commonio_entry *p;
void *eptr = NULL;
int flags = mode;
size_t buflen;
@@ -636,21 +639,21 @@ int commonio_open (struct commonio_db *db, int mode)
buflen = BUFLEN;
buf = MALLOC(buflen, char);
if (NULL == buf) {
goto cleanup_ENOMEM;
}
if (NULL == buf)
goto cleanup_errno;
while (db->ops->fgets (buf, buflen, db->fp) == buf) {
struct commonio_entry *p;
while ( (strrchr (buf, '\n') == NULL)
&& (feof (db->fp) == 0)) {
size_t len;
buflen += BUFLEN;
cp = REALLOC(buf, buflen, char);
if (NULL == cp) {
goto cleanup_buf;
}
buf = cp;
buf = REALLOCF(buf, buflen, char);
if (NULL == buf)
goto cleanup_errno;
len = strlen (buf);
if (db->ops->fgets (buf + len,
(int) (buflen - len),
@@ -658,10 +661,7 @@ int commonio_open (struct commonio_db *db, int mode)
goto cleanup_buf;
}
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
stpsep(buf, "\n");
line = strdup (buf);
if (NULL == line) {
@@ -713,7 +713,6 @@ int commonio_open (struct commonio_db *db, int mode)
free (line);
cleanup_buf:
free (buf);
cleanup_ENOMEM:
errno = ENOMEM;
cleanup_errno:
saved_errno = errno;
@@ -832,10 +831,8 @@ int commonio_sort_wrt (struct commonio_db *shadow,
if (NULL == spw_ptr->eptr) {
continue;
}
if (strcmp (name, shadow->ops->getname (spw_ptr->eptr))
== 0) {
if (streq(name, shadow->ops->getname(spw_ptr->eptr)))
break;
}
}
if (NULL == spw_ptr) {
continue;
@@ -1036,7 +1033,7 @@ static /*@dependent@*/ /*@null@*/struct commonio_entry *next_entry_by_name (
for (p = pos; NULL != p; p = p->next) {
ep = p->eptr;
if ( (NULL != ep)
&& (strcmp (db->ops->getname (ep), name) == 0)) {
&& streq(db->ops->getname(ep), name)) {
break;
}
}
@@ -1242,7 +1239,7 @@ int commonio_rewind (struct commonio_db *db)
if (!db->isopen) {
errno = EINVAL;
return 0;
return NULL;
}
if (NULL == db->cursor) {
db->cursor = db->head;

View File

@@ -9,20 +9,25 @@
*/
#include <config.h>
#include "defines.h"
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "string/strtcpy.h"
#include "string/strcmp/streq.h"
#include "string/strcpy/strtcpy.h"
#include "string/strtok/stpsep.h"
#ident "$Id$"
/*
* This is now rather generic function which decides if "tty" is listed
* under "cfgin" in config (directly or indirectly). Fallback to default if
* something is bad.
*/
static bool is_listed (const char *cfgin, const char *tty, bool def)
static bool
is_listed(const char *cfgin, const char *tty, bool def)
{
FILE *fp;
char buf[1024], *s;
@@ -45,14 +50,13 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
if (*cons != '/') {
char *pbuf;
STRTCPY(buf, cons);
pbuf = &buf[0];
while ((s = strtok (pbuf, ":")) != NULL) {
if (strcmp (s, tty) == 0) {
pbuf = buf;
while (NULL != (s = strsep(&pbuf, ":"))) {
if (streq(s, tty)) {
return true;
}
pbuf = NULL;
}
return false;
}
@@ -72,9 +76,8 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
*/
while (fgets (buf, sizeof (buf), fp) != NULL) {
/* Remove optional trailing '\n'. */
buf[strcspn (buf, "\n")] = '\0';
if (strcmp (buf, tty) == 0) {
stpsep(buf, "\n");
if (streq(buf, tty)) {
(void) fclose (fp);
return true;
}

View File

@@ -17,9 +17,11 @@
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "alloc/x/xmalloc.h"
#include "attr.h"
#include "fs/readlink/areadlink.h"
#include "prototypes.h"
#include "defines.h"
#ifdef WITH_SELINUX
@@ -36,7 +38,8 @@
#include <attr/libattr.h>
#endif /* WITH_ATTR */
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/sprintf/xasprintf.h"
#include "string/strcmp/streq.h"
static /*@null@*/const char *src_orig;
@@ -66,7 +69,6 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static /*@null@*/char *readlink_malloc (const char *filename);
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
@@ -313,8 +315,8 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
/*
* Skip the "." and ".." entries
*/
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
if (streq(ent->d_name, ".") ||
streq(ent->d_name, ".."))
{
continue;
}
@@ -536,42 +538,6 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
return err;
}
/*
* readlink_malloc - wrapper for readlink
*
* return NULL on error.
* The return string shall be freed by the caller.
*/
static /*@null@*/char *readlink_malloc (const char *filename)
{
size_t size = 1024;
while (true) {
ssize_t nchars;
char *buffer = MALLOC(size, char);
if (NULL == buffer) {
return NULL;
}
nchars = readlink (filename, buffer, size);
if (nchars < 0) {
free(buffer);
return NULL;
}
if ((size_t) nchars < size) { /* The buffer was large enough */
/* readlink does not nul-terminate */
buffer[nchars] = '\0';
return buffer;
}
/* Try again with a bigger buffer */
free (buffer);
size *= 2;
}
}
/*
* copy_symlink - copy a symlink
*
@@ -602,10 +568,9 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
* destination directory name.
*/
oldlink = readlink_malloc (src->full_path);
if (NULL == oldlink) {
oldlink = areadlink(src->full_path);
if (NULL == oldlink)
return -1;
}
/* If src was a link to an entry of the src_orig directory itself,
* create a link to the corresponding entry in the dst_orig

View File

@@ -1,21 +1,19 @@
/*
* SPDX-FileCopyrightText: Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2022-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#ident "$Id$"
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#if HAVE_SYS_RANDOM_H
#include <sys/random.h>
#endif
#include "bit.h"
#include "defines.h"
#include "prototypes.h"
@@ -34,7 +32,7 @@ static unsigned long csrand_uniform_slow(unsigned long n);
unsigned long
csrand(void)
{
FILE *fp;
int fd;
unsigned long r;
#ifdef HAVE_GETENTROPY
@@ -56,17 +54,16 @@ csrand(void)
#endif
/* Use /dev/urandom as a last resort. */
fp = fopen("/dev/urandom", "r");
if (NULL == fp) {
fd = open("/dev/urandom", O_RDONLY);
if (fd == -1)
goto fail;
if (read(fd, &r, sizeof(r)) != sizeof(r)) {
close(fd);
goto fail;
}
if (fread(&r, sizeof(r), 1, fp) != 1) {
fclose(fp);
goto fail;
}
fclose(fp);
close(fd);
return r;
fail:

View File

@@ -16,11 +16,14 @@
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
#include "alloc/x/xmalloc.h"
#include "alloc/x/xrealloc.h"
#include "prototypes.h"
#include "defines.h"
#include "shadowlog.h"
#include "string/sprintf.h"
#include "string/sprintf/snprintf.h"
#include "string/sprintf/xasprintf.h"
#include "string/strdup/xstrdup.h"
/*

View File

@@ -18,10 +18,10 @@
#include "defines.h"
#include "faillog.h"
#include "failure.h"
#include "memzero.h"
#include "prototypes.h"
#include "string/memset/memzero.h"
#include "string/strftime.h"
#include "string/strtcpy.h"
#include "string/strcpy/strtcpy.h"
#define YEAR (365L*DAY)
@@ -82,7 +82,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
}
STRTCPY(fl->fail_line, tty);
(void) time (&fl->fail_time);
fl->fail_time = time(NULL);
/*
* Seek back to the correct position in the file and write the
@@ -126,7 +126,7 @@ static bool too_many_failures (const struct faillog *fl)
return true; /* locked until reset manually */
}
(void) time (&now);
now = time(NULL);
if ((fl->fail_time + fl->fail_locktime) < now) {
return false; /* enough time since last failure */
}
@@ -242,14 +242,12 @@ void failprint (const struct faillog *fail)
struct tm *tp;
char lasttimeb[256];
char *lasttime = lasttimeb;
time_t NOW;
if (0 == fail->fail_cnt) {
return;
}
tp = localtime (&(fail->fail_time));
(void) time (&NOW);
/*
* Print all information we have.

View File

@@ -14,7 +14,13 @@
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "prototypes.h"
#include "string/strchr/stpspn.h"
#include "string/strchr/strrspn.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
/*
* valid_field - insure that a field contains all legal characters
@@ -42,7 +48,7 @@ int valid_field (const char *field, const char *illegal)
}
/* Search if there are non-printable or control characters */
for (cp = field; '\0' != *cp; cp++) {
for (cp = field; !streq(cp, ""); cp++) {
unsigned char c = *cp;
if (!isprint (c)) {
err = 1;
@@ -62,7 +68,8 @@ int valid_field (const char *field, const char *illegal)
* prompt the user with the name of the field being changed and the
* current value.
*/
void change_field (char *buf, size_t maxsize, const char *prompt)
void
change_field(char *buf, size_t maxsize, const char *prompt)
{
char newf[200];
char *cp;
@@ -77,29 +84,17 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
return;
}
cp = strchr (newf, '\n');
if (NULL == cp) {
if (stpsep(newf, "\n") == NULL)
return;
}
*cp = '\0';
if ('\0' != newf[0]) {
if (!streq(newf, "")) {
/*
* Remove leading and trailing whitespace. This also
* makes it possible to change the field to empty, by
* entering a space. --marekm
*/
while (newf < cp && isspace (cp[-1])) {
cp--;
}
*cp = '\0';
cp = newf;
while (isspace (*cp)) {
cp++;
}
stpcpy(strrspn(newf, " \t"), "");
cp = stpspn(newf, " \t");
strcpy (buf, cp);
}
}

View File

@@ -9,10 +9,11 @@
#include <config.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include "alloc.h"
#include "alloc/calloc.h"
#include "prototypes.h"
#include "groupio.h"
#include "getdef.h"

View File

@@ -9,10 +9,11 @@
#include <config.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include "alloc.h"
#include "alloc/calloc.h"
#include "prototypes.h"
#include "pwio.h"
#include "getdef.h"
@@ -304,7 +305,7 @@ int find_new_uid(bool sys_user,
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* This UID is in use or unusable, we'll
* continue to the next.
*/
} else {
@@ -350,7 +351,7 @@ int find_new_uid(bool sys_user,
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* This UID is in use or unusable, we'll
* continue to the next.
*/
} else {
@@ -413,7 +414,7 @@ int find_new_uid(bool sys_user,
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* This UID is in use or unusable, we'll
* continue to the next.
*/
} else {
@@ -459,7 +460,7 @@ int find_new_uid(bool sys_user,
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* This UID is in use or unusable, we'll
* continue to the next.
*/
} else {

View File

@@ -10,10 +10,11 @@
#include <config.h>
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "prototypes.h"
#ident "$Id$"
#include "string/strcmp/streq.h"
/*@null@*/char *
@@ -25,7 +26,7 @@ fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f)
while (cnt > 0) {
if (fgets (cp, cnt, f) != cp) {
if (cp == buf) {
return 0;
return NULL;
} else {
break;
}
@@ -33,10 +34,8 @@ fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f)
ep = strrchr (cp, '\\');
if ((NULL != ep) && (*(ep + 1) == '\n')) {
cnt -= ep - cp;
if (cnt > 0) {
cp = ep;
*cp = '\0';
}
if (cnt > 0)
cp = stpcpy(ep, "");
} else {
break;
}
@@ -48,7 +47,7 @@ int fputsx (const char *s, FILE * stream)
{
int i;
for (i = 0; '\0' != *s; i++, s++) {
for (i = 0; !streq(s, ""); i++, s++) {
if (putc (*s, stream) == EOF) {
return EOF;
}

View File

@@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "fs/readlink/areadlink.h"
extern inline char *areadlink(const char *link);

View File

@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_FS_READLINK_AREADLINK_H_
#define SHADOW_INCLUDE_LIB_FS_READLINK_AREADLINK_H_
#include <config.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "alloc/malloc.h"
#include "attr.h"
#include "fs/readlink/readlinknul.h"
ATTR_STRING(1)
inline char *areadlink(const char *link);
// Similar to readlink(2), but allocate and terminate the string.
inline char *
areadlink(const char *link)
{
size_t size = PATH_MAX;
while (true) {
int len;
char *buf;
buf = MALLOC(size, char);
if (NULL == buf)
return NULL;
len = readlinknul(link, buf, size);
if (len != -1)
return buf;
free(buf);
if (errno != E2BIG)
return NULL;
size *= 2;
}
}
#endif // include guard

View File

@@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "fs/readlink/readlinknul.h"
#include <stddef.h>
#include <sys/types.h>
extern inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
size_t size);

View File

@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_FS_READLINK_READLINKNUL_H_
#define SHADOW_INCLUDE_LIB_FS_READLINK_READLINKNUL_H_
#include <config.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "attr.h"
#include "sizeof.h"
#define READLINKNUL(link, buf) readlinknul(link, buf, NITEMS(buf))
ATTR_STRING(1)
inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
size_t size);
// Similar to readlink(2), but terminate the string.
inline ssize_t
readlinknul(const char *restrict link, char *restrict buf, size_t size)
{
size_t ulen;
ssize_t slen;
slen = readlink(link, buf, size);
if (slen == -1)
return -1;
ulen = slen;
if (ulen == size) {
stpcpy(&buf[size-1], "");
errno = E2BIG;
return -1;
}
stpcpy(&buf[ulen], "");
return slen;
}
#endif // include guard

View File

@@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2009 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int
get_gid(const char *gidstr, gid_t *gid)
{
char *end;
long long val;
errno = 0;
val = strtoll(gidstr, &end, 10);
if ( ('\0' == *gidstr)
|| ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
return -1;
}
*gid = val;
return 0;
}

View File

@@ -1,8 +1,7 @@
/*
* SPDX-FileCopyrightText: 2009 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
@@ -14,29 +13,10 @@
#include <sys/stat.h>
#include <fcntl.h>
#include "string/sprintf.h"
#include "atoi/getnum.h"
#include "string/sprintf/snprintf.h"
int
get_pid(const char *pidstr, pid_t *pid)
{
char *end;
long long val;
errno = 0;
val = strtoll(pidstr, &end, 10);
if ( ('\0' == *pidstr)
|| ('\0' != *end)
|| (0 != errno)
|| (val < 1)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
return -1;
}
*pid = val;
return 0;
}
/*
* If use passed in fd:4 as an argument, then return the
* value '4', the fd to use.
@@ -44,20 +24,12 @@ get_pid(const char *pidstr, pid_t *pid)
*/
int get_pidfd_from_fd(const char *pidfdstr)
{
char *end;
long long val;
int pidfd;
struct stat st;
dev_t proc_st_dev, proc_st_rdev;
errno = 0;
val = strtoll(pidfdstr, &end, 10);
if ( ('\0' == *pidfdstr)
|| ('\0' != *end)
|| (0 != errno)
|| (val < 0)
|| (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {
if (get_fd(pidfdstr, &pidfd) == -1)
return -1;
}
if (stat("/proc/self/uid_map", &st) < 0) {
return -1;
@@ -66,7 +38,7 @@ int get_pidfd_from_fd(const char *pidfdstr)
proc_st_dev = st.st_dev;
proc_st_rdev = st.st_rdev;
if (fstat(val, &st) < 0) {
if (fstat(pidfd, &st) < 0) {
return -1;
}
@@ -74,7 +46,7 @@ int get_pidfd_from_fd(const char *pidfdstr)
return -1;
}
return (int)val;
return pidfd;
}
int open_pidfd(const char *pidstr)

View File

@@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2009 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int
get_uid(const char *uidstr, uid_t *uid)
{
char *end;
long long val;
errno = 0;
val = strtoll(uidstr, &end, 10);
if ( ('\0' == *uidstr)
|| ('\0' != *end)
|| (0 != errno)
|| (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
return -1;
}
*uid = val;
return 0;
}

View File

@@ -24,14 +24,16 @@
# undef static
#endif
#include <stdio.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "attr.h"
#include "getdate.h"
#include "string/strchr/stpspn.h"
#include "string/strcmp/streq.h"
#include <string.h>
/* Some old versions of bison generate parsers that use bcopy.
That loses on systems that don't provide the function, so we have
@@ -625,16 +627,16 @@ static int LookupWord (char *buff)
bool abbrev;
/* Make it lowercase. */
for (p = buff; '\0' != *p; p++)
for (p = buff; !streq(p, ""); p++)
if (isupper (*p))
*p = tolower (*p);
if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
if (streq(buff, "am") || streq(buff, "a.m."))
{
yylval.Meridian = MERam;
return tMERIDIAN;
}
if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
if (streq(buff, "pm") || streq(buff, "p.m."))
{
yylval.Meridian = MERpm;
return tMERIDIAN;
@@ -646,7 +648,7 @@ static int LookupWord (char *buff)
else if (strlen (buff) == 4 && buff[3] == '.')
{
abbrev = true;
buff[3] = '\0';
stpcpy(&buff[3], "");
}
else
abbrev = false;
@@ -661,7 +663,7 @@ static int LookupWord (char *buff)
return tp->type;
}
}
else if (strcmp (buff, tp->name) == 0)
else if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -669,17 +671,17 @@ static int LookupWord (char *buff)
}
for (tp = TimezoneTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
if (strcmp (buff, "dst") == 0)
if (streq(buff, "dst"))
return tDST;
for (tp = UnitsTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -689,9 +691,9 @@ static int LookupWord (char *buff)
i = strlen (buff) - 1;
if (buff[i] == 's')
{
buff[i] = '\0';
stpcpy(&buff[i], "");
for (tp = UnitsTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -700,7 +702,7 @@ static int LookupWord (char *buff)
}
for (tp = OtherTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -710,7 +712,7 @@ static int LookupWord (char *buff)
if (buff[1] == '\0' && isalpha (*buff))
{
for (tp = MilitaryTable; tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -718,15 +720,15 @@ static int LookupWord (char *buff)
}
/* Drop out any periods and try the timezone table again. */
for (i = 0, p = q = buff; '\0' != *q; q++)
for (i = 0, p = q = buff; !streq(q, ""); q++)
if (*q != '.')
*p++ = *q;
else
i++;
*p = '\0';
stpcpy(p, "");
if (0 != i)
for (tp = TimezoneTable; NULL != tp->name; tp++)
if (strcmp (buff, tp->name) == 0)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
@@ -746,8 +748,7 @@ yylex (void)
for (;;)
{
while (isspace (*yyInput))
yyInput++;
yyInput = stpspn(yyInput, " \t");
if (isdigit (c = *yyInput) || c == '-' || c == '+')
{
@@ -772,7 +773,7 @@ yylex (void)
for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
if (p < &buff[sizeof buff - 1])
*p++ = c;
*p = '\0';
stpcpy(p, "");
yyInput--;
return LookupWord (buff);
}
@@ -821,7 +822,7 @@ time_t get_date (const char *p, const time_t *now)
time_t Start;
yyInput = p;
Start = now ? *now : time ((time_t *) NULL);
Start = now ? *now : time(NULL);
tmp = localtime (&Start);
yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
yyMonth = tmp->tm_mon + 1;
@@ -935,7 +936,7 @@ main(void)
buff[MAX_BUFF_LEN] = 0;
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
{
d = get_date (buff, (time_t *) NULL);
d = get_date(buff, NULL);
if (d == -1)
(void) printf ("Bad format - couldn't convert.\n");
else

View File

@@ -11,22 +11,29 @@
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#ifdef USE_ECONF
#include <libeconf.h>
#endif
#include "alloc.h"
#include "atoi/str2i.h"
#include "atoi/a2i/a2s.h"
#include "atoi/a2i/a2u.h"
#include "atoi/str2i/str2u.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/sprintf.h"
#include "string/sprintf/xasprintf.h"
#include "string/strchr/stpspn.h"
#include "string/strchr/strrspn.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
/*
@@ -151,7 +158,6 @@ static struct itemdef def_table[] = {
{NULL, NULL}
};
#define NUMKNOWNDEFS (sizeof(knowndef_table)/sizeof(knowndef_table[0]))
static struct itemdef knowndef_table[] = {
#ifdef USE_PAM
PAMDEFS
@@ -232,10 +238,11 @@ bool getdef_bool (const char *item)
* values are handled.
*/
int getdef_num (const char *item, int dflt)
int
getdef_num(const char *item, int dflt)
{
struct itemdef *d;
long val;
int val;
struct itemdef *d;
if (!def_loaded) {
def_load ();
@@ -246,9 +253,7 @@ int getdef_num (const char *item, int dflt)
return dflt;
}
if ( (str2sl(&val, d->value) == -1)
|| (val > INT_MAX)
|| (val < -1)) {
if (a2si(&val, d->value, NULL, 0, -1, INT_MAX) == -1) {
fprintf (shadow_logfd,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
@@ -267,10 +272,11 @@ int getdef_num (const char *item, int dflt)
* values are handled.
*/
unsigned int getdef_unum (const char *item, unsigned int dflt)
unsigned int
getdef_unum(const char *item, unsigned int dflt)
{
struct itemdef *d;
long val;
unsigned int val;
struct itemdef *d;
if (!def_loaded) {
def_load ();
@@ -281,9 +287,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
return dflt;
}
if ( (str2sl(&val, d->value) == -1)
|| (val < 0)
|| (val > INT_MAX)) {
if (a2ui(&val, d->value, NULL, 0, 0, UINT_MAX) == -1) {
fprintf (shadow_logfd,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
@@ -316,7 +320,7 @@ long getdef_long (const char *item, long dflt)
return dflt;
}
if (str2sl(&val, d->value) == -1 || val < -1) {
if (a2sl(&val, d->value, NULL, 0, -1, LONG_MAX) == -1) {
fprintf (shadow_logfd,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
@@ -416,7 +420,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, cons
*/
for (ptr = def_table; NULL != ptr->name; ptr++) {
if (strcmp (ptr->name, name) == 0) {
if (streq(ptr->name, name)) {
return ptr;
}
}
@@ -426,7 +430,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, cons
*/
for (ptr = knowndef_table; NULL != ptr->name; ptr++) {
if (strcmp (ptr->name, name) == 0) {
if (streq(ptr->name, name)) {
goto out;
}
}
@@ -526,7 +530,6 @@ static void def_load (void)
#else /* USE_ECONF */
static void def_load (void)
{
int i;
FILE *fp;
char buf[1024], *name, *value, *s;
@@ -558,28 +561,21 @@ static void def_load (void)
/*
* Trim trailing whitespace.
*/
for (i = (ptrdiff_t) strlen (buf) - 1; i >= 0; --i) {
if (!isspace (buf[i])) {
break;
}
}
i++;
buf[i] = '\0';
stpcpy(strrspn(buf, " \t\n"), "");
/*
* Break the line into two fields.
*/
name = buf + strspn (buf, " \t"); /* first nonwhite */
if (*name == '\0' || *name == '#')
name = stpspn(buf, " \t"); /* first nonwhite */
if (streq(name, "") || *name == '#')
continue; /* comment or empty */
s = name + strcspn (name, " \t"); /* end of field */
if (*s == '\0')
s = stpsep(name, " \t"); /* next field */
if (s == NULL)
continue; /* only 1 field?? */
*s++ = '\0';
value = s + strspn (s, " \"\t"); /* next nonwhite */
*(value + strcspn (value, "\"")) = '\0';
value = stpspn(s, " \"\t"); /* next nonwhite */
stpsep(value, "\"");
/*
* Store the value in def_table.

View File

@@ -1,11 +1,10 @@
/*
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 1991-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2000-2006, Tomasz Kłoczko
// 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>
@@ -14,30 +13,27 @@
#include <stdlib.h>
#include <errno.h>
#include <grp.h>
#include <sys/types.h>
#include "atoi/getnum.h"
#include "prototypes.h"
/*
* getgr_nam_gid - Return a pointer to the group specified by a string.
* The string may be a valid GID or a valid groupname.
* If the group does not exist on the system, NULL is returned.
*/
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname)
extern /*@only@*//*@null@*/struct group *
getgr_nam_gid(/*@null@*/const char *grname)
{
char *end;
long long gid;
gid_t gid;
if (NULL == grname) {
if (NULL == grname)
return NULL;
}
errno = 0;
gid = strtoll(grname, &end, 10);
if ( ('\0' != *grname)
&& ('\0' == *end)
&& (0 == errno)
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
return xgetgrgid (gid);
}
return xgetgrnam (grname);
if (get_gid(grname, &gid) == 0)
return xgetgrgid(gid);
return xgetgrnam(grname);
}

View File

@@ -10,9 +10,10 @@
#include <ctype.h>
#include <stdlib.h>
#include "atoi/a2i.h"
#include "atoi/a2i/a2u.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
/*
@@ -53,7 +54,7 @@ getrange(const char *range,
return 0; /* <long> */
case '-':
if ('\0' == *end)
if (streq(end, ""))
return 0; /* <long>- */
parse_max:
if (!isdigit((unsigned char) *end))

View File

@@ -11,7 +11,7 @@
#include <limits.h>
#include <stdio.h>
#include "atoi/a2i.h"
#include "atoi/a2i/a2i.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"

View File

@@ -15,12 +15,14 @@
#include <assert.h>
#include <stdio.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "alloc/calloc.h"
#include "alloc/malloc.h"
#include "commonio.h"
#include "defines.h"
#include "getdef.h"
#include "groupio.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
static /*@null@*/struct commonio_entry *merge_group_entries (
@@ -262,8 +264,8 @@ static int group_open_hook (void)
struct group *g2 = gr2->eptr;
if (NULL != g1 &&
NULL != g2 &&
0 == strcmp (g1->gr_name, g2->gr_name) &&
0 == strcmp (g1->gr_passwd, g2->gr_passwd) &&
streq(g1->gr_name, g2->gr_name) &&
streq(g1->gr_passwd, g2->gr_passwd) &&
g1->gr_gid == g2->gr_gid) {
/* Both group entries refer to the same
* group. It is a split group. Merge the
@@ -331,7 +333,7 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = gptr1->gr_mem;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
if (streq(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;
@@ -354,7 +356,7 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = new_members;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
if (streq(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;

View File

@@ -12,11 +12,13 @@
#ident "$Id$"
#include "alloc.h"
#include "memzero.h"
#include "alloc/calloc.h"
#include "alloc/malloc.h"
#include "prototypes.h"
#include "defines.h"
#include "groupio.h"
#include "string/memset/memzero.h"
/*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent)
{
@@ -81,10 +83,9 @@ void
gr_free(/*@only@*/struct group *grent)
{
free (grent->gr_name);
if (NULL != grent->gr_passwd) {
strzero (grent->gr_passwd);
free (grent->gr_passwd);
}
if (NULL != grent->gr_passwd)
free(strzero(grent->gr_passwd));
gr_free_members(grent);
free (grent);
}

View File

@@ -14,45 +14,40 @@
#ident "$Id$"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "prototypes.h"
#include "alloc/malloc.h"
#include "alloc/realloc.h"
#include "alloc/x/xmalloc.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strchr/strchrcnt.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
static /*@null@*/FILE *shadow;
static /*@null@*//*@only@*/char **members = NULL;
static size_t nmembers = 0;
static /*@null@*//*@only@*/char **admins = NULL;
static size_t nadmins = 0;
static struct sgrp sgroup;
static struct sgrp sgroup = {};
#define FIELDS 4
static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
static /*@null@*/char **
build_list(char *s)
{
char **ptr = *list;
size_t nelem = *nlist, size;
char **l;
size_t i;
while (s != NULL && *s != '\0') {
size = (nelem + 1) * sizeof (ptr);
ptr = REALLOC(*list, size, char *);
if (NULL != ptr) {
ptr[nelem] = strsep(&s, ",");
nelem++;
*list = ptr;
*nlist = nelem;
}
}
size = (nelem + 1) * sizeof (ptr);
ptr = REALLOC(*list, size, char *);
if (NULL != ptr) {
ptr[nelem] = NULL;
*list = ptr;
}
return ptr;
l = XMALLOC(strchrcnt(s, ',') + 2, char *);
for (i = 0; s != NULL && !streq(s, ""); i++)
l[i] = strsep(&s, ",");
l[i] = NULL;
return l;
}
void setsgent (void)
@@ -73,7 +68,8 @@ void endsgent (void)
shadow = NULL;
}
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
/*@observer@*//*@null@*/struct sgrp *
sgetsgent(const char *string)
{
static char *sgrbuf = NULL;
static size_t sgrbuflen = 0;
@@ -85,19 +81,15 @@ void endsgent (void)
if (len > sgrbuflen) {
char *buf = REALLOC(sgrbuf, len, char);
if (NULL == buf) {
if (NULL == buf)
return NULL;
}
sgrbuf = buf;
sgrbuflen = len;
}
strcpy (sgrbuf, string);
cp = strrchr (sgrbuf, '\n');
if (NULL != cp) {
*cp = '\0';
}
stpsep(sgrbuf, "\n");
/*
* There should be exactly 4 colon separated fields. Find
@@ -113,22 +105,16 @@ void endsgent (void)
*/
if (NULL != cp || i != FIELDS)
return 0;
return NULL;
sgroup.sg_name = fields[0];
sgroup.sg_passwd = fields[1];
if (0 != nadmins) {
nadmins = 0;
free (admins);
admins = NULL;
}
if (0 != nmembers) {
nmembers = 0;
free (members);
members = NULL;
}
sgroup.sg_adm = build_list (fields[2], &admins, &nadmins);
sgroup.sg_mem = build_list (fields[3], &members, &nmembers);
free(sgroup.sg_adm);
free(sgroup.sg_mem);
sgroup.sg_adm = build_list(fields[2]);
sgroup.sg_mem = build_list(fields[3]);
return &sgroup;
}
@@ -159,32 +145,29 @@ void endsgent (void)
return NULL;
}
if (fgetsx(buf, buflen, fp) == buf) {
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (fp) == 0)) {
size_t len;
if (fgetsx(buf, buflen, fp) == NULL)
return NULL;
cp = REALLOC(buf, buflen * 2, char);
if (NULL == cp) {
return NULL;
}
buf = cp;
buflen *= 2;
while ( (strrchr(buf, '\n') == NULL)
&& (feof (fp) == 0)) {
size_t len;
len = strlen (buf);
if (fgetsx (&buf[len],
(int) (buflen - len),
fp) != &buf[len]) {
return NULL;
}
cp = REALLOC(buf, buflen * 2, char);
if (NULL == cp) {
return NULL;
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
buf = cp;
buflen *= 2;
len = strlen (buf);
if (fgetsx (&buf[len],
(int) (buflen - len),
fp) != &buf[len]) {
return NULL;
}
return (sgetsgent (buf));
}
return NULL;
stpsep(buf, "\n");
return (sgetsgent (buf));
}
/*
@@ -210,7 +193,7 @@ void endsgent (void)
setsgent ();
while ((sgrp = getsgent ()) != NULL) {
if (strcmp (name, sgrp->sg_name) == 0) {
if (streq(name, sgrp->sg_name)) {
break;
}
}
@@ -253,53 +236,36 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
/*
* Copy the group name and passwd.
*/
strcpy (cp, sgrp->sg_name);
cp += strlen (cp);
*cp++ = ':';
strcpy (cp, sgrp->sg_passwd);
cp += strlen (cp);
*cp++ = ':';
cp = stpcpy(stpcpy(cp, sgrp->sg_name), ":");
cp = stpcpy(stpcpy(cp, sgrp->sg_passwd), ":");
/*
* Copy the administrators, separating each from the other
* with a ",".
*/
for (i = 0; NULL != sgrp->sg_adm[i]; i++) {
if (i > 0) {
*cp++ = ',';
}
if (i > 0)
cp = stpcpy(cp, ",");
strcpy (cp, sgrp->sg_adm[i]);
cp += strlen (cp);
cp = stpcpy(cp, sgrp->sg_adm[i]);
}
*cp = ':';
cp++;
cp = stpcpy(cp, ":");
/*
* Now do likewise with the group members.
*/
for (i = 0; NULL != sgrp->sg_mem[i]; i++) {
if (i > 0) {
*cp = ',';
cp++;
}
if (i > 0)
cp = stpcpy(cp, ",");
strcpy (cp, sgrp->sg_mem[i]);
cp += strlen (cp);
cp = stpcpy(cp, sgrp->sg_mem[i]);
}
*cp = '\n';
cp++;
*cp = '\0';
stpcpy(cp, "\n");
/*
* Output using the function which understands the line
* continuation conventions.
*/
if (fputsx (buf, fp) == EOF) {
free (buf);
return -1;

View File

@@ -30,7 +30,6 @@ struct sgrp {
#include <stdio.h> /* for FILE */
#if __STDC__
/*@observer@*//*@null@*/struct sgrp *getsgent (void);
/*@observer@*//*@null@*/struct sgrp *getsgnam (const char *);
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *);
@@ -38,15 +37,6 @@ struct sgrp {
void setsgent (void);
void endsgent (void);
int putsgent (const struct sgrp *, FILE *);
#else
/*@observer@*//*@null@*/struct sgrp *getsgent ();
/*@observer@*//*@null@*/struct sgrp *getsgnam ();
/*@observer@*//*@null@*/struct sgrp *sgetsgent ();
/*@observer@*//*@null@*/struct sgrp *fgetsgent ();
void setsgent ();
void endsgent ();
int putsgent ();
#endif
#define GSHADOW "/etc/gshadow"
#endif /* ifndef _H_GSHADOW */

View File

@@ -12,13 +12,17 @@
#ident "$Id$"
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
#include "string/sprintf.h"
#include "prototypes.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
/*
@@ -70,9 +74,9 @@ bool hushed (const char *username)
return false;
}
for (found = false; !found && (fgets (buf, sizeof buf, fp) == buf);) {
buf[strcspn (buf, "\n")] = '\0';
found = (strcmp (buf, pw->pw_shell) == 0) ||
(strcmp (buf, pw->pw_name) == 0);
stpsep(buf, "\n");
found = streq(buf, pw->pw_shell) ||
streq(buf, pw->pw_name);
}
(void) fclose (fp);
return found;

View File

@@ -12,24 +12,26 @@
#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include "alloc.h"
#include "atoi/str2i.h"
#include "prototypes.h"
#include "string/stpeprintf.h"
#include "idmapping.h"
#if HAVE_SYS_CAPABILITY_H
#include <sys/prctl.h>
#include <sys/capability.h>
#endif
#include "alloc/calloc.h"
#include "alloc/x/xmalloc.h"
#include "atoi/a2i/a2u.h"
#include "idmapping.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "sizeof.h"
#include "string/sprintf/stpeprintf.h"
#include "string/strcmp/streq.h"
struct map_range *get_map_ranges(int ranges, int argc, char **argv)
struct map_range *
get_map_ranges(int ranges, int argc, char **argv)
{
struct map_range *mappings, *mapping;
int idx, argidx;
struct map_range *mappings, *m;
if (ranges < 0 || argc < 0) {
fprintf(log_get_logfd(), "%s: error calculating number of arguments\n", log_get_progname());
@@ -45,45 +47,30 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
if (!mappings) {
fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"),
log_get_progname());
exit(EXIT_FAILURE);
return NULL;
}
/* Gather up the ranges from the command line */
mapping = mappings;
for (idx = 0, argidx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
if (str2ul(&mapping->upper, argv[argidx + 0]) == -1) {
m = mappings;
for (int i = 0; i < ranges * 3; i+=3, m++) {
if (a2ul(&m->upper, argv[i + 0], NULL, 0, 0, UINT_MAX - 1) == -1) {
if (errno == ERANGE)
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
free(mappings);
return NULL;
}
if (str2ul(&mapping->lower, argv[argidx + 1]) == -1) {
if (a2ul(&m->lower, argv[i + 1], NULL, 0, 0, UINT_MAX - 1) == -1) {
if (errno == ERANGE)
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
free(mappings);
return NULL;
}
if (str2ul(&mapping->count, argv[argidx + 2]) == -1) {
if (a2ul(&m->count, argv[i + 2], NULL, 0, 1, UINT_MAX - MAX(m->lower, m->upper)) == -1) {
if (errno == ERANGE)
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
free(mappings);
return NULL;
}
if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) {
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
exit(EXIT_FAILURE);
}
if (mapping->upper > UINT_MAX ||
mapping->lower > UINT_MAX ||
mapping->count > UINT_MAX) {
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
exit(EXIT_FAILURE);
}
if (mapping->lower + mapping->count > UINT_MAX ||
mapping->upper + mapping->count > UINT_MAX) {
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
exit(EXIT_FAILURE);
}
if (mapping->lower + mapping->count < mapping->lower ||
mapping->upper + mapping->count < mapping->upper) {
/* this one really shouldn't be possible given previous checks */
fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname());
exit(EXIT_FAILURE);
}
}
return mappings;
}
@@ -147,9 +134,9 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
struct __user_cap_header_struct hdr = {_LINUX_CAPABILITY_VERSION_3, 0};
struct __user_cap_data_struct data[2] = {{0}};
if (strcmp(map_file, "uid_map") == 0) {
if (streq(map_file, "uid_map")) {
cap = CAP_SETUID;
} else if (strcmp(map_file, "gid_map") == 0) {
} else if (streq(map_file, "gid_map")) {
cap = CAP_SETGID;
} else {
fprintf(log_get_logfd(), _("%s: Invalid map file %s specified\n"), log_get_progname(), map_file);
@@ -158,7 +145,7 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
/* Align setuid- and fscaps-based new{g,u}idmap behavior. */
if (geteuid() == 0 && geteuid() != ruid) {
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
if (prctl(PR_SET_KEEPCAPS, 1L) == -1) {
fprintf(log_get_logfd(), _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), log_get_progname());
exit(EXIT_FAILURE);
}

View File

@@ -21,6 +21,7 @@
#include "adds.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
#ident "$Id$"
@@ -67,7 +68,7 @@ int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp)
* returns sp_lstchg==0 (must change password) instead of -1!
*/
if ( (0 == sp->sp_lstchg)
&& (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)) {
&& streq(pw->pw_passwd, SHADOW_PASSWD_STRING)) {
return 1;
}

View File

@@ -30,8 +30,15 @@
#include "shadowlog.h"
#include <sys/resource.h>
#include "atoi/str2i.h"
#include "memzero.h"
#include "atoi/a2i/a2i.h"
#include "atoi/a2i/a2s.h"
#include "atoi/str2i/str2i.h"
#include "atoi/str2i/str2s.h"
#include "atoi/str2i/str2u.h"
#include "string/memset/memzero.h"
#include "string/strchr/stpspn.h"
#include "string/strcmp/streq.h"
#include "typetraits.h"
#ifndef LIMITS_FILE
@@ -49,9 +56,7 @@ static int setrlimit_value (unsigned int resource,
const char *value,
unsigned int multiplier)
{
char *end;
long l;
rlim_t limit;
rlim_t l, limit;
struct rlimit rlim;
/* The "-" is special, not belonging to a strange negative limit.
@@ -59,18 +64,13 @@ static int setrlimit_value (unsigned int resource,
*/
if ('-' == value[0]) {
limit = RLIM_INFINITY;
}
else {
/* 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, &end, 10);
if (value == end || errno != 0)
} else {
if (a2i(rlim_t, &l, value, NULL, 10, 0, type_max(rlim_t)) == -1
&& errno != ENOTSUP)
{
return 0; // FIXME: We could instead throw an error, though.
}
if (__builtin_mul_overflow(l, multiplier, &limit)) {
/* FIXME: Again, silent error handling...
@@ -89,14 +89,14 @@ static int setrlimit_value (unsigned int resource,
}
static int set_prio (const char *value)
static int
set_prio(const char *value)
{
long prio;
int prio;
if ( (str2sl(&prio, value) == -1)
|| (prio != (int) prio)) {
if (str2si(&prio, value) == -1)
return 0;
}
if (setpriority (PRIO_PROCESS, 0, prio) != 0) {
return LOGIN_ERROR_RLIMIT;
}
@@ -104,14 +104,13 @@ static int set_prio (const char *value)
}
static int set_umask (const char *value)
static int
set_umask(const char *value)
{
unsigned long mask;
mode_t mask;
if ( (str2ul(&mask, value) == -1)
|| (mask != (mode_t) mask)) {
if (str2i(mode_t, &mask, value) == -1)
return 0;
}
(void) umask (mask);
return 0;
@@ -124,6 +123,10 @@ static int check_logins (const char *name, const char *maxlogins)
unsigned long limit, count;
if (str2ul(&limit, maxlogins) == -1) {
if (errno == ERANGE) {
SYSLOG((LOG_WARN, "Invalid maxlogins value\n"));
return LOGIN_ERROR_LOGIN;
}
return 0;
}
@@ -184,11 +187,7 @@ static int do_user_limits (const char *buf, const char *name)
int retval = 0;
bool reported = false;
pp = buf;
/* Skip leading whitespace. */
while ((' ' == *pp) || ('\t' == *pp)) {
pp++;
}
pp = stpspn(buf, " \t");
/* The special limit string "-" results in no limit for all known
* limits.
@@ -196,7 +195,7 @@ static int do_user_limits (const char *buf, const char *name)
* being ignored if a limit type is not known to the system.
* Though, there will be complaining for unknown limit types.
*/
if (strcmp (pp, "-") == 0) {
if (streq(pp, "-")) {
/* Remember to extend this, too, when adding new limits!
* Oh... but "unlimited" does not make sense for umask,
* or does it? (K-)
@@ -204,7 +203,7 @@ static int do_user_limits (const char *buf, const char *name)
pp = "A- C- D- F- I- L- M- N- O- P- R- S- T- U-";
}
while ('\0' != *pp) {
while (!streq(pp, "")) {
switch (*pp++) {
case 'a':
case 'A':
@@ -312,12 +311,7 @@ static int do_user_limits (const char *buf, const char *name)
* So, let's skip all digits, "-" and our limited set of
* whitespace.
*/
while ( isdigit (*pp)
|| ('-' == *pp)
|| (' ' == *pp)
|| ('\t' ==*pp)) {
pp++;
}
pp = stpspn(pp, "0123456789- \t");
}
return retval;
}
@@ -402,10 +396,10 @@ static int setup_user_limits (const char *uname)
*/
if (sscanf (buf, "%s%[ACDFIKLMNOPRSTUacdfiklmnoprstu0-9 \t-]",
name, tempbuf) == 2) {
if (strcmp (name, uname) == 0) {
if (streq(name, uname)) {
strcpy (limits, tempbuf);
break;
} else if (strcmp (name, "*") == 0) {
} else if (streq(name, "*")) {
strcpy (deflimits, tempbuf);
} else if (name[0] == '@') {
/* If the user is in the group, the group
@@ -419,9 +413,9 @@ static int setup_user_limits (const char *uname)
}
}
(void) fclose (fil);
if (limits[0] == '\0') {
if (streq(limits, "")) {
/* no user specific limits */
if (deflimits[0] == '\0') { /* no default limits */
if (streq(deflimits, "")) { /* no default limits */
return 0;
}
strcpy (limits, deflimits); /* use the default limits */
@@ -443,7 +437,7 @@ static void setup_usergroups (const struct passwd *info)
/* local, no need for xgetgrgid */
grp = getgrgid (info->pw_gid);
if ( (NULL != grp)
&& (strcmp (info->pw_name, grp->gr_name) == 0)) {
&& streq(info->pw_name, grp->gr_name)) {
mode_t tmpmask;
tmpmask = umask (0777);
tmpmask = (tmpmask & ~070) | ((tmpmask >> 3) & 070);
@@ -484,10 +478,9 @@ void setup_limits (const struct passwd *info)
}
if (strncmp (cp, "pri=", 4) == 0) {
long inc;
int inc;
if ( (str2sl(&inc, cp + 4) == 0)
&& (inc >= -20) && (inc <= 20)) {
if (a2si(&inc, cp + 4, NULL, 0, -20, 20) == 0) {
errno = 0;
if ( (nice (inc) != -1)
|| (0 != errno)) {
@@ -503,9 +496,9 @@ void setup_limits (const struct passwd *info)
continue;
}
if (strncmp (cp, "ulimit=", 7) == 0) {
long blocks;
if ( (str2sl(&blocks, cp + 7) == -1)
|| (blocks != (int) blocks)
int blocks;
if ( (str2si(&blocks, cp + 7) == -1)
|| (set_filesize_limit (blocks) != 0)) {
SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s",
@@ -514,10 +507,9 @@ void setup_limits (const struct passwd *info)
continue;
}
if (strncmp (cp, "umask=", 6) == 0) {
unsigned long mask;
mode_t mask;
if ( (str2ul(&mask, cp + 6) == -1)
|| (mask != (mode_t) mask)) {
if (str2i(mode_t, &mask, cp + 6) == -1) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",
info->pw_name));

View File

@@ -12,9 +12,14 @@
#include <assert.h>
#include "alloc.h"
#include "alloc/x/xmalloc.h"
#include "prototypes.h"
#include "defines.h"
#include "string/strchr/strchrcnt.h"
#include "string/strcmp/streq.h"
#include "string/strdup/xstrdup.h"
/*
* add_list - add a member to a list of group members
*
@@ -37,7 +42,7 @@ add_list(/*@returned@*/ /*@only@*/char **list, const char *member)
*/
for (i = 0; list[i] != NULL; i++) {
if (strcmp (list[i], member) == 0) {
if (streq(list[i], member)) {
return list;
}
}
@@ -88,7 +93,7 @@ del_list(/*@returned@*/ /*@only@*/char **list, const char *member)
*/
for (i = j = 0; list[i] != NULL; i++) {
if (strcmp (list[i], member) != 0) {
if (!streq(list[i], member)) {
j++;
}
}
@@ -111,7 +116,7 @@ del_list(/*@returned@*/ /*@only@*/char **list, const char *member)
*/
for (i = j = 0; list[i] != NULL; i++) {
if (strcmp (list[i], member) != 0) {
if (!streq(list[i], member)) {
tmp[j] = list[i];
j++;
}
@@ -163,7 +168,7 @@ bool is_on_list (char *const *list, const char *member)
assert (NULL != list);
while (NULL != *list) {
if (strcmp (*list, member) == 0) {
if (streq(*list, member)) {
return true;
}
list++;
@@ -176,7 +181,8 @@ bool is_on_list (char *const *list, const char *member)
* comma_to_list - convert comma-separated list to (char *) array
*/
/*@only@*/char **comma_to_list (const char *comma)
/*@only@*/char **
comma_to_list(const char *comma)
{
char *members;
char **array;
@@ -192,36 +198,18 @@ bool is_on_list (char *const *list, const char *member)
members = xstrdup (comma);
/*
* Count the number of commas in the list
*/
for (cp = members, i = 0;; i++) {
cp2 = strchr (cp, ',');
if (NULL != cp2) {
cp = cp2 + 1;
} else {
break;
}
}
/*
* Add 2 - one for the ending NULL, the other for the last item
*/
i += 2;
/*
* Allocate the array we're going to store the pointers into.
* n: number of delimiters + last element + NULL
*/
array = XMALLOC(i, char *);
array = XMALLOC(strchrcnt(members, ',') + 2, char *);
/*
* Empty list is special - 0 members, not 1 empty member. --marekm
*/
if ('\0' == *members) {
if (streq(members, "")) {
*array = NULL;
free (members);
return array;

View File

@@ -17,10 +17,10 @@
#include <time.h>
#include "defines.h"
#include <lastlog.h>
#include "memzero.h"
#include "prototypes.h"
#include "string/strncpy.h"
#include "string/strtcpy.h"
#include "string/memset/memzero.h"
#include "string/strcpy/strncpy.h"
#include "string/strcpy/strtcpy.h"
/*
@@ -79,7 +79,7 @@ void dolastlog (
}
ll_time = newlog.ll_time;
(void) time (&ll_time);
ll_time = time(NULL);
newlog.ll_time = ll_time;
STRTCPY(newlog.ll_line, line);
#if HAVE_LL_HOST

View File

@@ -15,12 +15,15 @@
#include <stdio.h>
#include <signal.h>
#include "alloc.h"
#include "attr.h"
#include "memzero.h"
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "string/memset/memzero.h"
#include "string/strchr/stpspn.h"
#include "string/strcpy/strtcpy.h"
#include "string/strtok/stpsep.h"
static void login_exit (MAYBE_UNUSED int sig)
{
@@ -33,8 +36,8 @@ static void login_exit (MAYBE_UNUSED int sig)
* login_prompt() displays the standard login prompt. If ISSUE_FILE
* is set in login.defs, this file is displayed before the prompt.
*/
void login_prompt (char *name, int namesize)
void
login_prompt(char *name, int namesize)
{
char buf[1024];
@@ -84,22 +87,16 @@ void login_prompt (char *name, int namesize)
exit (EXIT_FAILURE);
}
cp = strchr (buf, '\n');
if (NULL == cp) {
exit (EXIT_FAILURE);
}
*cp = '\0'; /* remove \n [ must be there ] */
if (stpsep(buf, "\n") == NULL)
exit(EXIT_FAILURE);
/*
* Skip leading whitespace. This makes " username" work right.
* Then copy the rest (up to the end) into the username.
*/
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++);
for (i = 0; i < namesize - 1 && *cp != '\0'; name[i++] = *cp++);
name[i] = '\0';
cp = stpspn(buf, " \t");
strtcpy(name, cp, namesize);
/*
* Set the SIGQUIT handler back to its original value

View File

@@ -15,9 +15,8 @@
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "getdef.h"
#include "string/sprintf.h"
#include "string/sprintf/xasprintf.h"
#ident "$Id$"

View File

@@ -1,17 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <stddef.h>
#include "memzero.h"
extern inline void memzero(void *ptr, size_t size);
extern inline void strzero(char *s);

View File

@@ -12,11 +12,14 @@
#ident "$Id$"
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "string/strdup/xstrdup.h"
/*
* motd -- output the /etc/motd file
*
@@ -24,7 +27,8 @@
* it to the user's terminal at login time. The MOTD_FILE configuration
* option is a colon-delimited list of filenames.
*/
void motd (void)
void
motd(void)
{
FILE *fp;
char *motdlist;
@@ -39,12 +43,8 @@ void motd (void)
motdlist = xstrdup (motdfile);
for (mb = motdlist; ;mb = NULL) {
motdfile = strtok (mb, ":");
if (NULL == motdfile) {
break;
}
mb = motdlist;
while (NULL != (motdfile = strsep(&mb, ":"))) {
fp = fopen (motdfile, "r");
if (NULL != fp) {
while ((c = getc (fp)) != EOF) {

Some files were not shown because too many files have changed in this diff Show More