mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 12:13:33 +08:00
socket: allow configuration of socket/directory mode
This commit is contained in:
parent
a9f5d45466
commit
b5a0699f0b
2
fixme
2
fixme
@ -72,3 +72,5 @@
|
||||
- distccd
|
||||
|
||||
- teach dbus to talk to systemd when autospawning services
|
||||
|
||||
- unix sockets chown()/chgrp()
|
||||
|
@ -285,7 +285,7 @@ static int config_parse_oom_adjust(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config_parse_umask(
|
||||
static int config_parse_mode(
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
@ -306,12 +306,12 @@ static int config_parse_umask(
|
||||
errno = 0;
|
||||
l = strtol(rvalue, &x, 8);
|
||||
if (!x || *x || errno) {
|
||||
log_error("[%s:%u] Failed to parse umask value: %s", filename, line, rvalue);
|
||||
log_error("[%s:%u] Failed to parse mode value: %s", filename, line, rvalue);
|
||||
return errno ? -errno : -EINVAL;
|
||||
}
|
||||
|
||||
if (l < 0000 || l > 0777) {
|
||||
log_error("[%s:%u] umask value out of range: %s", filename, line, rvalue);
|
||||
if (l < 0000 || l > 07777) {
|
||||
log_error("[%s:%u] mode value out of range: %s", filename, line, rvalue);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
@ -1045,7 +1045,7 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "CPUSchedulingPriority", config_parse_cpu_sched_prio, &(context), section }, \
|
||||
{ "CPUSchedulingResetOnFork", config_parse_bool, &(context).cpu_sched_reset_on_fork, section }, \
|
||||
{ "CPUAffinity", config_parse_cpu_affinity, &(context), section }, \
|
||||
{ "UMask", config_parse_umask, &(context).umask, section }, \
|
||||
{ "UMask", config_parse_mode, &(context).umask, section }, \
|
||||
{ "Environment", config_parse_strv, &(context).environment, section }, \
|
||||
{ "Output", config_parse_output, &(context).output, section }, \
|
||||
{ "Input", config_parse_input, &(context).input, section }, \
|
||||
@ -1112,6 +1112,8 @@ static int load_from_path(Unit *u, const char *path) {
|
||||
{ "ExecStartPost", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_START_POST, "Socket" },
|
||||
{ "ExecStopPre", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_STOP_PRE, "Socket" },
|
||||
{ "ExecStopPost", config_parse_exec, u->socket.exec_command+SOCKET_EXEC_STOP_POST, "Socket" },
|
||||
{ "DirectoryMode", config_parse_mode, &u->socket.directory_mode, "Socket" },
|
||||
{ "SocketMode", config_parse_mode, &u->socket.socket_mode, "Socket" },
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
|
||||
|
||||
EXEC_CONTEXT_CONFIG_ITEMS(u->automount.exec_context, "Automount"),
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
@ -298,7 +300,15 @@ int socket_address_print(const SocketAddress *a, char **p) {
|
||||
}
|
||||
}
|
||||
|
||||
int socket_address_listen(const SocketAddress *a, int backlog, SocketAddressBindIPv6Only only, const char *bind_to_device, int *ret) {
|
||||
int socket_address_listen(
|
||||
const SocketAddress *a,
|
||||
int backlog,
|
||||
SocketAddressBindIPv6Only only,
|
||||
const char *bind_to_device,
|
||||
mode_t directory_mode,
|
||||
mode_t socket_mode,
|
||||
int *ret) {
|
||||
|
||||
int r, fd, one;
|
||||
assert(a);
|
||||
assert(ret);
|
||||
@ -324,7 +334,31 @@ int socket_address_listen(const SocketAddress *a, int backlog, SocketAddressBind
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0)
|
||||
goto fail;
|
||||
|
||||
if (bind(fd, &a->sockaddr.sa, a->size) < 0)
|
||||
if (socket_address_family(a) == AF_UNIX && a->sockaddr.un.sun_path[0] != 0) {
|
||||
mode_t old_mask;
|
||||
|
||||
/* Create parents */
|
||||
mkdir_parents(a->sockaddr.un.sun_path, directory_mode);
|
||||
|
||||
/* Enforce the right access mode for the socket*/
|
||||
old_mask = umask(~ socket_mode);
|
||||
|
||||
/* Include the original umask in our mask */
|
||||
umask(~socket_mode | old_mask);
|
||||
|
||||
r = bind(fd, &a->sockaddr.sa, a->size);
|
||||
|
||||
if (r < 0 && errno == EADDRINUSE) {
|
||||
/* Unlink and try again */
|
||||
unlink(a->sockaddr.un.sun_path);
|
||||
r = bind(fd, &a->sockaddr.sa, a->size);
|
||||
}
|
||||
|
||||
umask(old_mask);
|
||||
} else
|
||||
r = bind(fd, &a->sockaddr.sa, a->size);
|
||||
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
||||
if (a->type == SOCK_STREAM)
|
||||
|
@ -58,6 +58,14 @@ typedef enum SocketAddressBindIPv6Only {
|
||||
int socket_address_parse(SocketAddress *a, const char *s);
|
||||
int socket_address_print(const SocketAddress *a, char **p);
|
||||
int socket_address_verify(const SocketAddress *a);
|
||||
int socket_address_listen(const SocketAddress *a, int backlog, SocketAddressBindIPv6Only only, const char *bind_to_device, int *ret);
|
||||
|
||||
int socket_address_listen(
|
||||
const SocketAddress *a,
|
||||
int backlog,
|
||||
SocketAddressBindIPv6Only only,
|
||||
const char *bind_to_device,
|
||||
mode_t directory_mode,
|
||||
mode_t socket_mode,
|
||||
int *ret);
|
||||
|
||||
#endif
|
||||
|
19
socket.c
19
socket.c
@ -105,6 +105,8 @@ static int socket_init(Unit *u) {
|
||||
s->bind_ipv6_only = false;
|
||||
s->backlog = SOMAXCONN;
|
||||
s->timeout_usec = DEFAULT_TIMEOUT_USEC;
|
||||
s->directory_mode = 0755;
|
||||
s->socket_mode = 0666;
|
||||
exec_context_init(&s->exec_context);
|
||||
|
||||
if ((r = unit_load_fragment_and_dropin(u)) <= 0) {
|
||||
@ -171,10 +173,14 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
fprintf(f,
|
||||
"%sSocket State: %s\n"
|
||||
"%sBindIPv6Only: %s\n"
|
||||
"%sBacklog: %u\n",
|
||||
"%sBacklog: %u\n"
|
||||
"%sSocketMode: %04o\n"
|
||||
"%sDirectoryMode: %04o\n",
|
||||
prefix, state_string_table[s->state],
|
||||
prefix, yes_no(s->bind_ipv6_only),
|
||||
prefix, s->backlog);
|
||||
prefix, s->backlog,
|
||||
prefix, s->socket_mode,
|
||||
prefix, s->directory_mode);
|
||||
|
||||
if (s->bind_to_device)
|
||||
fprintf(f,
|
||||
@ -243,7 +249,14 @@ static int socket_open_fds(Socket *s) {
|
||||
|
||||
if (p->type == SOCKET_SOCKET) {
|
||||
|
||||
if ((r = socket_address_listen(&p->address, s->backlog, s->bind_ipv6_only, s->bind_to_device, &p->fd)) < 0)
|
||||
if ((r = socket_address_listen(
|
||||
&p->address,
|
||||
s->backlog,
|
||||
s->bind_ipv6_only,
|
||||
s->bind_to_device,
|
||||
s->directory_mode,
|
||||
s->socket_mode,
|
||||
&p->fd)) < 0)
|
||||
goto rollback;
|
||||
|
||||
} else {
|
||||
|
2
socket.h
2
socket.h
@ -93,6 +93,8 @@ struct Socket {
|
||||
pid_t control_pid;
|
||||
|
||||
char *bind_to_device;
|
||||
mode_t directory_mode;
|
||||
mode_t socket_mode;
|
||||
|
||||
bool failure;
|
||||
Watch timer_watch;
|
||||
|
@ -2,7 +2,7 @@
|
||||
Description=Syslog Socket
|
||||
|
||||
[Socket]
|
||||
ListenDatagram=/tmp/systemd-syslog-socket
|
||||
ListenDatagram=/tmp/foobar/waldo/systemd-syslog-socket
|
||||
ListenStream=eth0:3456
|
||||
ExecStartPre=/bin/rm -f /tmp/systemd-syslog-socket
|
||||
ExecStopPost=/bin/rm -f /tmp/systemd-syslog-socket
|
||||
DirectoryMode=0700
|
||||
SocketMode=0400
|
||||
|
Loading…
Reference in New Issue
Block a user