summaryrefslogtreecommitdiff
path: root/src/core/dynamic-user.c
diff options
context:
space:
mode:
authorFilipe Brandenburger <filbranden@google.com>2018-07-24 18:46:01 -0700
committerFilipe Brandenburger <filbranden@google.com>2018-08-02 09:25:04 -0700
commitd34673ecb825aa9ecf6958b0caab792f5061c56a (patch)
treef3d4e3a2700e37048cda9358043148d1477ee4e3 /src/core/dynamic-user.c
parent27d4866ad8dcbe95cfc4d59357c65c559737c1ae (diff)
downloadsystemd-d34673ecb825aa9ecf6958b0caab792f5061c56a.tar.gz
socket-util: Introduce send_one_fd_iov() and receive_one_fd_iov()
These take a struct iovec to send data together with the passed FD. The receive function returns the FD through an output argument. In case data is received, but no FD is passed, the receive function will set the output argument to -1 explicitly. Update code in dynamic-user to use the new helpers.
Diffstat (limited to 'src/core/dynamic-user.c')
-rw-r--r--src/core/dynamic-user.c57
1 files changed, 4 insertions, 53 deletions
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c
index f380db553e..5e20783102 100644
--- a/src/core/dynamic-user.c
+++ b/src/core/dynamic-user.c
@@ -312,20 +312,8 @@ static int pick_uid(char **suggested_paths, const char *name, uid_t *ret_uid) {
static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) {
uid_t uid = UID_INVALID;
struct iovec iov = IOVEC_INIT(&uid, sizeof(uid));
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
- struct cmsghdr *cmsg;
-
+ int lock_fd;
ssize_t k;
- int lock_fd = -1;
assert(d);
assert(ret_uid);
@@ -334,15 +322,9 @@ static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) {
/* Read the UID and lock fd that is stored in the storage AF_UNIX socket. This should be called with the lock
* on the socket taken. */
- k = recvmsg(d->storage_socket[0], &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
+ k = receive_one_fd_iov(d->storage_socket[0], &iov, 1, MSG_DONTWAIT, &lock_fd);
if (k < 0)
- return -errno;
-
- cmsg = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int)));
- if (cmsg)
- lock_fd = *(int*) CMSG_DATA(cmsg);
- else
- cmsg_close_all(&mh); /* just in case... */
+ return (int) k;
*ret_uid = uid;
*ret_lock_fd = lock_fd;
@@ -352,42 +334,11 @@ static int dynamic_user_pop(DynamicUser *d, uid_t *ret_uid, int *ret_lock_fd) {
static int dynamic_user_push(DynamicUser *d, uid_t uid, int lock_fd) {
struct iovec iov = IOVEC_INIT(&uid, sizeof(uid));
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- .msg_iov = &iov,
- .msg_iovlen = 1,
- };
- ssize_t k;
assert(d);
/* Store the UID and lock_fd in the storage socket. This should be called with the socket pair lock taken. */
-
- if (lock_fd >= 0) {
- struct cmsghdr *cmsg;
-
- 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), &lock_fd, sizeof(int));
-
- mh.msg_controllen = CMSG_SPACE(sizeof(int));
- } else {
- mh.msg_control = NULL;
- mh.msg_controllen = 0;
- }
-
- k = sendmsg(d->storage_socket[1], &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
- if (k < 0)
- return -errno;
-
- return 0;
+ return send_one_fd_iov(d->storage_socket[1], lock_fd, &iov, 1, MSG_DONTWAIT);
}
static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) {