diff options
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 |