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