socket: allow configuration of socket/directory mode

This commit is contained in:
Lennart Poettering 2010-02-12 02:02:14 +01:00
parent a9f5d45466
commit b5a0699f0b
7 changed files with 75 additions and 14 deletions

2
fixme
View File

@ -72,3 +72,5 @@
- distccd
- teach dbus to talk to systemd when autospawning services
- unix sockets chown()/chgrp()

View File

@ -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"),

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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