X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=src%2Fcore%2Fsocket.c;h=324ec1e34bd03f0333f33f9aa7260e1fd09f54e8;hb=01e10de3c2b9c2944bd86b12fab83d1164d0b64a;hp=f3f09cac4326133e8af4c9ecb3a8a4132fd3a0e7;hpb=aea54018a5e66a41318afb6c6be745b6aef48d9e;p=elogind.git diff --git a/src/core/socket.c b/src/core/socket.c index f3f09cac4..324ec1e34 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -28,7 +28,9 @@ #include #include #include +#ifdef HAVE_ATTR_XATTR_H #include +#endif #include "unit.h" #include "socket.h" @@ -136,12 +138,6 @@ static void socket_done(Unit *u) { free(s->smack_ip_in); free(s->smack_ip_out); - free(s->socket_user); - s->socket_user = NULL; - - free(s->socket_group); - s->socket_group = NULL; - unit_unwatch_timer(u, &s->timer_watch); } @@ -455,16 +451,6 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { prefix, yes_no(s->pass_sec), prefix, strna(s->tcp_congestion)); - if (s->socket_user) - fprintf(f, - "SocketUser: %s\n", - s->socket_user); - - if (s->socket_group) - fprintf(f, - "SocketGroup: %s\n", - s->socket_group); - if (s->control_pid > 0) fprintf(f, "%sControl PID: %lu\n", @@ -708,9 +694,6 @@ static void socket_close_fds(Socket *s) { } static void socket_apply_socket_options(Socket *s, int fd) { - uid_t uid = 0; - gid_t gid = 0; - assert(s); assert(fd >= 0); @@ -787,6 +770,7 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_warning("TCP_CONGESTION failed: %m"); +#ifdef HAVE_ATTR_XATTR_H if (s->smack_ip_in) if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0) log_error("fsetxattr(\"security.SMACK64IPIN\"): %m"); @@ -794,21 +778,7 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (s->smack_ip_out) if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0) log_error("fsetxattr(\"security.SMACK64IPOUT\"): %m"); - - if (s->socket_user && - get_user_creds((const char **)&s->socket_user, &uid, - NULL, NULL, NULL) < 0) { - log_warning("failed to lookup user: %s", s->socket_user); - } - - if (s->socket_group && - get_group_creds((const char **)&s->socket_group, &gid) < 0) { - log_warning("failed to lookup group: %s", s->socket_group); - } - - if ((uid != 0 || gid != 0) && fchown(fd, uid, gid) < 0) { - log_warning("failed to change ownership of socket"); - } +#endif } static void socket_apply_fifo_options(Socket *s, int fd) { @@ -819,24 +789,22 @@ static void socket_apply_fifo_options(Socket *s, int fd) { if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0) log_warning("F_SETPIPE_SZ: %m"); +#ifdef HAVE_ATTR_XATTR_H if (s->smack) if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0) log_error("fsetxattr(\"security.SMACK64\"): %m"); +#endif } static int fifo_address_create( const char *path, mode_t directory_mode, mode_t socket_mode, - const char *socket_user, - const char *socket_group, int *_fd) { int fd = -1, r = 0; struct stat st; mode_t old_mask; - uid_t uid = 0; - gid_t gid = 0; assert(path); assert(_fd); @@ -861,8 +829,7 @@ static int fifo_address_create( goto fail; } - fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW); - if (fd < 0) { + if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) { r = -errno; goto fail; } @@ -874,35 +841,15 @@ static int fifo_address_create( goto fail; } - if (socket_user && - get_user_creds(&socket_user, &uid, NULL, NULL, NULL) < 0) { - r = -errno; - log_error("failed to lookup user: %s", socket_user); - goto fail; - } - - if (socket_group && - get_group_creds(&socket_group, &gid) < 0) { - r = -errno; - log_error("failed to lookup group: %s", socket_group); - goto fail; - } - if (!S_ISFIFO(st.st_mode) || (st.st_mode & 0777) != (socket_mode & ~old_mask) || - st.st_uid != uid || - st.st_gid != gid) { + st.st_uid != getuid() || + st.st_gid != getgid()) { r = -EEXIST; goto fail; } - if ((uid != 0 || gid != 0) && fchown(fd, uid, gid) < 0) { - r = -errno; - log_error("failed to changed ownership of FIFO: %s", path); - goto fail; - } - *_fd = fd; return 0; @@ -1072,8 +1019,6 @@ static int socket_open_fds(Socket *s) { p->path, s->directory_mode, s->socket_mode, - s->socket_user, - s->socket_group, &p->fd)) < 0) goto rollback; @@ -1201,10 +1146,12 @@ static int socket_coldplug(Unit *u) { if (s->control_pid <= 0) return -EBADMSG; - if ((r = unit_watch_pid(UNIT(s), s->control_pid)) < 0) + r = unit_watch_pid(UNIT(s), s->control_pid); + if (r < 0) return r; - if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) return r; } @@ -1236,10 +1183,12 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); - if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) goto fail; - if (!(argv = unit_full_printf_strv(UNIT(s), c->argv))) { + argv = unit_full_printf_strv(UNIT(s), c->argv); + if (!argv) { r = -ENOMEM; goto fail; } @@ -1361,7 +1310,8 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { } if (wait_for_exit) { - if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch); + if (r < 0) goto fail; socket_set_state(s, state); @@ -1534,7 +1484,7 @@ static void socket_enter_running(Socket *s, int cfd) { Service *service; if (s->n_connections >= s->max_connections) { - log_warning("Too many incoming connections (%u)", s->n_connections); + log_warning("%s: Too many incoming connections (%u)", UNIT(s)->id, s->n_connections); close_nointr_nofail(cfd); return; } @@ -1603,7 +1553,7 @@ static void socket_enter_running(Socket *s, int cfd) { return; fail: - log_warning("%s failed to queue socket startup job: %s", UNIT(s)->id, bus_error(&error, r)); + log_warning("%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s", UNIT(s)->id, cfd >= 0 ? "template" : "non-template", bus_error(&error, r)); socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); if (cfd >= 0) @@ -1752,7 +1702,8 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { if (p->type == SOCKET_SOCKET) { char *t; - if ((r = socket_address_print(&p->address, &t)) < 0) + r = socket_address_print(&p->address, &t); + if (r < 0) return r; if (socket_address_family(&p->address) == AF_NETLINK) @@ -1762,6 +1713,8 @@ static int socket_serialize(Unit *u, FILE *f, FDSet *fds) { free(t); } else if (p->type == SOCKET_SPECIAL) unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path); + else if (p->type == SOCKET_MQUEUE) + unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path); else { assert(p->type == SOCKET_FIFO); unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path); @@ -1782,7 +1735,8 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, if (streq(key, "state")) { SocketState state; - if ((state = socket_state_from_string(value)) < 0) + state = socket_state_from_string(value); + if (state < 0) log_debug("Failed to parse state value %s", value); else s->deserialized_state = state; @@ -1858,6 +1812,26 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, } } + } else if (streq(key, "mqueue")) { + int fd, skip = 0; + SocketPort *p; + + if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd)) + log_debug("Failed to parse mqueue value %s", value); + else { + + LIST_FOREACH(port, p, s->ports) + if (p->type == SOCKET_MQUEUE && + streq_ptr(p->path, value+skip)) + break; + + if (p) { + if (p->fd >= 0) + close_nointr_nofail(p->fd); + p->fd = fdset_remove(fds, fd); + } + } + } else if (streq(key, "socket")) { int fd, type, skip = 0; SocketPort *p; @@ -1902,6 +1876,34 @@ static int socket_deserialize_item(Unit *u, const char *key, const char *value, return 0; } +static int socket_distribute_fds(Unit *u, FDSet *fds) { + Socket *s = SOCKET(u); + SocketPort *p; + + assert(u); + + LIST_FOREACH(port, p, s->ports) { + Iterator i; + int fd; + + if (p->type != SOCKET_SOCKET) + continue; + + if (p->fd >= 0) + continue; + + FDSET_FOREACH(fd, fds, i) { + if (socket_address_matches_fd(&p->address, fd)) { + p->fd = fdset_remove(fds, fd); + s->deserialized_state = SOCKET_LISTENING; + break; + } + } + } + + return 0; +} + static UnitActiveState socket_active_state(Unit *u) { assert(u); @@ -2314,6 +2316,7 @@ const UnitVTable socket_vtable = { .serialize = socket_serialize, .deserialize_item = socket_deserialize_item, + .distribute_fds = socket_distribute_fds, .active_state = socket_active_state, .sub_state_to_string = socket_sub_state_to_string,