Compare commits

..

No commits in common. "0328d672f3ad72a4f07fcb23859678b99e352898" and "a6e1018df27d89b21ea254236692b5af38402776" have entirely different histories.

37 changed files with 195 additions and 416 deletions

View File

@ -469,7 +469,6 @@ sensor:modalias:acpi:SMO8500*:dmi:*:svnMEDION:pnAkoyaE2212TMD99720:*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
# Medion Akoya E2215T MD60198 # Medion Akoya E2215T MD60198
sensor:modalias:acpi:KIOX000A*:dmi:*svnMEDION:pnE2215TMD60198:*
# Medion Akoya E3216 MD60900 # Medion Akoya E3216 MD60900
# Medion Akoya E3221 MD61237 # Medion Akoya E3221 MD61237
# Medion Akoya E2292 MD63390 # Medion Akoya E2292 MD63390

View File

@ -161,10 +161,10 @@
<listitem><para>Takes a directory path as an argument. All paths will be prefixed with the given alternate <listitem><para>Takes a directory path as an argument. All paths will be prefixed with the given alternate
<replaceable>root</replaceable> path, including config search paths.</para> <replaceable>root</replaceable> path, including config search paths.</para>
<para>When this option is used, the libc Name Service Switch (NSS) is bypassed for resolving users <para>Note that this option does not alter how the users and groups specified in the configuration files are
and groups. Instead the files <filename>/etc/passwd</filename> and <filename>/etc/group</filename> resolved. With or without this option, users and groups are always resolved according to the host's user and
inside the alternate root are read directly. This means that users/groups not listed in these files group databases, any such databases stored under the specified root directories are not
will not be resolved, i.e. LDAP NIS and other complex databases are not considered.</para></listitem> consulted.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -2891,8 +2891,6 @@ if conf.get('ENABLE_TMPFILES') == 1
exe = executable( exe = executable(
'systemd-tmpfiles', 'systemd-tmpfiles',
'src/tmpfiles/tmpfiles.c', 'src/tmpfiles/tmpfiles.c',
'src/tmpfiles/offline-passwd.c',
'src/tmpfiles/offline-passwd.h',
include_directories : includes, include_directories : includes,
link_with : [libshared], link_with : [libshared],
dependencies : [libacl], dependencies : [libacl],

View File

@ -254,21 +254,6 @@ bool locale_is_valid(const char *name) {
return true; return true;
} }
int locale_is_installed(const char *name) {
if (!locale_is_valid(name))
return false;
if (STR_IN_SET(name, "C", "POSIX")) /* These ones are always OK */
return true;
_cleanup_(freelocalep) locale_t loc =
newlocale(LC_ALL_MASK, name, 0);
if (loc == (locale_t) 0)
return errno == ENOMEM ? -ENOMEM : false;
return true;
}
void init_gettext(void) { void init_gettext(void) {
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
textdomain(GETTEXT_PACKAGE); textdomain(GETTEXT_PACKAGE);

View File

@ -31,7 +31,6 @@ typedef enum LocaleVariable {
int get_locales(char ***l); int get_locales(char ***l);
bool locale_is_valid(const char *name); bool locale_is_valid(const char *name);
int locale_is_installed(const char *name);
#define _(String) gettext(String) #define _(String) gettext(String)
#define N_(String) String #define N_(String) String

View File

@ -818,7 +818,10 @@ ssize_t send_one_fd_iov_sa(
const struct sockaddr *sa, socklen_t len, const struct sockaddr *sa, socklen_t len,
int flags) { int flags) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {}; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
struct msghdr mh = { struct msghdr mh = {
.msg_name = (struct sockaddr*) sa, .msg_name = (struct sockaddr*) sa,
.msg_namelen = len, .msg_namelen = len,
@ -847,6 +850,8 @@ ssize_t send_one_fd_iov_sa(
cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
mh.msg_controllen = CMSG_SPACE(sizeof(int));
} }
k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags); k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags);
if (k < 0) if (k < 0)
@ -872,7 +877,10 @@ ssize_t receive_one_fd_iov(
int flags, int flags,
int *ret_fd) { int *ret_fd) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
struct msghdr mh = { struct msghdr mh = {
.msg_control = &control, .msg_control = &control,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(control),

View File

@ -166,17 +166,6 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
(ctype*) (_found ? CMSG_DATA(_found) : NULL); \ (ctype*) (_found ? CMSG_DATA(_found) : NULL); \
}) })
/* Resolves to a type that can carry cmsghdr structures. Make sure things are properly aligned, i.e. the type
* itself is placed properly in memory and the size is also aligned to what's appropriate for "cmsghdr"
* structures. */
#define CMSG_BUFFER_TYPE(size) \
union { \
struct cmsghdr cmsghdr; \
uint8_t buf[size]; \
uint8_t align_check[(size) >= CMSG_SPACE(0) && \
(size) == CMSG_ALIGN(size) ? 1 : -1]; \
}
/* /*
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr * Certain hardware address types (e.g Infiniband) do not fit into sll_addr
* (8 bytes) and run over the structure. This macro returns the correct size that * (8 bytes) and run over the structure. This macro returns the correct size that

View File

@ -2349,8 +2349,11 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf)-1, .iov_len = sizeof(buf)-1,
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + union {
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control; struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
} control = {};
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,

View File

@ -884,7 +884,10 @@ static int process_socket(int fd) {
log_debug("Processing coredump received on stdin..."); log_debug("Processing coredump received on stdin...");
for (;;) { for (;;) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
struct msghdr mh = { struct msghdr mh = {
.msg_control = &control, .msg_control = &control,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(control),

View File

@ -205,14 +205,6 @@ static int prompt_loop(const char *text, char **l, unsigned percentage, bool (*i
} }
} }
static bool locale_is_ok(const char *name) {
if (arg_root)
return locale_is_valid(name);
return locale_is_installed(name) > 0;
}
static int prompt_locale(void) { static int prompt_locale(void) {
_cleanup_strv_free_ char **locales = NULL; _cleanup_strv_free_ char **locales = NULL;
int r; int r;
@ -246,7 +238,7 @@ static int prompt_locale(void) {
print_welcome(); print_welcome();
r = prompt_loop("Please enter system locale name or number", r = prompt_loop("Please enter system locale name or number",
locales, 60, locale_is_ok, &arg_locale); locales, 60, locale_is_valid, &arg_locale);
if (r < 0) if (r < 0)
return r; return r;
@ -254,7 +246,7 @@ static int prompt_locale(void) {
return 0; return 0;
r = prompt_loop("Please enter system message locale name or number", r = prompt_loop("Please enter system message locale name or number",
locales, 60, locale_is_ok, &arg_locale_messages); locales, 60, locale_is_valid, &arg_locale_messages);
if (r < 0) if (r < 0)
return r; return r;
@ -799,6 +791,10 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LOCALE: case ARG_LOCALE:
if (!locale_is_valid(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Locale %s is not valid.", optarg);
r = free_and_strdup(&arg_locale, optarg); r = free_and_strdup(&arg_locale, optarg);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -806,6 +802,10 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LOCALE_MESSAGES: case ARG_LOCALE_MESSAGES:
if (!locale_is_valid(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Locale %s is not valid.", optarg);
r = free_and_strdup(&arg_locale_messages, optarg); r = free_and_strdup(&arg_locale_messages, optarg);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -927,14 +927,6 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option"); assert_not_reached("Unhandled option");
} }
/* We check if the specified locale strings are valid down here, so that we can take --root= into
* account when looking for the locale files. */
if (arg_locale && !locale_is_ok(arg_locale))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale);
if (arg_locale_messages && !locale_is_ok(arg_locale_messages))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale_messages);
return 1; return 1;
} }

View File

@ -2806,9 +2806,6 @@ static int parse_argv(int argc, char *argv[]) {
if (!locale_is_valid(optarg)) if (!locale_is_valid(optarg))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale '%s' is not valid.", optarg); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale '%s' is not valid.", optarg);
if (locale_is_installed(optarg) <= 0)
log_warning("Locale '%s' is not installed, accepting anyway.", optarg);
r = json_variant_set_field_string(&arg_identity_extra, "preferredLanguage", optarg); r = json_variant_set_field_string(&arg_identity_extra, "preferredLanguage", optarg);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set preferredLanguage field: %m"); return log_error_errno(r, "Failed to set preferredLanguage field: %m");

View File

@ -946,7 +946,10 @@ static ssize_t read_datagram(int fd, struct ucred *ret_sender, void **ret) {
return -ENOMEM; return -ENOMEM;
if (ret_sender) { if (ret_sender) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
} control;
bool found_ucred = false; bool found_ucred = false;
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct msghdr mh; struct msghdr mh;

View File

@ -550,8 +550,11 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf)-1, .iov_len = sizeof(buf)-1,
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + union {
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control; struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
} control = {};
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,

View File

@ -1268,14 +1268,21 @@ int server_process_datagram(
int *fds = NULL, v = 0; int *fds = NULL, v = 0;
size_t n_fds = 0; size_t n_fds = 0;
/* We use NAME_MAX space for the SELinux label here. The kernel currently enforces no limit, but union {
* according to suggestions from the SELinux people this will change and it will probably be struct cmsghdr cmsghdr;
* identical to NAME_MAX. For now we use that, but this should be updated one day when the final
* limit is known. */ /* We use NAME_MAX space for the SELinux label
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + * here. The kernel currently enforces no
CMSG_SPACE(sizeof(struct timeval)) + * limit, but according to suggestions from
CMSG_SPACE(sizeof(int)) + /* fd */ * the SELinux people this will change and it
CMSG_SPACE(NAME_MAX) /* selinux label */) control; * will probably be identical to NAME_MAX. For
* now we use that, but this should be updated
* one day when the final limit is known. */
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(struct timeval)) +
CMSG_SPACE(sizeof(int)) + /* fd */
CMSG_SPACE(NAME_MAX)]; /* selinux label */
} control = {};
union sockaddr_union sa = {}; union sockaddr_union sa = {};

View File

@ -489,7 +489,7 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
} }
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
StdoutStream *s = userdata; StdoutStream *s = userdata;
struct ucred *ucred; struct ucred *ucred;
struct iovec iovec; struct iovec iovec;
@ -500,8 +500,8 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = buf,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(buf),
}; };
assert(s); assert(s);

View File

@ -39,7 +39,10 @@ static void forward_syslog_iovec(
.msg_iovlen = n_iovec, .msg_iovlen = n_iovec,
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
} control;
const char *j; const char *j;
int r; int r;

View File

@ -147,9 +147,11 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
triple_timestamp *timestamp) { triple_timestamp *timestamp) {
union {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */ struct cmsghdr cmsghdr;
CMSG_SPACE(sizeof(struct timeval))) control; uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
CMSG_SPACE(sizeof(struct timeval))];
} control = {};
struct iovec iov = {}; struct iovec iov = {};
union sockaddr_union sa = {}; union sockaddr_union sa = {};
struct msghdr msg = { struct msghdr msg = {

View File

@ -1899,13 +1899,13 @@ static int client_receive_message_raw(
sd_dhcp_client *client = userdata; sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPPacket *packet = NULL; _cleanup_free_ DHCPPacket *packet = NULL;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct tpacket_auxdata))) control; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
struct iovec iov = {}; struct iovec iov = {};
struct msghdr msg = { struct msghdr msg = {
.msg_iov = &iov, .msg_iov = &iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = cmsgbuf,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(cmsgbuf),
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
bool checksum = true; bool checksum = true;

View File

@ -267,14 +267,14 @@ static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
.iov_base = message, .iov_base = message,
.iov_len = len, .iov_len = len,
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {}; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))] = {};
struct msghdr msg = { struct msghdr msg = {
.msg_name = &dest, .msg_name = &dest,
.msg_namelen = sizeof(dest.in), .msg_namelen = sizeof(dest.in),
.msg_iov = &iov, .msg_iov = &iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = cmsgbuf,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(cmsgbuf),
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct in_pktinfo *pktinfo; struct in_pktinfo *pktinfo;
@ -970,14 +970,14 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
static int server_receive_message(sd_event_source *s, int fd, static int server_receive_message(sd_event_source *s, int fd,
uint32_t revents, void *userdata) { uint32_t revents, void *userdata) {
_cleanup_free_ DHCPMessage *message = NULL; _cleanup_free_ DHCPMessage *message = NULL;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct in_pktinfo))];
sd_dhcp_server *server = userdata; sd_dhcp_server *server = userdata;
struct iovec iov = {}; struct iovec iov = {};
struct msghdr msg = { struct msghdr msg = {
.msg_iov = &iov, .msg_iov = &iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = cmsgbuf,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(cmsgbuf),
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
ssize_t buflen, len; ssize_t buflen, len;

View File

@ -518,7 +518,10 @@ static int bus_socket_read_auth(sd_bus *b) {
ssize_t k; ssize_t k;
int r; int r;
void *p; void *p;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
} control;
bool handle_cmsg = false; bool handle_cmsg = false;
assert(b); assert(b);
@ -1034,10 +1037,8 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) {
if (m->n_fds > 0 && *idx == 0) { if (m->n_fds > 0 && *idx == 0) {
struct cmsghdr *control; struct cmsghdr *control;
mh.msg_controllen = CMSG_SPACE(sizeof(int) * m->n_fds); mh.msg_control = control = alloca(CMSG_SPACE(sizeof(int) * m->n_fds));
mh.msg_control = alloca0(mh.msg_controllen); mh.msg_controllen = control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
control = CMSG_FIRSTHDR(&mh);
control->cmsg_len = CMSG_LEN(sizeof(int) * m->n_fds);
control->cmsg_level = SOL_SOCKET; control->cmsg_level = SOL_SOCKET;
control->cmsg_type = SCM_RIGHTS; control->cmsg_type = SCM_RIGHTS;
memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds); memcpy(CMSG_DATA(control), m->fds, sizeof(int) * m->n_fds);
@ -1166,7 +1167,10 @@ int bus_socket_read_message(sd_bus *bus) {
size_t need; size_t need;
int r; int r;
void *b; void *b;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
} control;
bool handle_cmsg = false; bool handle_cmsg = false;
assert(bus); assert(bus);

View File

@ -361,13 +361,13 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
.iov_base = &buf, .iov_base = &buf,
.iov_len = sizeof(buf) .iov_len = sizeof(buf)
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
union sockaddr_union snl; union sockaddr_union snl;
struct msghdr smsg = { struct msghdr smsg = {
.msg_iov = &iov, .msg_iov = &iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = cred_msg,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(cred_msg),
.msg_name = &snl, .msg_name = &snl,
.msg_namelen = sizeof(snl), .msg_namelen = sizeof(snl),
}; };

View File

@ -258,57 +258,18 @@ static int property_get_xkb(
return -EINVAL; return -EINVAL;
} }
static int process_locale_list_item(
const char *assignment,
char *new_locale[static _VARIABLE_LC_MAX],
sd_bus_error *error) {
assert(assignment);
assert(new_locale);
for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) {
const char *name, *e;
assert_se(name = locale_variable_to_string(p));
e = startswith(assignment, name);
if (!e)
continue;
if (*e != '=')
continue;
e++;
if (!locale_is_valid(e))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s is not valid, refusing.", e);
if (locale_is_installed(e) <= 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale %s not installed, refusing.", e);
if (new_locale[p])
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale variable %s set twice, refusing.", name);
new_locale[p] = strdup(e);
if (!new_locale[p])
return -ENOMEM;
return 0;
}
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Locale assignment %s not valid, refusing.", assignment);
}
static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) { static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *error) {
_cleanup_(locale_variables_freep) char *new_locale[_VARIABLE_LC_MAX] = {}; _cleanup_(locale_variables_freep) char *new_locale[_VARIABLE_LC_MAX] = {};
_cleanup_strv_free_ char **settings = NULL, **l = NULL; _cleanup_strv_free_ char **settings = NULL, **l = NULL;
Context *c = userdata; Context *c = userdata;
bool modified = false; bool modified = false;
int interactive, r; int interactive, p, r;
char **i; char **i;
assert(m); assert(m);
assert(c); assert(c);
r = sd_bus_message_read_strv(m, &l); r = bus_message_read_strv_extend(m, &l);
if (r < 0) if (r < 0)
return r; return r;
@ -317,13 +278,11 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
return r; return r;
/* If single locale without variable name is provided, then we assume it is LANG=. */ /* If single locale without variable name is provided, then we assume it is LANG=. */
if (strv_length(l) == 1 && !strchr(l[0], '=')) { if (strv_length(l) == 1 && !strchr(*l, '=')) {
if (!locale_is_valid(l[0])) if (!locale_is_valid(*l))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid locale specification: %s", l[0]); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
if (locale_is_installed(l[0]) <= 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified locale is not installed: %s", l[0]);
new_locale[VARIABLE_LANG] = strdup(l[0]); new_locale[VARIABLE_LANG] = strdup(*l);
if (!new_locale[VARIABLE_LANG]) if (!new_locale[VARIABLE_LANG])
return -ENOMEM; return -ENOMEM;
@ -332,9 +291,31 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
/* Check whether a variable is valid */ /* Check whether a variable is valid */
STRV_FOREACH(i, l) { STRV_FOREACH(i, l) {
r = process_locale_list_item(*i, new_locale, error); bool valid = false;
if (r < 0)
return r; for (p = 0; p < _VARIABLE_LC_MAX; p++) {
size_t k;
const char *name;
name = locale_variable_to_string(p);
assert(name);
k = strlen(name);
if (startswith(*i, name) &&
(*i)[k] == '=' &&
locale_is_valid((*i) + k + 1)) {
valid = true;
new_locale[p] = strdup((*i) + k + 1);
if (!new_locale[p])
return -ENOMEM;
break;
}
}
if (!valid)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Locale data.");
} }
/* If LANG was specified, but not LANGUAGE, check if we should /* If LANG was specified, but not LANGUAGE, check if we should
@ -357,7 +338,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
} }
/* Merge with the current settings */ /* Merge with the current settings */
for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) for (p = 0; p < _VARIABLE_LC_MAX; p++)
if (!isempty(c->locale[p]) && isempty(new_locale[p])) { if (!isempty(c->locale[p]) && isempty(new_locale[p])) {
new_locale[p] = strdup(c->locale[p]); new_locale[p] = strdup(c->locale[p]);
if (!new_locale[p]) if (!new_locale[p])
@ -366,7 +347,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
locale_simplify(new_locale); locale_simplify(new_locale);
for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) for (p = 0; p < _VARIABLE_LC_MAX; p++)
if (!streq_ptr(c->locale[p], new_locale[p])) { if (!streq_ptr(c->locale[p], new_locale[p])) {
modified = true; modified = true;
break; break;
@ -391,7 +372,7 @@ static int method_set_locale(sd_bus_message *m, void *userdata, sd_bus_error *er
if (r == 0) if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
for (LocaleVariable p = 0; p < _VARIABLE_LC_MAX; p++) for (p = 0; p < _VARIABLE_LC_MAX; p++)
free_and_replace(c->locale[p], new_locale[p]); free_and_replace(c->locale[p], new_locale[p]);
r = locale_write_data(c, &settings); r = locale_write_data(c, &settings);

View File

@ -580,9 +580,9 @@ static int apply_user_record_settings(pam_handle_t *handle, UserRecord *ur, bool
if (pam_getenv(handle, "LANG")) { if (pam_getenv(handle, "LANG")) {
if (debug) if (debug)
pam_syslog(handle, LOG_DEBUG, "PAM environment variable $LANG already set, not changing based on user record."); pam_syslog(handle, LOG_DEBUG, "PAM environment variable $LANG already set, not changing based on user record.");
} else if (locale_is_installed(ur->preferred_language) <= 0) { } else if (!locale_is_valid(ur->preferred_language)) {
if (debug) if (debug)
pam_syslog(handle, LOG_DEBUG, "Preferred language specified in user record is not valid or not installed, not setting $LANG."); pam_syslog(handle, LOG_DEBUG, "Preferred language specified in user record is not valid locally, not setting $LANG.");
} else { } else {
_cleanup_free_ char *joined = NULL; _cleanup_free_ char *joined = NULL;

View File

@ -3687,8 +3687,11 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
.iov_base = buf, .iov_base = buf,
.iov_len = sizeof(buf)-1, .iov_len = sizeof(buf)-1,
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + union {
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control; struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
} control = {};
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,

View File

@ -127,7 +127,10 @@ static int send_item(
const char *name, const char *name,
int fd) { int fd) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {}; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
struct iovec iovec; struct iovec iovec;
struct msghdr mh = { struct msghdr mh = {
.msg_control = &control, .msg_control = &control,
@ -152,6 +155,7 @@ static int send_item(
cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_len = CMSG_LEN(sizeof(int));
memcpy(CMSG_DATA(cmsg), &data_fd, sizeof(int)); memcpy(CMSG_DATA(cmsg), &data_fd, sizeof(int));
mh.msg_controllen = CMSG_SPACE(sizeof(int));
iovec = IOVEC_MAKE_STRING(name); iovec = IOVEC_MAKE_STRING(name);
if (sendmsg(socket_fd, &mh, MSG_NOSIGNAL) < 0) if (sendmsg(socket_fd, &mh, MSG_NOSIGNAL) < 0)
@ -165,7 +169,10 @@ static int recv_item(
char **ret_name, char **ret_name,
int *ret_fd) { int *ret_fd) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
char buffer[PATH_MAX+2]; char buffer[PATH_MAX+2];
struct iovec iov = IOVEC_INIT(buffer, sizeof(buffer)-1); struct iovec iov = IOVEC_INIT(buffer, sizeof(buffer)-1);
struct msghdr mh = { struct msghdr mh = {

View File

@ -87,8 +87,11 @@ static int dns_stream_complete(DnsStream *s, int error) {
} }
static int dns_stream_identify(DnsStream *s) { static int dns_stream_identify(DnsStream *s) {
CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo)) union {
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */) control; struct cmsghdr header; /* For alignment */
uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */];
} control;
struct msghdr mh = {}; struct msghdr mh = {};
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
socklen_t sl; socklen_t sl;

View File

@ -741,9 +741,12 @@ Manager *manager_free(Manager *m) {
int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo)) union {
+ CMSG_SPACE(int) /* ttl/hoplimit */ struct cmsghdr header; /* For alignment */
+ EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */) control; uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
+ CMSG_SPACE(int) /* ttl/hoplimit */
+ EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
} control;
union sockaddr_union sa; union sockaddr_union sa;
struct iovec iov; struct iovec iov;
struct msghdr mh = { struct msghdr mh = {
@ -927,8 +930,10 @@ static int manager_ipv4_send(
uint16_t port, uint16_t port,
const struct in_addr *source, const struct in_addr *source,
DnsPacket *p) { DnsPacket *p) {
union {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {}; struct cmsghdr header; /* For alignment */
uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
} control = {};
union sockaddr_union sa; union sockaddr_union sa;
struct iovec iov; struct iovec iov;
struct msghdr mh = { struct msghdr mh = {
@ -957,10 +962,10 @@ static int manager_ipv4_send(
struct in_pktinfo *pi; struct in_pktinfo *pi;
mh.msg_control = &control; mh.msg_control = &control;
mh.msg_controllen = sizeof(control); mh.msg_controllen = CMSG_LEN(sizeof(struct in_pktinfo));
cmsg = CMSG_FIRSTHDR(&mh); cmsg = CMSG_FIRSTHDR(&mh);
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); cmsg->cmsg_len = mh.msg_controllen;
cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_PKTINFO; cmsg->cmsg_type = IP_PKTINFO;
@ -983,7 +988,10 @@ static int manager_ipv6_send(
const struct in6_addr *source, const struct in6_addr *source,
DnsPacket *p) { DnsPacket *p) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in6_pktinfo))) control = {}; union {
struct cmsghdr header; /* For alignment */
uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
} control = {};
union sockaddr_union sa; union sockaddr_union sa;
struct iovec iov; struct iovec iov;
struct msghdr mh = { struct msghdr mh = {
@ -1013,10 +1021,10 @@ static int manager_ipv6_send(
struct in6_pktinfo *pi; struct in6_pktinfo *pi;
mh.msg_control = &control; mh.msg_control = &control;
mh.msg_controllen = sizeof(control); mh.msg_controllen = CMSG_LEN(sizeof(struct in6_pktinfo));
cmsg = CMSG_FIRSTHDR(&mh); cmsg = CMSG_FIRSTHDR(&mh);
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); cmsg->cmsg_len = mh.msg_controllen;
cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_PKTINFO; cmsg->cmsg_type = IPV6_PKTINFO;

View File

@ -859,10 +859,13 @@ int ask_password_agent(
pollfd[FD_INOTIFY].events = POLLIN; pollfd[FD_INOTIFY].events = POLLIN;
for (;;) { for (;;) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
char passphrase[LINE_MAX+1]; char passphrase[LINE_MAX+1];
struct iovec iovec; struct iovec iovec;
struct ucred *ucred; struct ucred *ucred;
union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
} control;
ssize_t n; ssize_t n;
int k; int k;
usec_t t; usec_t t;
@ -914,6 +917,7 @@ int ask_password_agent(
iovec = IOVEC_MAKE(passphrase, sizeof(passphrase)); iovec = IOVEC_MAKE(passphrase, sizeof(passphrase));
zero(control);
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,

View File

@ -356,30 +356,12 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
char buf[FORMAT_BYTES_MAX]; char buf[FORMAT_BYTES_MAX];
if (hr->disk_size != UINT64_MAX) { if (hr->disk_size != UINT64_MAX) {
const char *color_on, *color_off;
unsigned permille; unsigned permille;
permille = (unsigned) ((hr->disk_free * 1000U) / hr->disk_size); /* Round down! */ permille = (unsigned) ((hr->disk_free * 1000U) / hr->disk_size); /* Round down! */
printf(" Disk Free: %s (= %u.%01u%%)\n",
/* Color the output red or yellow if we are below 10% resp. 25% free. Because 10% and
* 25% can be a lot of space still, let's additionally make some absolute
* restrictions: 1G and 2G */
if (permille <= 100U &&
hr->disk_free < 1024U*1024U*1024U /* 1G */) {
color_on = ansi_highlight_red();
color_off = ansi_normal();
} else if (permille <= 250U &&
hr->disk_free < 2U*1024U*1024U*1024U /* 2G */) {
color_on = ansi_highlight_yellow();
color_off = ansi_normal();
} else
color_on = color_off = "";
printf(" Disk Free: %s%s (= %u.%01u%%)%s\n",
color_on,
format_bytes(buf, sizeof(buf), hr->disk_free), format_bytes(buf, sizeof(buf), hr->disk_free),
permille / 10, permille % 10, permille / 10, permille % 10);
color_off);
} else } else
printf(" Disk Free: %s\n", format_bytes(buf, sizeof(buf), hr->disk_free)); printf(" Disk Free: %s\n", format_bytes(buf, sizeof(buf), hr->disk_free));
} }

View File

@ -1814,7 +1814,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_root); r = parse_path_argument_and_warn(optarg, true, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;

View File

@ -36,28 +36,6 @@ static void test_locale_is_valid(void) {
assert_se(!locale_is_valid("\x01gar\x02 bage\x03")); assert_se(!locale_is_valid("\x01gar\x02 bage\x03"));
} }
static void test_locale_is_installed(void) {
log_info("/* %s */", __func__);
/* Always available */
assert_se(locale_is_installed("POSIX") > 0);
assert_se(locale_is_installed("C") > 0);
/* Might, or might not be installed. */
assert_se(locale_is_installed("en_EN.utf8") >= 0);
assert_se(locale_is_installed("fr_FR.utf8") >= 0);
assert_se(locale_is_installed("fr_FR@euro") >= 0);
assert_se(locale_is_installed("fi_FI") >= 0);
/* Definitely not valid */
assert_se(locale_is_installed("") == 0);
assert_se(locale_is_installed("/usr/bin/foo") == 0);
assert_se(locale_is_installed("\x01gar\x02 bage\x03") == 0);
/* Definitely not installed */
assert_se(locale_is_installed("zz_ZZ") == 0);
}
static void test_keymaps(void) { static void test_keymaps(void) {
_cleanup_strv_free_ char **kmaps = NULL; _cleanup_strv_free_ char **kmaps = NULL;
char **p; char **p;
@ -120,7 +98,6 @@ static void dump_special_glyphs(void) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_get_locales(); test_get_locales();
test_locale_is_valid(); test_locale_is_valid();
test_locale_is_installed();
test_keymaps(); test_keymaps();
dump_special_glyphs(); dump_special_glyphs();

View File

@ -407,7 +407,10 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
.iov_base = &ntpmsg, .iov_base = &ntpmsg,
.iov_len = sizeof(ntpmsg), .iov_len = sizeof(ntpmsg),
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timeval))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
} control;
union sockaddr_union server_addr; union sockaddr_union server_addr;
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iov, .msg_iov = &iov,

View File

@ -1,122 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "fd-util.h"
#include "offline-passwd.h"
#include "path-util.h"
#include "user-util.h"
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(uid_gid_hash_ops, char, string_hash_func, string_compare_func, free);
int name_to_uid_offline(
const char *root,
const char *user,
uid_t *ret_uid,
Hashmap **cache) {
void *found;
int r;
assert(user);
assert(ret_uid);
assert(cache);
if (!*cache) {
_cleanup_(hashmap_freep) Hashmap *uid_by_name = NULL;
_cleanup_fclose_ FILE *f = NULL;
struct passwd *pw;
const char *passwd_path;
passwd_path = prefix_roota(root, "/etc/passwd");
f = fopen(passwd_path, "re");
if (!f)
return errno == ENOENT ? -ESRCH : -errno;
uid_by_name = hashmap_new(&uid_gid_hash_ops);
if (!uid_by_name)
return -ENOMEM;
while ((r = fgetpwent_sane(f, &pw)) > 0) {
_cleanup_free_ char *n = NULL;
n = strdup(pw->pw_name);
if (!n)
return -ENOMEM;
r = hashmap_put(uid_by_name, n, UID_TO_PTR(pw->pw_uid));
if (r == -EEXIST) {
log_warning_errno(r, "Duplicate entry in %s for %s: %m", passwd_path, pw->pw_name);
continue;
}
if (r < 0)
return r;
TAKE_PTR(n);
}
*cache = TAKE_PTR(uid_by_name);
}
found = hashmap_get(*cache, user);
if (!found)
return -ESRCH;
*ret_uid = PTR_TO_UID(found);
return 0;
}
int name_to_gid_offline(
const char *root,
const char *group,
gid_t *ret_gid,
Hashmap **cache) {
void *found;
int r;
assert(group);
assert(ret_gid);
assert(cache);
if (!*cache) {
_cleanup_(hashmap_freep) Hashmap *gid_by_name = NULL;
_cleanup_fclose_ FILE *f = NULL;
struct group *gr;
const char *group_path;
group_path = prefix_roota(root, "/etc/group");
f = fopen(group_path, "re");
if (!f)
return errno == ENOENT ? -ESRCH : -errno;
gid_by_name = hashmap_new(&uid_gid_hash_ops);
if (!gid_by_name)
return -ENOMEM;
while ((r = fgetgrent_sane(f, &gr)) > 0) {
_cleanup_free_ char *n = NULL;
n = strdup(gr->gr_name);
if (!n)
return -ENOMEM;
r = hashmap_put(gid_by_name, n, GID_TO_PTR(gr->gr_gid));
if (r == -EEXIST) {
log_warning_errno(r, "Duplicate entry in %s for %s: %m", group_path, gr->gr_name);
continue;
}
if (r < 0)
return r;
TAKE_PTR(n);
}
*cache = TAKE_PTR(gid_by_name);
}
found = hashmap_get(*cache, group);
if (!found)
return -ESRCH;
*ret_gid = PTR_TO_GID(found);
return 0;
}

View File

@ -1,9 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <sys/types.h>
#include "hashmap.h"
int name_to_uid_offline(const char *root, const char *user, uid_t *ret_uid, Hashmap **cache);
int name_to_gid_offline(const char *root, const char *group, gid_t *ret_gid, Hashmap **cache);

View File

@ -39,7 +39,6 @@
#include "main-func.h" #include "main-func.h"
#include "mkdir.h" #include "mkdir.h"
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "offline-passwd.h"
#include "pager.h" #include "pager.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-lookup.h" #include "path-lookup.h"
@ -2489,63 +2488,7 @@ static int patch_var_run(const char *fname, unsigned line, char **path) {
return 0; return 0;
} }
static int find_uid(const char *user, uid_t *ret_uid, Hashmap **cache) { static int parse_line(const char *fname, unsigned line, const char *buffer, bool *invalid_config) {
int r;
assert(user);
assert(ret_uid);
/* First: parse as numeric UID string */
r = parse_uid(user, ret_uid);
if (r >= 0)
return r;
/* Second: pass to NSS if we are running "online" */
if (!arg_root)
return get_user_creds(&user, ret_uid, NULL, NULL, NULL, 0);
/* Third, synthesize "root" unconditionally */
if (streq(user, "root")) {
*ret_uid = 0;
return 0;
}
/* Fourth: use fgetpwent() to read /etc/passwd directly, if we are "offline" */
return name_to_uid_offline(arg_root, user, ret_uid, cache);
}
static int find_gid(const char *group, gid_t *ret_gid, Hashmap **cache) {
int r;
assert(group);
assert(ret_gid);
/* First: parse as numeric GID string */
r = parse_gid(group, ret_gid);
if (r >= 0)
return r;
/* Second: pass to NSS if we are running "online" */
if (!arg_root)
return get_group_creds(&group, ret_gid, 0);
/* Third, synthesize "root" unconditionally */
if (streq(group, "root")) {
*ret_gid = 0;
return 0;
}
/* Fourth: use fgetgrent() to read /etc/group directly, if we are "offline" */
return name_to_gid_offline(arg_root, group, ret_gid, cache);
}
static int parse_line(
const char *fname,
unsigned line,
const char *buffer,
bool *invalid_config,
Hashmap **uid_cache,
Hashmap **gid_cache) {
_cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL; _cleanup_free_ char *action = NULL, *mode = NULL, *user = NULL, *group = NULL, *age = NULL, *path = NULL;
_cleanup_(item_free_contents) Item i = {}; _cleanup_(item_free_contents) Item i = {};
@ -2667,7 +2610,7 @@ static int parse_line(
case COPY_FILES: case COPY_FILES:
if (!i.argument) { if (!i.argument) {
i.argument = path_join("/usr/share/factory", i.path); i.argument = path_join(arg_root, "/usr/share/factory", i.path);
if (!i.argument) if (!i.argument)
return log_oom(); return log_oom();
@ -2675,9 +2618,7 @@ static int parse_line(
*invalid_config = true; *invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, SYNTHETIC_ERRNO(EBADMSG), "Source path '%s' is not absolute.", i.argument); return log_syntax(NULL, LOG_ERR, fname, line, SYNTHETIC_ERRNO(EBADMSG), "Source path '%s' is not absolute.", i.argument);
} } else if (arg_root) {
if (!empty_or_root(arg_root)) {
char *p; char *p;
p = path_join(arg_root, i.argument); p = path_join(arg_root, i.argument);
@ -2768,7 +2709,7 @@ static int parse_line(
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to substitute specifiers in argument: %m"); return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to substitute specifiers in argument: %m");
} }
if (!empty_or_root(arg_root)) { if (arg_root) {
char *p; char *p;
p = path_join(arg_root, i.path); p = path_join(arg_root, i.path);
@ -2778,7 +2719,9 @@ static int parse_line(
} }
if (!empty_or_dash(user)) { if (!empty_or_dash(user)) {
r = find_uid(user, &i.uid, uid_cache); const char *u = user;
r = get_user_creds(&u, &i.uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
if (r < 0) { if (r < 0) {
*invalid_config = true; *invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve user '%s': %m", user); return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve user '%s': %m", user);
@ -2788,7 +2731,9 @@ static int parse_line(
} }
if (!empty_or_dash(group)) { if (!empty_or_dash(group)) {
r = find_gid(group, &i.gid, gid_cache); const char *g = group;
r = get_group_creds(&g, &i.gid, USER_CREDS_ALLOW_MISSING);
if (r < 0) { if (r < 0) {
*invalid_config = true; *invalid_config = true;
return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s'.", group); return log_syntax(NULL, LOG_ERR, fname, line, r, "Failed to resolve group '%s'.", group);
@ -2996,7 +2941,7 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_ROOT: case ARG_ROOT:
r = parse_path_argument_and_warn(optarg, /* suppress_root= */ false, &arg_root); r = parse_path_argument_and_warn(optarg, true, &arg_root);
if (r < 0) if (r < 0)
return r; return r;
break; break;
@ -3037,7 +2982,6 @@ static int parse_argv(int argc, char *argv[]) {
} }
static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) { static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) {
_cleanup_(hashmap_freep) Hashmap *uid_cache = NULL, *gid_cache = NULL;
_cleanup_fclose_ FILE *_f = NULL; _cleanup_fclose_ FILE *_f = NULL;
Iterator iterator; Iterator iterator;
unsigned v = 0; unsigned v = 0;
@ -3083,7 +3027,7 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe
if (IN_SET(*l, 0, '#')) if (IN_SET(*l, 0, '#'))
continue; continue;
k = parse_line(fn, v, l, &invalid_line, &uid_cache, &gid_cache); k = parse_line(fn, v, l, &invalid_line);
if (k < 0) { if (k < 0) {
if (invalid_line) if (invalid_line)
/* Allow reporting with a special code if the caller requested this */ /* Allow reporting with a special code if the caller requested this */

View File

@ -189,12 +189,12 @@ static int udev_ctrl_connection_event_handler(sd_event_source *s, int fd, uint32
_cleanup_(udev_ctrl_disconnect_and_listen_againp) struct udev_ctrl *uctrl = NULL; _cleanup_(udev_ctrl_disconnect_and_listen_againp) struct udev_ctrl *uctrl = NULL;
struct udev_ctrl_msg_wire msg_wire; struct udev_ctrl_msg_wire msg_wire;
struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(struct udev_ctrl_msg_wire)); struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(struct udev_ctrl_msg_wire));
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
struct msghdr smsg = { struct msghdr smsg = {
.msg_iov = &iov, .msg_iov = &iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_control = &control, .msg_control = cred_msg,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(cred_msg),
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct ucred *cred; struct ucred *cred;

View File

@ -906,7 +906,10 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
.iov_base = &msg, .iov_base = &msg,
.iov_len = sizeof(msg), .iov_len = sizeof(msg),
}; };
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control; union {
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
} control = {};
struct msghdr msghdr = { struct msghdr msghdr = {
.msg_iov = &iovec, .msg_iov = &iovec,
.msg_iovlen = 1, .msg_iovlen = 1,