1 /* $OpenBSD: pass.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
2 /*
3 * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/socket.h>
19 #include <sys/wait.h>
20
21 #include <err.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "header.h"
26
27 void
fdops(int fdpre,int fdpost)28 fdops(int fdpre, int fdpost)
29 {
30 struct msghdr msg;
31 struct iovec iov[1];
32 char buf[1];
33 struct cmsghdr *cmsg;
34 union {
35 struct cmsghdr hdr;
36 unsigned char buf[CMSG_SPACE(sizeof(int))];
37 } cmsgbuf;
38 pid_t child;
39 int pair[2], status;
40
41 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) == -1)
42 err(1, "socketpair");
43
44 memset(&msg, 0, sizeof(msg));
45 msg.msg_control = &cmsgbuf.buf;
46 msg.msg_controllen = sizeof(cmsgbuf.buf);
47
48 if ((child = fork()) == -1)
49 err(1, "fork");
50
51 if (child == 0) {
52
53 /* child process */
54
55 cmsg = CMSG_FIRSTHDR(&msg);
56 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
57 cmsg->cmsg_level = SOL_SOCKET;
58 cmsg->cmsg_type = SCM_RIGHTS;
59
60 *(int *)CMSG_DATA(cmsg) = fdpre;
61 if (sendmsg(pair[1], &msg, 0) == -1)
62 err(1, "sendmsg pre");
63
64 cmsg = CMSG_FIRSTHDR(&msg);
65 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
66 cmsg->cmsg_level = SOL_SOCKET;
67 cmsg->cmsg_type = SCM_RIGHTS;
68
69 *(int *)CMSG_DATA(cmsg) = fdpost;
70 if (sendmsg(pair[1], &msg, 0) == -1)
71 err(1, "sendmsg post");
72
73 _exit(0);
74 }
75
76 /* parent process */
77
78 msg.msg_iov = iov;
79 msg.msg_iovlen = 1;
80 iov[0].iov_base = buf;
81 iov[0].iov_len = sizeof(buf);
82
83 if (recvmsg(pair[0], &msg, 0) == -1)
84 err(1, "recvmsg pre");
85 if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
86 errx(1, "trunk pre");
87
88 if (recvmsg(pair[0], &msg, 0) == -1)
89 err(1, "recvmsg post");
90 if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
91 errx(1, "trunk post");
92
93 if (waitpid(child, &status, 0) == -1)
94 err(1, "waitpid");
95 if (status != 0)
96 errx(1, "child failed: %d", status);
97 }
98