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