aports

Custom Alpine Linux aports

git clone https://git.8pit.net/aports.git

 1/* This is a very simple SUID binary for creating an XDG_RUNTIME_DIR
 2 * on systems using neither PAM nor elogind. The code is basically
 3 * taken from dumb-runtime-dir and hence licensed under 0BSD.
 4 *
 5 * The tool creates a directory with RUNTIME_DIR_PREFIX and prints
 6 * its path. The caller is responsible for setting XDG_RUNTIME_DIR
 7 * accordingly. Contrary to the spec, the directory is never removed. */
 8
 9#include <assert.h>
10#include <err.h>
11#include <errno.h>
12#include <stddef.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
17
18#include <sys/stat.h>
19
20int
21main(void) {
22	uid_t gid = getgid();
23	uid_t uid = getuid();
24
25	/* The following has been taken from dumb-runtime-dir and slightly modified.
26	 *
27	 * See: https://github.com/ifreund/dumb_runtime_dir/blob/v1.0.4/pam_dumb_runtime_dir.c#L51-L61 */
28
29	/* The bit size of uintmax_t will always be larger than the number of
30	 * bytes needed to print it. */
31	char path[sizeof(RUNTIME_DIR_PREFIX) + sizeof(uintmax_t) * 8];
32	/* Valid UIDs are always positive even if POSIX allows the uid_t type
33	 * itself to be signed. Therefore, we can convert to uintmax_t for
34	 * safe formatting. */
35	int ret = snprintf(path, sizeof(path), RUNTIME_DIR_PREFIX"%ju", (uintmax_t)uid);
36	assert(ret >= 0 && (size_t)ret < sizeof(path));
37
38	if (mkdir(path, 0700) < 0) {
39		/* It's ok if the directory already exists, in that case we just
40		 * ensure the mode is correct before we chown(). */
41		if (errno != EEXIST)
42			err(EXIT_FAILURE, "mkdir failed");
43		if (chmod(path, 0700) < 0)
44			err(EXIT_FAILURE, "chmod failed");
45	}
46
47	if (chown(path, uid, gid) < 0)
48		err(EXIT_FAILURE, "chown failed");
49
50	printf("%s\n", path);
51	return EXIT_SUCCESS;
52}