summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am12
-rw-r--r--man/systemd.mount.xml2
-rw-r--r--src/basic/audit.c1
-rw-r--r--src/basic/cgroup-util.c1
-rw-r--r--src/basic/copy.c1
-rw-r--r--src/basic/ether-addr-util.c44
-rw-r--r--src/basic/ether-addr-util.h4
-rw-r--r--src/basic/io-util.c261
-rw-r--r--src/basic/io-util.h39
-rw-r--r--src/basic/path-util.c6
-rw-r--r--src/basic/process-util.c11
-rw-r--r--src/basic/process-util.h3
-rw-r--r--src/basic/random-util.c1
-rw-r--r--src/basic/socket-util.c193
-rw-r--r--src/basic/socket-util.h12
-rw-r--r--src/basic/terminal-util.c2
-rw-r--r--src/basic/user-util.c429
-rw-r--r--src/basic/user-util.h54
-rw-r--r--src/basic/util.c802
-rw-r--r--src/basic/util.h55
-rw-r--r--src/bootchart/bootchart.c1
-rw-r--r--src/bus-proxyd/bus-proxyd.c1
-rw-r--r--src/bus-proxyd/bus-xml-policy.c3
-rw-r--r--src/bus-proxyd/stdio-bridge.c1
-rw-r--r--src/core/automount.c1
-rw-r--r--src/core/bus-policy.c5
-rw-r--r--src/core/dbus-mount.c2
-rw-r--r--src/core/execute.c2
-rw-r--r--src/core/load-fragment-gperf.gperf.m42
-rw-r--r--src/core/machine-id-setup.c1
-rw-r--r--src/core/main.c1
-rw-r--r--src/core/manager.c1
-rw-r--r--src/core/mount.c12
-rw-r--r--src/core/mount.h2
-rw-r--r--src/core/namespace.c1
-rw-r--r--src/core/socket.c1
-rw-r--r--src/core/timer.c3
-rw-r--r--src/core/umount.c26
-rw-r--r--src/core/unit-printf.c3
-rw-r--r--src/core/unit.c3
-rw-r--r--src/import/import-raw.c1
-rw-r--r--src/import/import-tar.c1
-rw-r--r--src/import/pull-common.c1
-rw-r--r--src/import/pull-job.c1
-rw-r--r--src/journal/compress.c1
-rw-r--r--src/journal/coredump-vacuum.c1
-rw-r--r--src/journal/coredump.c1
-rw-r--r--src/journal/coredumpctl.c1
-rw-r--r--src/journal/journal-send.c1
-rw-r--r--src/journal/journalctl.c2
-rw-r--r--src/journal/journald-server.c16
-rw-r--r--src/journal/sd-journal.c2
-rw-r--r--src/libsystemd/sd-bus/bus-socket.c1
-rw-r--r--src/libsystemd/sd-bus/busctl.c1
l---------src/libsystemd/sd-device/Makefile1
-rw-r--r--src/libsystemd/sd-id128/sd-id128.c3
-rw-r--r--src/libsystemd/sd-login/sd-login.c3
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c1
-rw-r--r--src/libsystemd/sd-netlink/test-netlink.c1
-rw-r--r--src/libsystemd/sd-path/sd-path.c1
-rw-r--r--src/libsystemd/sd-resolve/sd-resolve.c1
-rw-r--r--src/libudev/libudev-queue.c1
-rw-r--r--src/login/inhibit.c1
-rw-r--r--src/login/loginctl.c1
-rw-r--r--src/login/logind-action.c1
-rw-r--r--src/login/logind-core.c1
-rw-r--r--src/login/logind-dbus.c3
-rw-r--r--src/login/logind-inhibit.c1
-rw-r--r--src/login/logind-session.c3
-rw-r--r--src/login/logind-user-dbus.c7
-rw-r--r--src/login/logind-utmp.c16
-rw-r--r--src/machine/machined-dbus.c1
-rw-r--r--src/network/networkd-netdev-tuntap.c3
-rw-r--r--src/network/networkd.c4
-rw-r--r--src/nspawn/nspawn-expose-ports.c1
-rw-r--r--src/nspawn/nspawn-setuid.c1
-rw-r--r--src/nspawn/nspawn.c2
-rw-r--r--src/nss-mymachines/nss-mymachines.c1
-rw-r--r--src/random-seed/random-seed.c1
-rw-r--r--src/resolve/resolved-manager.c1
-rw-r--r--src/resolve/resolved.c11
-rw-r--r--src/rfkill/rfkill.c1
-rw-r--r--src/run/run.c1
-rw-r--r--src/shared/acl-util.c3
-rw-r--r--src/shared/ask-password-api.c1
-rw-r--r--src/shared/efivars.c1
-rw-r--r--src/shared/install-printf.c5
-rw-r--r--src/shared/logs-show.c1
-rw-r--r--src/shared/spawn-polkit-agent.c5
-rw-r--r--src/shared/uid-range.c3
-rw-r--r--src/shared/utmp-wtmp.c1
-rw-r--r--src/systemctl/systemctl.c2
-rw-r--r--src/sysusers/sysusers.c1
-rw-r--r--src/test/test-ipcrm.c3
-rw-r--r--src/test/test-user-util.c53
-rw-r--r--src/test/test-util.c4
-rw-r--r--src/timesync/timesyncd.c1
-rw-r--r--src/tmpfiles/tmpfiles.c2
-rw-r--r--src/tty-ask-password-agent/tty-ask-password-agent.c1
-rw-r--r--src/udev/udev-rules.c1
-rw-r--r--src/udev/udevd.c1
-rw-r--r--src/update-done/update-done.c1
-rw-r--r--src/vconsole/vconsole-setup.c1
-rw-r--r--units/tmp.mount.m42
105 files changed, 1272 insertions, 932 deletions
diff --git a/.gitignore b/.gitignore
index b47bd1b2f2..0a32bae7a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -266,6 +266,7 @@
/test-unaligned
/test-unit-file
/test-unit-name
+/test-user-util
/test-utf8
/test-util
/test-verbs
diff --git a/Makefile.am b/Makefile.am
index 5c9bcb4568..2e960623a5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -781,10 +781,14 @@ libbasic_la_SOURCES = \
src/basic/refcnt.h \
src/basic/util.c \
src/basic/util.h \
+ src/basic/io-util.c \
+ src/basic/io-util.h \
src/basic/string-util.c \
src/basic/string-util.h \
src/basic/fd-util.c \
src/basic/fd-util.h \
+ src/basic/user-util.c \
+ src/basic/user-util.h \
src/basic/extract-word.c \
src/basic/extract-word.h \
src/basic/escape.c \
@@ -846,6 +850,7 @@ libbasic_la_SOURCES = \
src/basic/in-addr-util.c \
src/basic/in-addr-util.h \
src/basic/ether-addr-util.h \
+ src/basic/ether-addr-util.c \
src/basic/replace-var.c \
src/basic/replace-var.h \
src/basic/clock-util.c \
@@ -1410,6 +1415,7 @@ tests += \
test-utf8 \
test-ellipsize \
test-util \
+ test-user-util \
test-hostname-util \
test-process-util \
test-terminal-util \
@@ -1694,6 +1700,12 @@ test_util_SOURCES = \
test_util_LDADD = \
libshared.la
+test_user_util_SOURCES = \
+ src/test/test-user-util.c
+
+test_user_util_LDADD = \
+ libshared.la
+
test_hostname_util_SOURCES = \
src/test/test-hostname-util.c
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index d3775ff830..aaf2e98175 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -324,7 +324,7 @@
</varlistentry>
<varlistentry>
- <term><varname>SmackFileSystemRoot=</varname></term>
+ <term><varname>SmackFileSystemRootLabel=</varname></term>
<listitem><para>Takes a string for the smack label.
This option specifies the label to assign the root of the
file system if it lacks the Smack extended attribute.
diff --git a/src/basic/audit.c b/src/basic/audit.c
index af43ec8097..c9b762151a 100644
--- a/src/basic/audit.c
+++ b/src/basic/audit.c
@@ -27,6 +27,7 @@
#include "fileio.h"
#include "macro.h"
#include "process-util.h"
+#include "user-util.h"
#include "util.h"
int audit_session_from_pid(pid_t pid, uint32_t *id) {
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 958497543a..4af991200c 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -43,6 +43,7 @@
#include "special.h"
#include "string-util.h"
#include "unit-name.h"
+#include "user-util.h"
#include "util.h"
int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) {
diff --git a/src/basic/copy.c b/src/basic/copy.c
index c15527df22..9f274c4d51 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -25,6 +25,7 @@
#include "btrfs-util.h"
#include "copy.h"
#include "fd-util.h"
+#include "io-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
diff --git a/src/basic/ether-addr-util.c b/src/basic/ether-addr-util.c
new file mode 100644
index 0000000000..2bf3bfec1d
--- /dev/null
+++ b/src/basic/ether-addr-util.c
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2014 Tom Gundersen
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+
+#include "ether-addr-util.h"
+#include "macro.h"
+
+char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
+ assert(addr);
+ assert(buffer);
+
+ /* Like ether_ntoa() but uses %02x instead of %x to print
+ * ethernet addresses, which makes them look less funny. Also,
+ * doesn't use a static buffer. */
+
+ sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
+ addr->ether_addr_octet[0],
+ addr->ether_addr_octet[1],
+ addr->ether_addr_octet[2],
+ addr->ether_addr_octet[3],
+ addr->ether_addr_octet[4],
+ addr->ether_addr_octet[5]);
+
+ return buffer;
+}
diff --git a/src/basic/ether-addr-util.h b/src/basic/ether-addr-util.h
index 7033138788..008f3b893e 100644
--- a/src/basic/ether-addr-util.h
+++ b/src/basic/ether-addr-util.h
@@ -25,3 +25,7 @@
#define ETHER_ADDR_FORMAT_STR "%02X%02X%02X%02X%02X%02X"
#define ETHER_ADDR_FORMAT_VAL(x) (x).ether_addr_octet[0], (x).ether_addr_octet[1], (x).ether_addr_octet[2], (x).ether_addr_octet[3], (x).ether_addr_octet[4], (x).ether_addr_octet[5]
+
+#define ETHER_ADDR_TO_STRING_MAX (3*6)
+
+char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
diff --git a/src/basic/io-util.c b/src/basic/io-util.c
new file mode 100644
index 0000000000..ac8f93ff57
--- /dev/null
+++ b/src/basic/io-util.c
@@ -0,0 +1,261 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <poll.h>
+#include <unistd.h>
+
+#include "io-util.h"
+
+int flush_fd(int fd) {
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = POLLIN,
+ };
+
+ for (;;) {
+ char buf[LINE_MAX];
+ ssize_t l;
+ int r;
+
+ r = poll(&pollfd, 1, 0);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -errno;
+
+ } else if (r == 0)
+ return 0;
+
+ l = read(fd, buf, sizeof(buf));
+ if (l < 0) {
+
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN)
+ return 0;
+
+ return -errno;
+ } else if (l == 0)
+ return 0;
+ }
+}
+
+ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
+ uint8_t *p = buf;
+ ssize_t n = 0;
+
+ assert(fd >= 0);
+ assert(buf);
+
+ /* If called with nbytes == 0, let's call read() at least
+ * once, to validate the operation */
+
+ if (nbytes > (size_t) SSIZE_MAX)
+ return -EINVAL;
+
+ do {
+ ssize_t k;
+
+ k = read(fd, p, nbytes);
+ if (k < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN && do_poll) {
+
+ /* We knowingly ignore any return value here,
+ * and expect that any error/EOF is reported
+ * via read() */
+
+ (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
+ continue;
+ }
+
+ return n > 0 ? n : -errno;
+ }
+
+ if (k == 0)
+ return n;
+
+ assert((size_t) k <= nbytes);
+
+ p += k;
+ nbytes -= k;
+ n += k;
+ } while (nbytes > 0);
+
+ return n;
+}
+
+int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
+ ssize_t n;
+
+ n = loop_read(fd, buf, nbytes, do_poll);
+ if (n < 0)
+ return (int) n;
+ if ((size_t) n != nbytes)
+ return -EIO;
+
+ return 0;
+}
+
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
+ const uint8_t *p = buf;
+
+ assert(fd >= 0);
+ assert(buf);
+
+ if (nbytes > (size_t) SSIZE_MAX)
+ return -EINVAL;
+
+ do {
+ ssize_t k;
+
+ k = write(fd, p, nbytes);
+ if (k < 0) {
+ if (errno == EINTR)
+ continue;
+
+ if (errno == EAGAIN && do_poll) {
+ /* We knowingly ignore any return value here,
+ * and expect that any error/EOF is reported
+ * via write() */
+
+ (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
+ continue;
+ }
+
+ return -errno;
+ }
+
+ if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
+ return -EIO;
+
+ assert((size_t) k <= nbytes);
+
+ p += k;
+ nbytes -= k;
+ } while (nbytes > 0);
+
+ return 0;
+}
+
+int pipe_eof(int fd) {
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = POLLIN|POLLHUP,
+ };
+
+ int r;
+
+ r = poll(&pollfd, 1, 0);
+ if (r < 0)
+ return -errno;
+
+ if (r == 0)
+ return 0;
+
+ return pollfd.revents & POLLHUP;
+}
+
+int fd_wait_for_event(int fd, int event, usec_t t) {
+
+ struct pollfd pollfd = {
+ .fd = fd,
+ .events = event,
+ };
+
+ struct timespec ts;
+ int r;
+
+ r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
+ if (r < 0)
+ return -errno;
+
+ if (r == 0)
+ return 0;
+
+ return pollfd.revents;
+}
+
+static size_t nul_length(const uint8_t *p, size_t sz) {
+ size_t n = 0;
+
+ while (sz > 0) {
+ if (*p != 0)
+ break;
+
+ n++;
+ p++;
+ sz--;
+ }
+
+ return n;
+}
+
+ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
+ const uint8_t *q, *w, *e;
+ ssize_t l;
+
+ q = w = p;
+ e = q + sz;
+ while (q < e) {
+ size_t n;
+
+ n = nul_length(q, e - q);
+
+ /* If there are more than the specified run length of
+ * NUL bytes, or if this is the beginning or the end
+ * of the buffer, then seek instead of write */
+ if ((n > run_length) ||
+ (n > 0 && q == p) ||
+ (n > 0 && q + n >= e)) {
+ if (q > w) {
+ l = write(fd, w, q - w);
+ if (l < 0)
+ return -errno;
+ if (l != q -w)
+ return -EIO;
+ }
+
+ if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
+ return -errno;
+
+ q += n;
+ w = q;
+ } else if (n > 0)
+ q += n;
+ else
+ q ++;
+ }
+
+ if (q > w) {
+ l = write(fd, w, q - w);
+ if (l < 0)
+ return -errno;
+ if (l != q - w)
+ return -EIO;
+ }
+
+ return q - (const uint8_t*) p;
+}
diff --git a/src/basic/io-util.h b/src/basic/io-util.h
new file mode 100644
index 0000000000..ff7c2a9ac4
--- /dev/null
+++ b/src/basic/io-util.h
@@ -0,0 +1,39 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+#include "time-util.h"
+
+int flush_fd(int fd);
+
+ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
+int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
+int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
+
+int pipe_eof(int fd);
+
+int fd_wait_for_event(int fd, int event, usec_t timeout);
+
+ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 7b01633f5f..0b8cac8f3e 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -428,7 +428,7 @@ int path_compare(const char *a, const char *b) {
* Which one is sorted before the other does not really matter.
* Here a relative path is ordered before an absolute path. */
d = (a[0] == '/') - (b[0] == '/');
- if (d)
+ if (d != 0)
return d;
for (;;) {
@@ -451,12 +451,12 @@ int path_compare(const char *a, const char *b) {
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
d = memcmp(a, b, MIN(j, k));
- if (d)
+ if (d != 0)
return (d > 0) - (d < 0); /* sign of d */
/* Sort "/foo/a" before "/foo/aaa" */
d = (j > k) - (j < k); /* sign of (j - k) */
- if (d)
+ if (d != 0)
return d;
a += j;
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index 949bd1f64d..72fc82e7cb 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -35,6 +35,7 @@
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
int get_process_state(pid_t pid) {
@@ -479,6 +480,16 @@ int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_cod
return -EPROTO;
}
+void sigkill_wait(pid_t *pid) {
+ if (!pid)
+ return;
+ if (*pid <= 1)
+ return;
+
+ if (kill(*pid, SIGKILL) > 0)
+ (void) wait_for_terminate(*pid, NULL);
+}
+
int kill_and_sigcont(pid_t pid, int sig) {
int r;
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index 07431d043b..2c0d1af000 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -55,6 +55,9 @@ int get_process_environ(pid_t pid, char **environ);
int wait_for_terminate(pid_t pid, siginfo_t *status);
int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code);
+void sigkill_wait(pid_t *pid);
+#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
+
int kill_and_sigcont(pid_t pid, int sig);
pid_t get_parent_of_pid(pid_t pid, pid_t *ppid);
void rename_process(const char name[8]);
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index e183165b9f..2f5c16e2af 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -29,6 +29,7 @@
#include <time.h>
#include "fd-util.h"
+#include "io-util.h"
#include "missing.h"
#include "random-util.h"
#include "time-util.h"
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 9ed5feb849..684ac765f5 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -23,20 +23,22 @@
#include <errno.h>
#include <net/if.h>
#include <netdb.h>
+#include <netinet/ip.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
+#include "fd-util.h"
#include "fileio.h"
#include "formats-util.h"
#include "macro.h"
#include "missing.h"
#include "path-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
-#include "socket-util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
@@ -750,21 +752,182 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b
return false;
}
-char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
- assert(addr);
- assert(buffer);
+int fd_inc_sndbuf(int fd, size_t n) {
+ int r, value;
+ socklen_t l = sizeof(value);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
+ if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
+ return 0;
+
+ /* If we have the privileges we will ignore the kernel limit. */
+
+ value = (int) n;
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
+ return -errno;
+
+ return 1;
+}
+
+int fd_inc_rcvbuf(int fd, size_t n) {
+ int r, value;
+ socklen_t l = sizeof(value);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
+ if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
+ return 0;
+
+ /* If we have the privileges we will ignore the kernel limit. */
+
+ value = (int) n;
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
+ return -errno;
+ return 1;
+}
+
+static const char* const ip_tos_table[] = {
+ [IPTOS_LOWDELAY] = "low-delay",
+ [IPTOS_THROUGHPUT] = "throughput",
+ [IPTOS_RELIABILITY] = "reliability",
+ [IPTOS_LOWCOST] = "low-cost",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
+
+int getpeercred(int fd, struct ucred *ucred) {
+ socklen_t n = sizeof(struct ucred);
+ struct ucred u;
+ int r;
+
+ assert(fd >= 0);
+ assert(ucred);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
+ if (r < 0)
+ return -errno;
+
+ if (n != sizeof(struct ucred))
+ return -EIO;
+
+ /* Check if the data is actually useful and not suppressed due
+ * to namespacing issues */
+ if (u.pid <= 0)
+ return -ENODATA;
+ if (u.uid == UID_INVALID)
+ return -ENODATA;
+ if (u.gid == GID_INVALID)
+ return -ENODATA;
- /* Like ether_ntoa() but uses %02x instead of %x to print
- * ethernet addresses, which makes them look less funny. Also,
- * doesn't use a static buffer. */
+ *ucred = u;
+ return 0;
+}
+
+int getpeersec(int fd, char **ret) {
+ socklen_t n = 64;
+ char *s;
+ int r;
- sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
- addr->ether_addr_octet[0],
- addr->ether_addr_octet[1],
- addr->ether_addr_octet[2],
- addr->ether_addr_octet[3],
- addr->ether_addr_octet[4],
- addr->ether_addr_octet[5]);
+ assert(fd >= 0);
+ assert(ret);
+
+ s = new0(char, n);
+ if (!s)
+ return -ENOMEM;
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
+ if (r < 0) {
+ free(s);
+
+ if (errno != ERANGE)
+ return -errno;
+
+ s = new0(char, n);
+ if (!s)
+ return -ENOMEM;
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
+ if (r < 0) {
+ free(s);
+ return -errno;
+ }
+ }
+
+ if (isempty(s)) {
+ free(s);
+ return -EOPNOTSUPP;
+ }
+
+ *ret = s;
+ return 0;
+}
+
+int send_one_fd(int transport_fd, int fd, int flags) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+ struct msghdr mh = {
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg;
+
+ assert(transport_fd >= 0);
+ assert(fd >= 0);
+
+ cmsg = CMSG_FIRSTHDR(&mh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
+
+ mh.msg_controllen = CMSG_SPACE(sizeof(int));
+ if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int receive_one_fd(int transport_fd, int flags) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+ struct msghdr mh = {
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg, *found = NULL;
+
+ assert(transport_fd >= 0);
+
+ /*
+ * Receive a single FD via @transport_fd. We don't care for
+ * the transport-type. We retrieve a single FD at most, so for
+ * packet-based transports, the caller must ensure to send
+ * only a single FD per packet. This is best used in
+ * combination with send_one_fd().
+ */
+
+ if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
+ return -errno;
+
+ CMSG_FOREACH(cmsg, &mh) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ assert(!found);
+ found = cmsg;
+ break;
+ }
+ }
+
+ if (!found) {
+ cmsg_close_all(&mh);
+ return -EIO;
+ }
- return buffer;
+ return *(int*) CMSG_DATA(found);
}
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 6b0ce7836f..8b5410b391 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -116,6 +116,14 @@ int netlink_family_from_string(const char *s) _pure_;
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
-#define ETHER_ADDR_TO_STRING_MAX (3*6)
+int fd_inc_sndbuf(int fd, size_t n);
+int fd_inc_rcvbuf(int fd, size_t n);
-char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]);
+int ip_tos_to_string_alloc(int i, char **s);
+int ip_tos_from_string(const char *s);
+
+int getpeercred(int fd, struct ucred *ucred);
+int getpeersec(int fd, char **ret);
+
+int send_one_fd(int transport_fd, int fd, int flags);
+int receive_one_fd(int transport_fd, int flags);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 5949b99c95..7dfab0af62 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -33,8 +33,10 @@
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "terminal-util.h"
#include "time-util.h"
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
new file mode 100644
index 0000000000..7e6c4c645d
--- /dev/null
+++ b/src/basic/user-util.c
@@ -0,0 +1,429 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <pwd.h>
+#include <grp.h>
+
+#include "user-util.h"
+#include "macro.h"
+#include "util.h"
+#include "string-util.h"
+#include "path-util.h"
+
+bool uid_is_valid(uid_t uid) {
+
+ /* Some libc APIs use UID_INVALID as special placeholder */
+ if (uid == (uid_t) UINT32_C(0xFFFFFFFF))
+ return false;
+
+ /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
+ if (uid == (uid_t) UINT32_C(0xFFFF))
+ return false;
+
+ return true;
+}
+
+int parse_uid(const char *s, uid_t *ret) {
+ uint32_t uid = 0;
+ int r;
+
+ assert(s);
+
+ assert_cc(sizeof(uid_t) == sizeof(uint32_t));
+ r = safe_atou32(s, &uid);
+ if (r < 0)
+ return r;
+
+ if (!uid_is_valid(uid))
+ return -ENXIO; /* we return ENXIO instead of EINVAL
+ * here, to make it easy to distuingish
+ * invalid numeric uids invalid
+ * strings. */
+
+ if (ret)
+ *ret = uid;
+
+ return 0;
+}
+
+char* getlogname_malloc(void) {
+ uid_t uid;
+ struct stat st;
+
+ if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
+ uid = st.st_uid;
+ else
+ uid = getuid();
+
+ return uid_to_name(uid);
+}
+
+char *getusername_malloc(void) {
+ const char *e;
+
+ e = getenv("USER");
+ if (e)
+ return strdup(e);
+
+ return uid_to_name(getuid());
+}
+
+int get_user_creds(
+ const char **username,
+ uid_t *uid, gid_t *gid,
+ const char **home,
+ const char **shell) {
+
+ struct passwd *p;
+ uid_t u;
+
+ assert(username);
+ assert(*username);
+
+ /* We enforce some special rules for uid=0: in order to avoid
+ * NSS lookups for root we hardcode its data. */
+
+ if (streq(*username, "root") || streq(*username, "0")) {
+ *username = "root";
+
+ if (uid)
+ *uid = 0;
+
+ if (gid)
+ *gid = 0;
+
+ if (home)
+ *home = "/root";
+
+ if (shell)
+ *shell = "/bin/sh";
+
+ return 0;
+ }
+
+ if (parse_uid(*username, &u) >= 0) {
+ errno = 0;
+ p = getpwuid(u);
+
+ /* If there are multiple users with the same id, make
+ * sure to leave $USER to the configured value instead
+ * of the first occurrence in the database. However if
+ * the uid was configured by a numeric uid, then let's
+ * pick the real username from /etc/passwd. */
+ if (p)
+ *username = p->pw_name;
+ } else {
+ errno = 0;
+ p = getpwnam(*username);
+ }
+
+ if (!p)
+ return errno > 0 ? -errno : -ESRCH;
+
+ if (uid) {
+ if (!uid_is_valid(p->pw_uid))
+ return -EBADMSG;
+
+ *uid = p->pw_uid;
+ }
+
+ if (gid) {
+ if (!gid_is_valid(p->pw_gid))
+ return -EBADMSG;
+
+ *gid = p->pw_gid;
+ }
+
+ if (home)
+ *home = p->pw_dir;
+
+ if (shell)
+ *shell = p->pw_shell;
+
+ return 0;
+}
+
+int get_group_creds(const char **groupname, gid_t *gid) {
+ struct group *g;
+ gid_t id;
+
+ assert(groupname);
+
+ /* We enforce some special rules for gid=0: in order to avoid
+ * NSS lookups for root we hardcode its data. */
+
+ if (streq(*groupname, "root") || streq(*groupname, "0")) {
+ *groupname = "root";
+
+ if (gid)
+ *gid = 0;
+
+ return 0;
+ }
+
+ if (parse_gid(*groupname, &id) >= 0) {
+ errno = 0;
+ g = getgrgid(id);
+
+ if (g)
+ *groupname = g->gr_name;
+ } else {
+ errno = 0;
+ g = getgrnam(*groupname);
+ }
+
+ if (!g)
+ return errno > 0 ? -errno : -ESRCH;
+
+ if (gid) {
+ if (!gid_is_valid(g->gr_gid))
+ return -EBADMSG;
+
+ *gid = g->gr_gid;
+ }
+
+ return 0;
+}
+
+char* uid_to_name(uid_t uid) {
+ char *ret;
+ int r;
+
+ /* Shortcut things to avoid NSS lookups */
+ if (uid == 0)
+ return strdup("root");
+
+ if (uid_is_valid(uid)) {
+ long bufsize;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize <= 0)
+ bufsize = 4096;
+
+ for (;;) {
+ struct passwd pwbuf, *pw = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+
+ r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
+ if (r == 0 && pw)
+ return strdup(pw->pw_name);
+ if (r != ERANGE)
+ break;
+
+ bufsize *= 2;
+ }
+ }
+
+ if (asprintf(&ret, UID_FMT, uid) < 0)
+ return NULL;
+
+ return ret;
+}
+
+char* gid_to_name(gid_t gid) {
+ char *ret;
+ int r;
+
+ if (gid == 0)
+ return strdup("root");
+
+ if (gid_is_valid(gid)) {
+ long bufsize;
+
+ bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (bufsize <= 0)
+ bufsize = 4096;
+
+ for (;;) {
+ struct group grbuf, *gr = NULL;
+ _cleanup_free_ char *buf = NULL;
+
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+
+ r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
+ if (r == 0 && gr)
+ return strdup(gr->gr_name);
+ if (r != ERANGE)
+ break;
+
+ bufsize *= 2;
+ }
+ }
+
+ if (asprintf(&ret, GID_FMT, gid) < 0)
+ return NULL;
+
+ return ret;
+}
+
+int in_gid(gid_t gid) {
+ gid_t *gids;
+ int ngroups_max, r, i;
+
+ if (getgid() == gid)
+ return 1;
+
+ if (getegid() == gid)
+ return 1;
+
+ if (!gid_is_valid(gid))
+ return -EINVAL;
+
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ assert(ngroups_max > 0);
+
+ gids = alloca(sizeof(gid_t) * ngroups_max);
+
+ r = getgroups(ngroups_max, gids);
+ if (r < 0)
+ return -errno;
+
+ for (i = 0; i < r; i++)
+ if (gids[i] == gid)
+ return 1;
+
+ return 0;
+}
+
+int in_group(const char *name) {
+ int r;
+ gid_t gid;
+
+ r = get_group_creds(&name, &gid);
+ if (r < 0)
+ return r;
+
+ return in_gid(gid);
+}
+
+int get_home_dir(char **_h) {
+ struct passwd *p;
+ const char *e;
+ char *h;
+ uid_t u;
+
+ assert(_h);
+
+ /* Take the user specified one */
+ e = secure_getenv("HOME");
+ if (e && path_is_absolute(e)) {
+ h = strdup(e);
+ if (!h)
+ return -ENOMEM;
+
+ *_h = h;
+ return 0;
+ }
+
+ /* Hardcode home directory for root to avoid NSS */
+ u = getuid();
+ if (u == 0) {
+ h = strdup("/root");
+ if (!h)
+ return -ENOMEM;
+
+ *_h = h;
+ return 0;
+ }
+
+ /* Check the database... */
+ errno = 0;
+ p = getpwuid(u);
+ if (!p)
+ return errno > 0 ? -errno : -ESRCH;
+
+ if (!path_is_absolute(p->pw_dir))
+ return -EINVAL;
+
+ h = strdup(p->pw_dir);
+ if (!h)
+ return -ENOMEM;
+
+ *_h = h;
+ return 0;
+}
+
+int get_shell(char **_s) {
+ struct passwd *p;
+ const char *e;
+ char *s;
+ uid_t u;
+
+ assert(_s);
+
+ /* Take the user specified one */
+ e = getenv("SHELL");
+ if (e) {
+ s = strdup(e);
+ if (!s)
+ return -ENOMEM;
+
+ *_s = s;
+ return 0;
+ }
+
+ /* Hardcode home directory for root to avoid NSS */
+ u = getuid();
+ if (u == 0) {
+ s = strdup("/bin/sh");
+ if (!s)
+ return -ENOMEM;
+
+ *_s = s;
+ return 0;
+ }
+
+ /* Check the database... */
+ errno = 0;
+ p = getpwuid(u);
+ if (!p)
+ return errno > 0 ? -errno : -ESRCH;
+
+ if (!path_is_absolute(p->pw_shell))
+ return -EINVAL;
+
+ s = strdup(p->pw_shell);
+ if (!s)
+ return -ENOMEM;
+
+ *_s = s;
+ return 0;
+}
+
+int reset_uid_gid(void) {
+
+ if (setgroups(0, NULL) < 0)
+ return -errno;
+
+ if (setresgid(0, 0, 0) < 0)
+ return -errno;
+
+ if (setresuid(0, 0, 0) < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/basic/user-util.h b/src/basic/user-util.h
new file mode 100644
index 0000000000..7995698f27
--- /dev/null
+++ b/src/basic/user-util.h
@@ -0,0 +1,54 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+bool uid_is_valid(uid_t uid);
+
+static inline bool gid_is_valid(gid_t gid) {
+ return uid_is_valid((uid_t) gid);
+}
+
+int parse_uid(const char *s, uid_t* ret_uid);
+
+static inline int parse_gid(const char *s, gid_t *ret_gid) {
+ return parse_uid(s, (uid_t*) ret_gid);
+}
+
+char* getlogname_malloc(void);
+char* getusername_malloc(void);
+
+int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
+int get_group_creds(const char **groupname, gid_t *gid);
+
+char* uid_to_name(uid_t uid);
+char* gid_to_name(gid_t gid);
+
+int in_gid(gid_t gid);
+int in_group(const char *name);
+
+int get_home_dir(char **ret);
+int get_shell(char **_ret);
+
+int reset_uid_gid(void);
diff --git a/src/basic/util.c b/src/basic/util.c
index 05f34ea52c..d5227aa6d0 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -32,7 +32,6 @@
#include <linux/oom.h>
#include <linux/sched.h>
#include <locale.h>
-#include <netinet/ip.h>
#include <poll.h>
#include <pwd.h>
#include <sched.h>
@@ -98,6 +97,7 @@
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
+#include "user-util.h"
#include "utf8.h"
#include "util.h"
#include "virt.h"
@@ -168,47 +168,6 @@ int parse_pid(const char *s, pid_t* ret_pid) {
return 0;
}
-bool uid_is_valid(uid_t uid) {
-
- /* Some libc APIs use UID_INVALID as special placeholder */
- if (uid == (uid_t) 0xFFFFFFFF)
- return false;
-
- /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
- if (uid == (uid_t) 0xFFFF)
- return false;
-
- return true;
-}
-
-int parse_uid(const char *s, uid_t* ret_uid) {
- unsigned long ul = 0;
- uid_t uid;
- int r;
-
- assert(s);
-
- r = safe_atolu(s, &ul);
- if (r < 0)
- return r;
-
- uid = (uid_t) ul;
-
- if ((unsigned long) uid != ul)
- return -ERANGE;
-
- if (!uid_is_valid(uid))
- return -ENXIO; /* we return ENXIO instead of EINVAL
- * here, to make it easy to distuingish
- * invalid numeric uids invalid
- * strings. */
-
- if (ret_uid)
- *ret_uid = uid;
-
- return 0;
-}
-
int safe_atou(const char *s, unsigned *ret_u) {
char *x = NULL;
unsigned long l;
@@ -1236,142 +1195,6 @@ bool fstype_is_network(const char *fstype) {
return nulstr_contains(table, fstype);
}
-int flush_fd(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN,
- };
-
- for (;;) {
- char buf[LINE_MAX];
- ssize_t l;
- int r;
-
- r = poll(&pollfd, 1, 0);
- if (r < 0) {
- if (errno == EINTR)
- continue;
-
- return -errno;
-
- } else if (r == 0)
- return 0;
-
- l = read(fd, buf, sizeof(buf));
- if (l < 0) {
-
- if (errno == EINTR)
- continue;
-
- if (errno == EAGAIN)
- return 0;
-
- return -errno;
- } else if (l == 0)
- return 0;
- }
-}
-
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
- uint8_t *p = buf;
- ssize_t n = 0;
-
- assert(fd >= 0);
- assert(buf);
-
- /* If called with nbytes == 0, let's call read() at least
- * once, to validate the operation */
-
- if (nbytes > (size_t) SSIZE_MAX)
- return -EINVAL;
-
- do {
- ssize_t k;
-
- k = read(fd, p, nbytes);
- if (k < 0) {
- if (errno == EINTR)
- continue;
-
- if (errno == EAGAIN && do_poll) {
-
- /* We knowingly ignore any return value here,
- * and expect that any error/EOF is reported
- * via read() */
-
- (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
- continue;
- }
-
- return n > 0 ? n : -errno;
- }
-
- if (k == 0)
- return n;
-
- assert((size_t) k <= nbytes);
-
- p += k;
- nbytes -= k;
- n += k;
- } while (nbytes > 0);
-
- return n;
-}
-
-int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
- ssize_t n;
-
- n = loop_read(fd, buf, nbytes, do_poll);
- if (n < 0)
- return (int) n;
- if ((size_t) n != nbytes)
- return -EIO;
-
- return 0;
-}
-
-int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
- const uint8_t *p = buf;
-
- assert(fd >= 0);
- assert(buf);
-
- if (nbytes > (size_t) SSIZE_MAX)
- return -EINVAL;
-
- do {
- ssize_t k;
-
- k = write(fd, p, nbytes);
- if (k < 0) {
- if (errno == EINTR)
- continue;
-
- if (errno == EAGAIN && do_poll) {
- /* We knowingly ignore any return value here,
- * and expect that any error/EOF is reported
- * via write() */
-
- (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
- continue;
- }
-
- return -errno;
- }
-
- if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
- return -EIO;
-
- assert((size_t) k <= nbytes);
-
- p += k;
- nbytes -= k;
- } while (nbytes > 0);
-
- return 0;
-}
-
int parse_size(const char *t, uint64_t base, uint64_t *size) {
/* Soo, sometimes we want to parse IEC binary suffixes, and
@@ -1573,55 +1396,6 @@ void rename_process(const char name[8]) {
}
}
-char *lookup_uid(uid_t uid) {
- long bufsize;
- char *name;
- _cleanup_free_ char *buf = NULL;
- struct passwd pwbuf, *pw = NULL;
-
- /* Shortcut things to avoid NSS lookups */
- if (uid == 0)
- return strdup("root");
-
- bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
- if (bufsize <= 0)
- bufsize = 4096;
-
- buf = malloc(bufsize);
- if (!buf)
- return NULL;
-
- if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
- return strdup(pw->pw_name);
-
- if (asprintf(&name, UID_FMT, uid) < 0)
- return NULL;
-
- return name;
-}
-
-char* getlogname_malloc(void) {
- uid_t uid;
- struct stat st;
-
- if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
- uid = st.st_uid;
- else
- uid = getuid();
-
- return lookup_uid(uid);
-}
-
-char *getusername_malloc(void) {
- const char *e;
-
- e = getenv("USER");
- if (e)
- return strdup(e);
-
- return lookup_uid(getuid());
-}
-
bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
assert(s);
assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
@@ -2057,44 +1831,6 @@ bool plymouth_running(void) {
return access("/run/plymouth/pid", F_OK) >= 0;
}
-int pipe_eof(int fd) {
- struct pollfd pollfd = {
- .fd = fd,
- .events = POLLIN|POLLHUP,
- };
-
- int r;
-
- r = poll(&pollfd, 1, 0);
- if (r < 0)
- return -errno;
-
- if (r == 0)
- return 0;
-
- return pollfd.revents & POLLHUP;
-}
-
-int fd_wait_for_event(int fd, int event, usec_t t) {
-
- struct pollfd pollfd = {
- .fd = fd,
- .events = event,
- };
-
- struct timespec ts;
- int r;
-
- r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
- if (r < 0)
- return -errno;
-
- if (r == 0)
- return 0;
-
- return pollfd.revents;
-}
-
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
FILE *f;
char *t;
@@ -2248,182 +1984,6 @@ int socket_from_display(const char *display, char **path) {
return 0;
}
-int get_user_creds(
- const char **username,
- uid_t *uid, gid_t *gid,
- const char **home,
- const char **shell) {
-
- struct passwd *p;
- uid_t u;
-
- assert(username);
- assert(*username);
-
- /* We enforce some special rules for uid=0: in order to avoid
- * NSS lookups for root we hardcode its data. */
-
- if (streq(*username, "root") || streq(*username, "0")) {
- *username = "root";
-
- if (uid)
- *uid = 0;
-
- if (gid)
- *gid = 0;
-
- if (home)
- *home = "/root";
-
- if (shell)
- *shell = "/bin/sh";
-
- return 0;
- }
-
- if (parse_uid(*username, &u) >= 0) {
- errno = 0;
- p = getpwuid(u);
-
- /* If there are multiple users with the same id, make
- * sure to leave $USER to the configured value instead
- * of the first occurrence in the database. However if
- * the uid was configured by a numeric uid, then let's
- * pick the real username from /etc/passwd. */
- if (p)
- *username = p->pw_name;
- } else {
- errno = 0;
- p = getpwnam(*username);
- }
-
- if (!p)
- return errno > 0 ? -errno : -ESRCH;
-
- if (uid)
- *uid = p->pw_uid;
-
- if (gid)
- *gid = p->pw_gid;
-
- if (home)
- *home = p->pw_dir;
-
- if (shell)
- *shell = p->pw_shell;
-
- return 0;
-}
-
-char* uid_to_name(uid_t uid) {
- struct passwd *p;
- char *r;
-
- if (uid == 0)
- return strdup("root");
-
- p = getpwuid(uid);
- if (p)
- return strdup(p->pw_name);
-
- if (asprintf(&r, UID_FMT, uid) < 0)
- return NULL;
-
- return r;
-}
-
-char* gid_to_name(gid_t gid) {
- struct group *p;
- char *r;
-
- if (gid == 0)
- return strdup("root");
-
- p = getgrgid(gid);
- if (p)
- return strdup(p->gr_name);
-
- if (asprintf(&r, GID_FMT, gid) < 0)
- return NULL;
-
- return r;
-}
-
-int get_group_creds(const char **groupname, gid_t *gid) {
- struct group *g;
- gid_t id;
-
- assert(groupname);
-
- /* We enforce some special rules for gid=0: in order to avoid
- * NSS lookups for root we hardcode its data. */
-
- if (streq(*groupname, "root") || streq(*groupname, "0")) {
- *groupname = "root";
-
- if (gid)
- *gid = 0;
-
- return 0;
- }
-
- if (parse_gid(*groupname, &id) >= 0) {
- errno = 0;
- g = getgrgid(id);
-
- if (g)
- *groupname = g->gr_name;
- } else {
- errno = 0;
- g = getgrnam(*groupname);
- }
-
- if (!g)
- return errno > 0 ? -errno : -ESRCH;
-
- if (gid)
- *gid = g->gr_gid;
-
- return 0;
-}
-
-int in_gid(gid_t gid) {
- gid_t *gids;
- int ngroups_max, r, i;
-
- if (getgid() == gid)
- return 1;
-
- if (getegid() == gid)
- return 1;
-
- ngroups_max = sysconf(_SC_NGROUPS_MAX);
- assert(ngroups_max > 0);
-
- gids = alloca(sizeof(gid_t) * ngroups_max);
-
- r = getgroups(ngroups_max, gids);
- if (r < 0)
- return -errno;
-
- for (i = 0; i < r; i++)
- if (gids[i] == gid)
- return 1;
-
- return 0;
-}
-
-int in_group(const char *name) {
- int r;
- gid_t gid;
-
- r = get_group_creds(&name, &gid);
- if (r < 0)
- return r;
-
- return in_gid(gid);
-}
-
int glob_exists(const char *path) {
_cleanup_globfree_ glob_t g = {};
int k;
@@ -2710,15 +2270,6 @@ static const char* const rlimit_table[_RLIMIT_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
-static const char* const ip_tos_table[] = {
- [IPTOS_LOWDELAY] = "low-delay",
- [IPTOS_THROUGHPUT] = "throughput",
- [IPTOS_RELIABILITY] = "reliability",
- [IPTOS_LOWCOST] = "low-cost",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
-
bool kexec_loaded(void) {
bool loaded = false;
char *s;
@@ -2801,41 +2352,6 @@ void* memdup(const void *p, size_t l) {
return r;
}
-int fd_inc_sndbuf(int fd, size_t n) {
- int r, value;
- socklen_t l = sizeof(value);
-
- r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
- if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
- return 0;
-
- /* If we have the privileges we will ignore the kernel limit. */
-
- value = (int) n;
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
- return -errno;
-
- return 1;
-}
-
-int fd_inc_rcvbuf(int fd, size_t n) {
- int r, value;
- socklen_t l = sizeof(value);
-
- r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
- if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
- return 0;
-
- /* If we have the privileges we will ignore the kernel limit. */
-
- value = (int) n;
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
- return -errno;
- return 1;
-}
-
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
bool stdout_is_tty, stderr_is_tty;
pid_t parent_pid, agent_pid;
@@ -3038,100 +2554,6 @@ bool in_initrd(void) {
return saved;
}
-int get_home_dir(char **_h) {
- struct passwd *p;
- const char *e;
- char *h;
- uid_t u;
-
- assert(_h);
-
- /* Take the user specified one */
- e = secure_getenv("HOME");
- if (e && path_is_absolute(e)) {
- h = strdup(e);
- if (!h)
- return -ENOMEM;
-
- *_h = h;
- return 0;
- }
-
- /* Hardcode home directory for root to avoid NSS */
- u = getuid();
- if (u == 0) {
- h = strdup("/root");
- if (!h)
- return -ENOMEM;
-
- *_h = h;
- return 0;
- }
-
- /* Check the database... */
- errno = 0;
- p = getpwuid(u);
- if (!p)
- return errno > 0 ? -errno : -ESRCH;
-
- if (!path_is_absolute(p->pw_dir))
- return -EINVAL;
-
- h = strdup(p->pw_dir);
- if (!h)
- return -ENOMEM;
-
- *_h = h;
- return 0;
-}
-
-int get_shell(char **_s) {
- struct passwd *p;
- const char *e;
- char *s;
- uid_t u;
-
- assert(_s);
-
- /* Take the user specified one */
- e = getenv("SHELL");
- if (e) {
- s = strdup(e);
- if (!s)
- return -ENOMEM;
-
- *_s = s;
- return 0;
- }
-
- /* Hardcode home directory for root to avoid NSS */
- u = getuid();
- if (u == 0) {
- s = strdup("/bin/sh");
- if (!s)
- return -ENOMEM;
-
- *_s = s;
- return 0;
- }
-
- /* Check the database... */
- errno = 0;
- p = getpwuid(u);
- if (!p)
- return errno > 0 ? -errno : -ESRCH;
-
- if (!path_is_absolute(p->pw_shell))
- return -EINVAL;
-
- s = strdup(p->pw_shell);
- if (!s)
- return -ENOMEM;
-
- *_s = s;
- return 0;
-}
-
bool filename_is_valid(const char *p) {
if (isempty(p))
@@ -3797,73 +3219,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
return reset_uid_gid();
}
-int getpeercred(int fd, struct ucred *ucred) {
- socklen_t n = sizeof(struct ucred);
- struct ucred u;
- int r;
-
- assert(fd >= 0);
- assert(ucred);
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
- if (r < 0)
- return -errno;
-
- if (n != sizeof(struct ucred))
- return -EIO;
-
- /* Check if the data is actually useful and not suppressed due
- * to namespacing issues */
- if (u.pid <= 0)
- return -ENODATA;
- if (u.uid == UID_INVALID)
- return -ENODATA;
- if (u.gid == GID_INVALID)
- return -ENODATA;
-
- *ucred = u;
- return 0;
-}
-
-int getpeersec(int fd, char **ret) {
- socklen_t n = 64;
- char *s;
- int r;
-
- assert(fd >= 0);
- assert(ret);
-
- s = new0(char, n);
- if (!s)
- return -ENOMEM;
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
- if (r < 0) {
- free(s);
-
- if (errno != ERANGE)
- return -errno;
-
- s = new0(char, n);
- if (!s)
- return -ENOMEM;
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
- if (r < 0) {
- free(s);
- return -errno;
- }
- }
-
- if (isempty(s)) {
- free(s);
- return -EOPNOTSUPP;
- }
-
- *ret = s;
- return 0;
-}
-
/* This is much like like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern, int flags) {
_cleanup_umask_ mode_t u;
@@ -4661,78 +4016,6 @@ int read_attr_path(const char *p, unsigned *ret) {
return read_attr_fd(fd, ret);
}
-static size_t nul_length(const uint8_t *p, size_t sz) {
- size_t n = 0;
-
- while (sz > 0) {
- if (*p != 0)
- break;
-
- n++;
- p++;
- sz--;
- }
-
- return n;
-}
-
-ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
- const uint8_t *q, *w, *e;
- ssize_t l;
-
- q = w = p;
- e = q + sz;
- while (q < e) {
- size_t n;
-
- n = nul_length(q, e - q);
-
- /* If there are more than the specified run length of
- * NUL bytes, or if this is the beginning or the end
- * of the buffer, then seek instead of write */
- if ((n > run_length) ||
- (n > 0 && q == p) ||
- (n > 0 && q + n >= e)) {
- if (q > w) {
- l = write(fd, w, q - w);
- if (l < 0)
- return -errno;
- if (l != q -w)
- return -EIO;
- }
-
- if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
- return -errno;
-
- q += n;
- w = q;
- } else if (n > 0)
- q += n;
- else
- q ++;
- }
-
- if (q > w) {
- l = write(fd, w, q - w);
- if (l < 0)
- return -errno;
- if (l != q - w)
- return -EIO;
- }
-
- return q - (const uint8_t*) p;
-}
-
-void sigkill_wait(pid_t *pid) {
- if (!pid)
- return;
- if (*pid <= 1)
- return;
-
- if (kill(*pid, SIGKILL) > 0)
- (void) wait_for_terminate(*pid, NULL);
-}
-
int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
int a = 0, b = 0, c = 0;
int k;
@@ -4867,20 +4150,6 @@ int mount_move_root(const char *path) {
return 0;
}
-int reset_uid_gid(void) {
-
- if (setgroups(0, NULL) < 0)
- return -errno;
-
- if (setresgid(0, 0, 0) < 0)
- return -errno;
-
- if (setresuid(0, 0, 0) < 0)
- return -errno;
-
- return 0;
-}
-
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
char *v;
size_t l;
@@ -4951,75 +4220,6 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
}
}
-int send_one_fd(int transport_fd, int fd, int flags) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
-
- assert(transport_fd >= 0);
- assert(fd >= 0);
-
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
- mh.msg_controllen = CMSG_SPACE(sizeof(int));
- if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
- return -errno;
-
- return 0;
-}
-
-int receive_one_fd(int transport_fd, int flags) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg, *found = NULL;
-
- assert(transport_fd >= 0);
-
- /*
- * Receive a single FD via @transport_fd. We don't care for
- * the transport-type. We retrieve a single FD at most, so for
- * packet-based transports, the caller must ensure to send
- * only a single FD per packet. This is best used in
- * combination with send_one_fd().
- */
-
- if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
- return -errno;
-
- CMSG_FOREACH(cmsg, &mh) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- assert(!found);
- found = cmsg;
- break;
- }
- }
-
- if (!found) {
- cmsg_close_all(&mh);
- return -EIO;
- }
-
- return *(int*) CMSG_DATA(found);
-}
-
void nop_signal_handler(int sig) {
/* nothing here */
}
diff --git a/src/basic/util.h b/src/basic/util.h
index e50fd69664..f32033767a 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -91,14 +91,6 @@ int parse_size(const char *t, uint64_t base, uint64_t *size);
int parse_boolean(const char *v) _pure_;
int parse_pid(const char *s, pid_t* ret_pid);
-int parse_uid(const char *s, uid_t* ret_uid);
-#define parse_gid(s, ret_gid) parse_uid(s, ret_gid)
-
-bool uid_is_valid(uid_t uid);
-
-static inline bool gid_is_valid(gid_t gid) {
- return uid_is_valid((uid_t) gid);
-}
int safe_atou(const char *s, unsigned *ret_u);
int safe_atoi(const char *s, int *ret_i);
@@ -237,14 +229,8 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k
bool fstype_is_network(const char *fstype);
-int flush_fd(int fd);
-
int fopen_temporary(const char *path, FILE **_f, char **_temp_path);
-ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll);
-int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll);
-int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll);
-
bool is_device_path(const char *path);
int dir_is_empty(const char *path);
@@ -258,10 +244,6 @@ static inline int dir_is_populated(const char *path) {
return !r;
}
-char* lookup_uid(uid_t uid);
-char* getlogname_malloc(void);
-char* getusername_malloc(void);
-
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
@@ -274,8 +256,6 @@ int path_check_fstype(const char *path, statfs_f_type_t magic_value);
bool is_temporary_fs(const struct statfs *s) _pure_;
int fd_is_temporary_fs(int fd);
-int pipe_eof(int fd);
-
#define xsprintf(buf, fmt, ...) \
assert_message_se((size_t) snprintf(buf, ELEMENTSOF(buf), fmt, __VA_ARGS__) < ELEMENTSOF(buf), \
"xsprintf: " #buf "[] must be big enough")
@@ -312,15 +292,6 @@ int fchmod_umask(int fd, mode_t mode);
bool display_is_local(const char *display) _pure_;
int socket_from_display(const char *display, char **path);
-int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home, const char **shell);
-int get_group_creds(const char **groupname, gid_t *gid);
-
-int in_gid(gid_t gid);
-int in_group(const char *name);
-
-char* uid_to_name(uid_t uid);
-char* gid_to_name(gid_t gid);
-
int glob_exists(const char *path);
int glob_extend(char ***strv, const char *path);
@@ -358,9 +329,6 @@ int sched_policy_from_string(const char *s);
const char *rlimit_to_string(int i) _const_;
int rlimit_from_string(const char *s) _pure_;
-int ip_tos_to_string_alloc(int i, char **s);
-int ip_tos_from_string(const char *s);
-
extern int saved_argc;
extern char **saved_argv;
@@ -370,13 +338,8 @@ int prot_from_flags(int flags) _const_;
char *format_bytes(char *buf, size_t l, uint64_t t);
-int fd_wait_for_event(int fd, int event, usec_t timeout);
-
void* memdup(const void *p, size_t l) _alloc_(2);
-int fd_inc_sndbuf(int fd, size_t n);
-int fd_inc_rcvbuf(int fd, size_t n);
-
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
int setrlimit_closest(int resource, const struct rlimit *rlim);
@@ -388,9 +351,6 @@ bool http_etag_is_valid(const char *etag);
bool in_initrd(void);
-int get_home_dir(char **ret);
-int get_shell(char **_ret);
-
static inline void freep(void *p) {
free(*(void**) p);
}
@@ -644,11 +604,6 @@ int container_get_leader(const char *machine, pid_t *pid);
int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
-int getpeercred(int fd, struct ucred *ucred);
-int getpeersec(int fd, char **ret);
-
-int writev_safe(int fd, const struct iovec *w, int j);
-
int mkostemp_safe(char *pattern, int flags);
int open_tmpfile(const char *path, int flags);
@@ -721,11 +676,6 @@ int read_attr_path(const char *p, unsigned *ret);
#define RLIMIT_MAKE_CONST(lim) ((struct rlimit) { lim, lim })
-ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length);
-
-void sigkill_wait(pid_t *pid);
-#define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait)
-
int syslog_parse_priority(const char **p, int *priority, bool with_facility);
int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
@@ -734,14 +684,9 @@ int parse_mode(const char *s, mode_t *ret);
int mount_move_root(const char *path);
-int reset_uid_gid(void);
-
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
int fgetxattr_malloc(int fd, const char *name, char **value);
-int send_one_fd(int transport_fd, int fd, int flags);
-int receive_one_fd(int transport_fd, int flags);
-
void nop_signal_handler(int sig);
int version(void);
diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c
index a1699f8736..ef113ed40c 100644
--- a/src/bootchart/bootchart.c
+++ b/src/bootchart/bootchart.c
@@ -52,6 +52,7 @@
#include "conf-parser.h"
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "list.h"
#include "macro.h"
#include "path-util.h"
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 1bbf984a2e..7e7574568c 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -43,6 +43,7 @@
#include "proxy.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static char *arg_address = NULL;
diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c
index c5a1e09cf8..56dcfeab62 100644
--- a/src/bus-proxyd/bus-xml-policy.c
+++ b/src/bus-proxyd/bus-xml-policy.c
@@ -22,14 +22,15 @@
#include "sd-login.h"
#include "bus-internal.h"
+#include "bus-xml-policy.h"
#include "conf-files.h"
#include "fileio.h"
#include "formats-util.h"
#include "set.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "xml.h"
-#include "bus-xml-policy.h"
static void policy_item_free(PolicyItem *i) {
assert(i);
diff --git a/src/bus-proxyd/stdio-bridge.c b/src/bus-proxyd/stdio-bridge.c
index 168fc9ead0..a009ea76c4 100644
--- a/src/bus-proxyd/stdio-bridge.c
+++ b/src/bus-proxyd/stdio-bridge.c
@@ -37,6 +37,7 @@
#include "log.h"
#include "proxy.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static char *arg_address = NULL;
diff --git a/src/core/automount.c b/src/core/automount.c
index c25038ca50..d362d6579d 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -36,6 +36,7 @@
#include "dbus-automount.h"
#include "fd-util.h"
#include "formats-util.h"
+#include "io-util.h"
#include "label.h"
#include "mkdir.h"
#include "mount.h"
diff --git a/src/core/bus-policy.c b/src/core/bus-policy.c
index a6a8fcd4d3..2490903a8c 100644
--- a/src/core/bus-policy.c
+++ b/src/core/bus-policy.c
@@ -19,10 +19,11 @@
#include <stdlib.h>
-#include "kdbus.h"
-#include "util.h"
#include "bus-kernel.h"
#include "bus-policy.h"
+#include "kdbus.h"
+#include "user-util.h"
+#include "util.h"
int bus_kernel_translate_access(BusPolicyAccess access) {
assert(access >= 0);
diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c
index 318e81abd6..0c91850c52 100644
--- a/src/core/dbus-mount.c
+++ b/src/core/dbus-mount.c
@@ -118,7 +118,7 @@ const sd_bus_vtable bus_mount_vtable[] = {
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Mount, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Mount, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SloppyOptions", "b", bus_property_get_bool, offsetof(Mount, sloppy_options), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("SmackFileSystemRoot", "s", NULL, offsetof(Mount, smack_fs_root), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("SmackFileSystemRootLabel", "s", NULL, offsetof(Mount, smack_fs_root_label), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Mount, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
BUS_EXEC_COMMAND_VTABLE("ExecMount", offsetof(Mount, exec_command[MOUNT_EXEC_MOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
BUS_EXEC_COMMAND_VTABLE("ExecUnmount", offsetof(Mount, exec_command[MOUNT_EXEC_UNMOUNT]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
diff --git a/src/core/execute.c b/src/core/execute.c
index 83ae3f6253..3f2607ff1a 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -69,6 +69,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "formats-util.h"
+#include "io-util.h"
#include "ioprio.h"
#include "log.h"
#include "macro.h"
@@ -89,6 +90,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "unit.h"
+#include "user-util.h"
#include "util.h"
#include "utmp-wtmp.h"
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 507cfdde75..c3b48aec4c 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -319,7 +319,7 @@ Mount.Type, config_parse_string, 0,
Mount.TimeoutSec, config_parse_sec, 0, offsetof(Mount, timeout_usec)
Mount.DirectoryMode, config_parse_mode, 0, offsetof(Mount, directory_mode)
Mount.SloppyOptions, config_parse_bool, 0, offsetof(Mount, sloppy_options)
-Mount.SmackFileSystemRoot, config_parse_string, 0, offsetof(Mount, smack_fs_root)
+Mount.SmackFileSystemRootLabel, config_parse_string, 0, offsetof(Mount, smack_fs_root_label)
EXEC_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Mount)m4_dnl
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index f59bf56c73..c72892b343 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -31,6 +31,7 @@
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "log.h"
#include "machine-id-setup.h"
#include "macro.h"
diff --git a/src/core/main.c b/src/core/main.c
index 68ec730406..b0ca6fa10e 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -76,6 +76,7 @@
#include "strv.h"
#include "switch-root.h"
#include "terminal-util.h"
+#include "user-util.h"
#include "virt.h"
#include "watchdog.h"
diff --git a/src/core/manager.c b/src/core/manager.c
index 400c66977b..287676ff27 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -55,6 +55,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "hashmap.h"
+#include "io-util.h"
#include "locale-setup.h"
#include "log.h"
#include "macro.h"
diff --git a/src/core/mount.c b/src/core/mount.c
index 47dd680b93..ebdb3503e9 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -206,7 +206,7 @@ static void mount_done(Unit *u) {
assert(m);
m->where = mfree(m->where);
- m->smack_fs_root = mfree(m->smack_fs_root);
+ m->smack_fs_root_label = mfree(m->smack_fs_root_label);
mount_parameters_done(&m->parameters_proc_self_mountinfo);
mount_parameters_done(&m->parameters_fragment);
@@ -672,7 +672,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
"%sFrom /proc/self/mountinfo: %s\n"
"%sFrom fragment: %s\n"
"%sDirectoryMode: %04o\n"
- "%sSmackFileSystemRoot: %s\n",
+ "%sSmackFileSystemRootLabel: %s\n",
prefix, mount_state_to_string(m->state),
prefix, mount_result_to_string(m->result),
prefix, m->where,
@@ -682,7 +682,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
prefix, yes_no(m->from_proc_self_mountinfo),
prefix, yes_no(m->from_fragment),
prefix, m->directory_mode,
- prefix, strna(m->smack_fs_root));
+ prefix, strna(m->smack_fs_root_label));
if (m->control_pid > 0)
fprintf(f,
@@ -868,12 +868,12 @@ static int mount_get_opts(Mount *m, char **_opts) {
if (r < 0)
return r;
- if (mac_smack_use() && m->smack_fs_root) {
+ if (mac_smack_use() && m->smack_fs_root_label) {
if (!isempty(o)) {
- opts = strjoin(o, ",", "smackfsroot=", m->smack_fs_root, NULL);
+ opts = strjoin(o, ",", "smackfsroot=", m->smack_fs_root_label, NULL);
free(o);
} else
- opts = strjoin("smackfsroot=", m->smack_fs_root, NULL);
+ opts = strjoin("smackfsroot=", m->smack_fs_root_label, NULL);
if (!opts)
return -ENOMEM;
diff --git a/src/core/mount.h b/src/core/mount.h
index 4e28810f6c..b344b5aa13 100644
--- a/src/core/mount.h
+++ b/src/core/mount.h
@@ -71,7 +71,7 @@ struct Mount {
bool reset_cpu_usage:1;
bool sloppy_options;
- char *smack_fs_root;
+ char *smack_fs_root_label;
MountResult result;
MountResult reload_result;
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 470f384056..4d11d54bfe 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -36,6 +36,7 @@
#include "namespace.h"
#include "path-util.h"
#include "selinux-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
diff --git a/src/core/socket.c b/src/core/socket.c
index e2085dac1c..7f401025ed 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -54,6 +54,7 @@
#include "unit-name.h"
#include "unit-printf.h"
#include "unit.h"
+#include "user-util.h"
static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
[SOCKET_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/timer.c b/src/core/timer.c
index 4548a4fa52..908d45ac73 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -26,9 +26,10 @@
#include "dbus-timer.h"
#include "special.h"
#include "string-util.h"
+#include "timer.h"
#include "unit-name.h"
#include "unit.h"
-#include "timer.h"
+#include "user-util.h"
static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
[TIMER_DEAD] = UNIT_INACTIVE,
diff --git a/src/core/umount.c b/src/core/umount.c
index 0e61bcaebb..8735bed7b1 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -31,6 +31,7 @@
#include "escape.h"
#include "fd-util.h"
+#include "fstab-util.h"
#include "list.h"
#include "mount-setup.h"
#include "path-util.h"
@@ -42,6 +43,7 @@
typedef struct MountPoint {
char *path;
+ char *options;
dev_t devnum;
LIST_FIELDS(struct MountPoint, mount_point);
} MountPoint;
@@ -75,7 +77,7 @@ static int mount_points_list_get(MountPoint **head) {
return -errno;
for (i = 1;; i++) {
- _cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *path = NULL, *options = NULL;
char *p = NULL;
MountPoint *m;
int k;
@@ -86,15 +88,15 @@ static int mount_points_list_get(MountPoint **head) {
"%*s " /* (3) major:minor */
"%*s " /* (4) root */
"%ms " /* (5) mount point */
- "%*s" /* (6) mount options */
+ "%*s" /* (6) mount flags */
"%*[^-]" /* (7) optional fields */
"- " /* (8) separator */
"%*s " /* (9) file system type */
"%*s" /* (10) mount source */
- "%*s" /* (11) mount options 2 */
+ "%ms" /* (11) mount options */
"%*[^\n]", /* some rubbish at the end */
- &path);
- if (k != 1) {
+ &path, &options);
+ if (k != 2) {
if (k == EOF)
break;
@@ -129,6 +131,9 @@ static int mount_points_list_get(MountPoint **head) {
}
m->path = p;
+ m->options = options;
+ options = NULL;
+
LIST_PREPEND(mount_point, *head, m);
}
@@ -373,6 +378,14 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
benefits, but might confuse the host, as we remount
the superblock here, not the bind mound. */
if (detect_container() <= 0) {
+ _cleanup_free_ char *options = NULL;
+ /* MS_REMOUNT requires that the data parameter
+ * should be the same from the original mount
+ * except for the desired changes. Since we want
+ * to remount read-only, we should filter out
+ * rw (and ro too, because it confuses the kernel) */
+ (void) fstab_filter_options(m->options, "rw\0ro\0", NULL, NULL, &options);
+
/* We always try to remount directories
* read-only first, before we go on and umount
* them.
@@ -389,7 +402,8 @@ static int mount_points_list_umount(MountPoint **head, bool *changed, bool log_e
* alias read-only we hence should be
* relatively safe regarding keeping the fs we
* can otherwise not see dirty. */
- (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
+ log_info("Remounting '%s' read-only with options '%s'.", m->path, options);
+ (void) mount(NULL, m->path, NULL, MS_REMOUNT|MS_RDONLY, options);
}
/* Skip / and /usr since we cannot unmount that
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index 5b62f2d65c..4a5c7efdb0 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -26,8 +26,9 @@
#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
-#include "unit.h"
#include "unit-printf.h"
+#include "unit.h"
+#include "user-util.h"
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
Unit *u = userdata;
diff --git a/src/core/unit.c b/src/core/unit.c
index a054cc79b0..572b1c1b78 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -51,8 +51,9 @@
#include "string-util.h"
#include "strv.h"
#include "unit-name.h"
-#include "virt.h"
#include "unit.h"
+#include "user-util.h"
+#include "virt.h"
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
[UNIT_SERVICE] = &service_vtable,
diff --git a/src/import/import-raw.c b/src/import/import-raw.c
index f8fc6c108a..a34f30abfc 100644
--- a/src/import/import-raw.c
+++ b/src/import/import-raw.c
@@ -31,6 +31,7 @@
#include "import-common.h"
#include "import-compress.h"
#include "import-raw.h"
+#include "io-util.h"
#include "machine-pool.h"
#include "mkdir.h"
#include "path-util.h"
diff --git a/src/import/import-tar.c b/src/import/import-tar.c
index bc0cd9f5ba..9aade0f430 100644
--- a/src/import/import-tar.c
+++ b/src/import/import-tar.c
@@ -31,6 +31,7 @@
#include "import-common.h"
#include "import-compress.h"
#include "import-tar.h"
+#include "io-util.h"
#include "machine-pool.h"
#include "mkdir.h"
#include "path-util.h"
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index e98554b60c..f465154b1d 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -26,6 +26,7 @@
#include "copy.h"
#include "escape.h"
#include "fd-util.h"
+#include "io-util.h"
#include "process-util.h"
#include "pull-common.h"
#include "pull-job.h"
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index 7a0fb54bbe..4736306de2 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -22,6 +22,7 @@
#include <sys/xattr.h>
#include "fd-util.h"
+#include "io-util.h"
#include "machine-pool.h"
#include "pull-job.h"
#include "string-util.h"
diff --git a/src/journal/compress.c b/src/journal/compress.c
index 92f584777c..9308e8b789 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -35,6 +35,7 @@
#include "compress.h"
#include "fd-util.h"
+#include "io-util.h"
#include "journal-def.h"
#include "macro.h"
#include "sparse-endian.h"
diff --git a/src/journal/coredump-vacuum.c b/src/journal/coredump-vacuum.c
index 92259fd5ef..bad6ea4242 100644
--- a/src/journal/coredump-vacuum.c
+++ b/src/journal/coredump-vacuum.c
@@ -27,6 +27,7 @@
#include "macro.h"
#include "string-util.h"
#include "time-util.h"
+#include "user-util.h"
#include "util.h"
#define DEFAULT_MAX_USE_LOWER (uint64_t) (1ULL*1024ULL*1024ULL) /* 1 MiB */
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 3b87eb5355..7336db219b 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -52,6 +52,7 @@
#include "stacktrace.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
/* The maximum size up to which we process coredumps */
diff --git a/src/journal/coredumpctl.c b/src/journal/coredumpctl.c
index a497a4781b..f891ddffc6 100644
--- a/src/journal/coredumpctl.c
+++ b/src/journal/coredumpctl.c
@@ -42,6 +42,7 @@
#include "string-util.h"
#include "terminal-util.h"
#include "util.h"
+#include "user-util.h"
static enum {
ACTION_NONE,
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index d42f8262a5..f388c30d2e 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -32,6 +32,7 @@
#include "sd-journal.h"
#include "fd-util.h"
+#include "io-util.h"
#include "memfd-util.h"
#include "socket-util.h"
#include "string-util.h"
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index dbb05e0527..6e452a4d51 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -46,6 +46,7 @@
#include "fileio.h"
#include "fsprg.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "journal-def.h"
#include "journal-internal.h"
#include "journal-qrcode.h"
@@ -61,6 +62,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "unit-name.h"
+#include "user-util.h"
#define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 012970bad3..7cefea323e 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -36,6 +36,7 @@
#include "acl-util.h"
#include "cgroup-util.h"
#include "conf-parser.h"
+#include "extract-word.h"
#include "fd-util.h"
#include "formats-util.h"
#include "hashmap.h"
@@ -1289,8 +1290,7 @@ static int setup_signals(Server *s) {
static int server_parse_proc_cmdline(Server *s) {
_cleanup_free_ char *line = NULL;
- const char *w, *state;
- size_t l;
+ const char *p;
int r;
r = proc_cmdline(&line);
@@ -1299,12 +1299,16 @@ static int server_parse_proc_cmdline(Server *s) {
return 0;
}
- FOREACH_WORD_QUOTED(w, l, line, state) {
+ p = line;
+ for(;;) {
_cleanup_free_ char *word;
- word = strndup(w, l);
- if (!word)
- return -ENOMEM;
+ r = extract_first_word(&p, &word, NULL, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse journald syntax \"%s\": %m", line);
+
+ if (r == 0)
+ break;
if (startswith(word, "systemd.journald.forward_to_syslog=")) {
r = parse_boolean(word + 35);
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index d39c0a900c..9dcfc726ea 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -29,6 +29,7 @@
#include <unistd.h>
#include "sd-journal.h"
+
#include "catalog.h"
#include "compress.h"
#include "fd-util.h"
@@ -36,6 +37,7 @@
#include "formats-util.h"
#include "hashmap.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "journal-def.h"
#include "journal-file.h"
#include "journal-internal.h"
diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c
index 3273d9b0c2..42d7f80461 100644
--- a/src/libsystemd/sd-bus/bus-socket.c
+++ b/src/libsystemd/sd-bus/bus-socket.c
@@ -36,6 +36,7 @@
#include "missing.h"
#include "signal-util.h"
#include "string-util.h"
+#include "user-util.h"
#include "utf8.h"
#include "util.h"
diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c
index b55e81ce97..d3e846db84 100644
--- a/src/libsystemd/sd-bus/busctl.c
+++ b/src/libsystemd/sd-bus/busctl.c
@@ -37,6 +37,7 @@
#include "set.h"
#include "strv.h"
#include "terminal-util.h"
+#include "user-util.h"
#include "util.h"
static bool arg_no_pager = false;
diff --git a/src/libsystemd/sd-device/Makefile b/src/libsystemd/sd-device/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/libsystemd/sd-device/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
index ef89fd2572..335ad3b1b4 100644
--- a/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/libsystemd/sd-id128/sd-id128.c
@@ -25,10 +25,11 @@
#include "sd-id128.h"
+#include "fd-util.h"
+#include "io-util.h"
#include "macro.h"
#include "random-util.h"
#include "util.h"
-#include "fd-util.h"
_public_ char *sd_id128_to_string(sd_id128_t id, char s[SD_ID128_STRING_MAX]) {
unsigned n;
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 399918f834..f564d43e06 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -33,10 +33,13 @@
#include "fileio.h"
#include "formats-util.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "login-util.h"
#include "macro.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
/* Error codes:
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 57c5db1231..ba1f2a5a42 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -30,6 +30,7 @@
#include "missing.h"
#include "netlink-internal.h"
#include "netlink-util.h"
+#include "socket-util.h"
#include "util.h"
static int sd_netlink_new(sd_netlink **ret) {
diff --git a/src/libsystemd/sd-netlink/test-netlink.c b/src/libsystemd/sd-netlink/test-netlink.c
index 419a28725f..58b774e0e1 100644
--- a/src/libsystemd/sd-netlink/test-netlink.c
+++ b/src/libsystemd/sd-netlink/test-netlink.c
@@ -24,6 +24,7 @@
#include "sd-netlink.h"
+#include "ether-addr-util.h"
#include "event-util.h"
#include "macro.h"
#include "missing.h"
diff --git a/src/libsystemd/sd-path/sd-path.c b/src/libsystemd/sd-path/sd-path.c
index 2467c126ae..8e3eeb15d8 100644
--- a/src/libsystemd/sd-path/sd-path.c
+++ b/src/libsystemd/sd-path/sd-path.c
@@ -25,6 +25,7 @@
#include "path-util.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static int from_environment(const char *envname, const char *fallback, const char **ret) {
diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c
index 38e2dc0fdd..724405d534 100644
--- a/src/libsystemd/sd-resolve/sd-resolve.c
+++ b/src/libsystemd/sd-resolve/sd-resolve.c
@@ -34,6 +34,7 @@
#include "sd-resolve.h"
#include "fd-util.h"
+#include "io-util.h"
#include "list.h"
#include "missing.h"
#include "resolve-util.h"
diff --git a/src/libudev/libudev-queue.c b/src/libudev/libudev-queue.c
index 4d1a0adbf2..a22994c8a2 100644
--- a/src/libudev/libudev-queue.c
+++ b/src/libudev/libudev-queue.c
@@ -25,6 +25,7 @@
#include <sys/inotify.h>
#include "fd-util.h"
+#include "io-util.h"
#include "libudev-private.h"
/**
diff --git a/src/login/inhibit.c b/src/login/inhibit.c
index 5ff0957aed..f79f89af7e 100644
--- a/src/login/inhibit.c
+++ b/src/login/inhibit.c
@@ -34,6 +34,7 @@
#include "process-util.h"
#include "signal-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
static const char* arg_what = "idle:sleep:shutdown";
diff --git a/src/login/loginctl.c b/src/login/loginctl.c
index bfc8716009..1cd186dec3 100644
--- a/src/login/loginctl.c
+++ b/src/login/loginctl.c
@@ -42,6 +42,7 @@
#include "sysfs-show.h"
#include "terminal-util.h"
#include "unit-name.h"
+#include "user-util.h"
#include "util.h"
#include "verbs.h"
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index a44e369149..f06f8edc07 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -30,6 +30,7 @@
#include "formats-util.h"
#include "process-util.h"
#include "terminal-util.h"
+#include "user-util.h"
int manager_handle_action(
Manager *m,
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 3b6e982e9f..c2541e490b 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -33,6 +33,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "udev-util.h"
+#include "user-util.h"
int manager_add_device(Manager *m, const char *sysfs, bool master, Device **_device) {
Device *d;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 1677785467..61c2c9ba40 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -46,6 +46,7 @@
#include "terminal-util.h"
#include "udev-util.h"
#include "unit-name.h"
+#include "user-util.h"
#include "utmp-wtmp.h"
int manager_get_session_from_creds(Manager *m, sd_bus_message *message, const char *name, sd_bus_error *error, Session **ret) {
@@ -2027,7 +2028,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd
}
utmp_wall("The system shutdown has been cancelled",
- lookup_uid(uid), tty, logind_wall_tty_filter, m);
+ uid_to_name(uid), tty, logind_wall_tty_filter, m);
}
return sd_bus_reply_method_return(message, "b", cancelled);
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index ec34535f83..c4b74eb734 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -31,6 +31,7 @@
#include "logind-inhibit.h"
#include "mkdir.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
Inhibitor* inhibitor_new(Manager *m, const char* id) {
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index ead79ad327..714b1cb299 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -35,12 +35,15 @@
#include "bus-util.h"
#include "escape.h"
#include "fd-util.h"
+#include "fd-util.h"
#include "fileio.h"
#include "formats-util.h"
+#include "io-util.h"
#include "logind-session.h"
#include "mkdir.h"
#include "path-util.h"
#include "terminal-util.h"
+#include "user-util.h"
#include "util.h"
#define RELEASE_USEC (20*USEC_PER_SEC)
diff --git a/src/login/logind-user-dbus.c b/src/login/logind-user-dbus.c
index 20ea2fbdc4..5975b579e9 100644
--- a/src/login/logind-user-dbus.c
+++ b/src/login/logind-user-dbus.c
@@ -22,11 +22,12 @@
#include <errno.h>
#include <string.h>
-#include "strv.h"
#include "bus-util.h"
-#include "logind.h"
-#include "logind-user.h"
#include "formats-util.h"
+#include "logind-user.h"
+#include "logind.h"
+#include "strv.h"
+#include "user-util.h"
static int property_get_display(
sd_bus *bus,
diff --git a/src/login/logind-utmp.c b/src/login/logind-utmp.c
index 1e13ff01de..9c766bcb25 100644
--- a/src/login/logind-utmp.c
+++ b/src/login/logind-utmp.c
@@ -25,15 +25,17 @@
#include <pwd.h>
#include "sd-messages.h"
-#include "strv.h"
-#include "special.h"
-#include "unit-name.h"
+
#include "audit.h"
-#include "bus-util.h"
-#include "bus-error.h"
#include "bus-common-errors.h"
-#include "logind.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "formats-util.h"
+#include "logind.h"
+#include "special.h"
+#include "strv.h"
+#include "unit-name.h"
+#include "user-util.h"
#include "utmp-wtmp.h"
_const_ static usec_t when_wall(usec_t n, usec_t elapse) {
@@ -94,7 +96,7 @@ static int warn_wall(Manager *m, usec_t n) {
return 0;
}
- utmp_wall(l, lookup_uid(m->scheduled_shutdown_uid),
+ utmp_wall(l, uid_to_name(m->scheduled_shutdown_uid),
m->scheduled_shutdown_tty, logind_wall_tty_filter, m);
return 1;
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index b5ce6cdca2..3c91fa8644 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -41,6 +41,7 @@
#include "process-util.h"
#include "strv.h"
#include "unit-name.h"
+#include "user-util.h"
static int property_get_pool_path(
sd_bus *bus,
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index 3096c4f72a..d04bb9bd9f 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -23,8 +23,9 @@
#include <net/if.h>
#include <linux/if_tun.h>
-#include "networkd-netdev-tuntap.h"
#include "fd-util.h"
+#include "networkd-netdev-tuntap.h"
+#include "user-util.h"
#define TUN_DEV "/dev/net/tun"
diff --git a/src/network/networkd.c b/src/network/networkd.c
index e6259043fa..1a17847715 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -20,9 +20,11 @@
***/
#include "sd-daemon.h"
+
#include "capability.h"
-#include "signal-util.h"
#include "networkd.h"
+#include "signal-util.h"
+#include "user-util.h"
int main(int argc, char *argv[]) {
_cleanup_manager_free_ Manager *m = NULL;
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index df9fbe185b..98e4a7682f 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -27,6 +27,7 @@
#include "local-addresses.h"
#include "netlink-util.h"
#include "nspawn-expose-ports.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
diff --git a/src/nspawn/nspawn-setuid.c b/src/nspawn/nspawn-setuid.c
index 2a1dfd83a9..6b4ca5a3f3 100644
--- a/src/nspawn/nspawn-setuid.c
+++ b/src/nspawn/nspawn-setuid.c
@@ -29,6 +29,7 @@
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f95842d252..6502fe1943 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -86,10 +86,12 @@
#include "seccomp-util.h"
#endif
#include "signal-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "udev-util.h"
+#include "user-util.h"
#include "util.h"
typedef enum ContainerStatus {
diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c
index d05a32290b..b98bde676b 100644
--- a/src/nss-mymachines/nss-mymachines.c
+++ b/src/nss-mymachines/nss-mymachines.c
@@ -32,6 +32,7 @@
#include "macro.h"
#include "nss-util.h"
#include "string-util.h"
+#include "user-util.h"
#include "util.h"
NSS_GETHOSTBYNAME_PROTOTYPES(mymachines);
diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed.c
index 42841480c5..fbfd3a3eba 100644
--- a/src/random-seed/random-seed.c
+++ b/src/random-seed/random-seed.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include "fd-util.h"
+#include "io-util.h"
#include "log.h"
#include "mkdir.h"
#include "string-util.h"
diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c
index 65476fa38b..6144eedfeb 100644
--- a/src/resolve/resolved-manager.c
+++ b/src/resolve/resolved-manager.c
@@ -29,6 +29,7 @@
#include "fd-util.h"
#include "fileio-label.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "netlink-util.h"
#include "network-internal.h"
#include "ordered-set.h"
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 32e61af925..df4eb6f63e 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -19,15 +19,16 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "sd-event.h"
#include "sd-daemon.h"
-#include "mkdir.h"
+#include "sd-event.h"
+
#include "capability.h"
+#include "mkdir.h"
+#include "resolved-conf.h"
+#include "resolved-manager.h"
#include "selinux-util.h"
#include "signal-util.h"
-
-#include "resolved-manager.h"
-#include "resolved-conf.h"
+#include "user-util.h"
int main(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *m = NULL;
diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c
index df8fc0690d..311343e454 100644
--- a/src/rfkill/rfkill.c
+++ b/src/rfkill/rfkill.c
@@ -28,6 +28,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "mkdir.h"
#include "string-util.h"
#include "udev-util.h"
diff --git a/src/run/run.c b/src/run/run.c
index e81d0892e3..3646305961 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -39,6 +39,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "unit-name.h"
+#include "user-util.h"
static bool arg_ask_password = true;
static bool arg_scope = false;
diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c
index 47295ae379..e8931daee2 100644
--- a/src/shared/acl-util.c
+++ b/src/shared/acl-util.c
@@ -22,10 +22,11 @@
#include <errno.h>
#include <stdbool.h>
+#include "acl-util.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
-#include "acl-util.h"
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
acl_entry_t i;
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
index baa6f159f8..15203d21ea 100644
--- a/src/shared/ask-password-api.c
+++ b/src/shared/ask-password-api.c
@@ -35,6 +35,7 @@
#include "ask-password-api.h"
#include "fd-util.h"
#include "formats-util.h"
+#include "io-util.h"
#include "missing.h"
#include "mkdir.h"
#include "random-util.h"
diff --git a/src/shared/efivars.c b/src/shared/efivars.c
index b482603bce..4808ede60c 100644
--- a/src/shared/efivars.c
+++ b/src/shared/efivars.c
@@ -25,6 +25,7 @@
#include "efivars.h"
#include "fd-util.h"
+#include "io-util.h"
#include "utf8.h"
#include "util.h"
#include "virt.h"
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
index cbe984d2fb..224874f65c 100644
--- a/src/shared/install-printf.c
+++ b/src/shared/install-printf.c
@@ -21,11 +21,12 @@
#include <stdlib.h>
+#include "formats-util.h"
+#include "install-printf.h"
#include "specifier.h"
#include "unit-name.h"
+#include "user-util.h"
#include "util.h"
-#include "install-printf.h"
-#include "formats-util.h"
static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
UnitFileInstallInfo *i = userdata;
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 6f5b83d08d..d8ea4c9f92 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -29,6 +29,7 @@
#include "formats-util.h"
#include "hashmap.h"
#include "hostname-util.h"
+#include "io-util.h"
#include "journal-internal.h"
#include "log.h"
#include "logs-show.h"
diff --git a/src/shared/spawn-polkit-agent.c b/src/shared/spawn-polkit-agent.c
index 472cdecf20..7cc9e7ccc1 100644
--- a/src/shared/spawn-polkit-agent.c
+++ b/src/shared/spawn-polkit-agent.c
@@ -25,11 +25,12 @@
#include <errno.h>
#include <poll.h>
+#include "fd-util.h"
+#include "io-util.h"
#include "log.h"
-#include "util.h"
#include "process-util.h"
#include "spawn-polkit-agent.h"
-#include "fd-util.h"
+#include "util.h"
#ifdef ENABLE_POLKIT
static pid_t agent_pid = 0;
diff --git a/src/shared/uid-range.c b/src/shared/uid-range.c
index 4794ff45bb..079dd8752c 100644
--- a/src/shared/uid-range.c
+++ b/src/shared/uid-range.c
@@ -19,8 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "util.h"
#include "uid-range.h"
+#include "user-util.h"
+#include "util.h"
static bool uid_range_intersect(UidRange *range, uid_t start, uid_t nr) {
assert(range);
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index 93e6313360..1e6ac2f27d 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -33,6 +33,7 @@
#include "path-util.h"
#include "string-util.h"
#include "terminal-util.h"
+#include "user-util.h"
#include "utmp-wtmp.h"
int utmp_get_runlevel(int *runlevel, int *previous) {
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 213c3c30a0..fe4213c085 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -54,6 +54,7 @@
#include "hostname-util.h"
#include "initreq.h"
#include "install.h"
+#include "io-util.h"
#include "list.h"
#include "log.h"
#include "logs-show.h"
@@ -72,6 +73,7 @@
#include "strv.h"
#include "terminal-util.h"
#include "unit-name.h"
+#include "user-util.h"
#include "util.h"
#include "utmp-wtmp.h"
#include "verbs.h"
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 547bd1b344..177432bf9f 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -41,6 +41,7 @@
#include "utf8.h"
#include "util.h"
#include "fd-util.h"
+#include "user-util.h"
typedef enum ItemType {
ADD_USER = 'u',
diff --git a/src/test/test-ipcrm.c b/src/test/test-ipcrm.c
index 4944bf6ad9..5841cb3fb1 100644
--- a/src/test/test-ipcrm.c
+++ b/src/test/test-ipcrm.c
@@ -19,8 +19,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include "util.h"
#include "clean-ipc.h"
+#include "user-util.h"
+#include "util.h"
int main(int argc, char *argv[]) {
uid_t uid;
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
new file mode 100644
index 0000000000..dfd2031998
--- /dev/null
+++ b/src/test/test-user-util.c
@@ -0,0 +1,53 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "macro.h"
+#include "string-util.h"
+#include "user-util.h"
+#include "util.h"
+
+static void test_uid_to_name_one(uid_t uid, const char *name) {
+ _cleanup_free_ char *t = NULL;
+
+ assert_se(t = uid_to_name(uid));
+ assert_se(streq_ptr(t, name));
+}
+
+static void test_gid_to_name_one(gid_t gid, const char *name) {
+ _cleanup_free_ char *t = NULL;
+
+ assert_se(t = gid_to_name(gid));
+ assert_se(streq_ptr(t, name));
+}
+
+int main(int argc, char*argv[]) {
+
+ test_uid_to_name_one(0, "root");
+ test_uid_to_name_one(0xFFFF, "65535");
+ test_uid_to_name_one(0xFFFFFFFF, "4294967295");
+
+ test_gid_to_name_one(0, "root");
+ test_gid_to_name_one(TTY_GID, "tty");
+ test_gid_to_name_one(0xFFFF, "65535");
+ test_gid_to_name_one(0xFFFFFFFF, "4294967295");
+
+ return 0;
+}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index ddfcdd857b..c1f8a866af 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -35,7 +35,9 @@
#include "cpu-set-util.h"
#include "def.h"
#include "escape.h"
+#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "mkdir.h"
#include "process-util.h"
#include "rm-rf.h"
@@ -44,7 +46,7 @@
#include "strv.h"
#include "util.h"
#include "virt.h"
-#include "fd-util.h"
+#include "user-util.h"
static void test_streq_ptr(void) {
assert_se(streq_ptr(NULL, NULL));
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 7755a6d89f..7a0ab18ca0 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -29,6 +29,7 @@
#include "signal-util.h"
#include "timesyncd-conf.h"
#include "timesyncd-manager.h"
+#include "user-util.h"
static int load_clock_timestamp(uid_t uid, gid_t gid) {
_cleanup_close_ int fd = -1;
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index e574e5ac26..05c4661a2c 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -46,6 +46,7 @@
#include "escape.h"
#include "fd-util.h"
#include "formats-util.h"
+#include "io-util.h"
#include "label.h"
#include "log.h"
#include "macro.h"
@@ -58,6 +59,7 @@
#include "specifier.h"
#include "string-util.h"
#include "strv.h"
+#include "user-util.h"
#include "util.h"
/* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index 30f7f42a09..33419f6962 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -36,6 +36,7 @@
#include "conf-parser.h"
#include "def.h"
#include "fd-util.h"
+#include "io-util.h"
#include "mkdir.h"
#include "path-util.h"
#include "process-util.h"
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index f99d1a86c9..311d515645 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -38,6 +38,7 @@
#include "strv.h"
#include "sysctl-util.h"
#include "udev.h"
+#include "user-util.h"
#include "util.h"
#define PREALLOC_TOKEN 2048
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a548f9ba49..df5fd88bff 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -51,6 +51,7 @@
#include "fileio.h"
#include "formats-util.h"
#include "hashmap.h"
+#include "io-util.h"
#include "netlink-util.h"
#include "process-util.h"
#include "selinux-util.h"
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 4f67145b36..4c44d50613 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -20,6 +20,7 @@
***/
#include "fd-util.h"
+#include "io-util.h"
#include "selinux-util.h"
#include "util.h"
diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c
index a06f61dd6f..49523a0a67 100644
--- a/src/vconsole/vconsole-setup.c
+++ b/src/vconsole/vconsole-setup.c
@@ -33,6 +33,7 @@
#include "fd-util.h"
#include "fileio.h"
+#include "io-util.h"
#include "log.h"
#include "process-util.h"
#include "signal-util.h"
diff --git a/units/tmp.mount.m4 b/units/tmp.mount.m4
index e1e26bdfc0..6402200c62 100644
--- a/units/tmp.mount.m4
+++ b/units/tmp.mount.m4
@@ -20,5 +20,5 @@ Where=/tmp
Type=tmpfs
Options=mode=1777,strictatime
m4_ifdef(`HAVE_SMACK',
-SmackFileSystemRoot=*
+SmackFileSystemRootLabel=*
)m4_dnl