1*55c3341cSjca /* $OpenBSD: monitor_fdpass.c,v 1.7 2016/02/29 20:22:36 jca Exp $ */
2b96c0bc5Shenning
3b96c0bc5Shenning /*
4b96c0bc5Shenning * Copyright (c) 2002 Matthieu Herrb
5b96c0bc5Shenning * Copyright (c) 2001 Niels Provos <provos@citi.umich.edu>
6b96c0bc5Shenning *
7b96c0bc5Shenning * Permission to use, copy, modify, and distribute this software for any
8b96c0bc5Shenning * purpose with or without fee is hereby granted, provided that the above
9b96c0bc5Shenning * copyright notice and this permission notice appear in all copies.
10b96c0bc5Shenning *
11b96c0bc5Shenning * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12b96c0bc5Shenning * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13b96c0bc5Shenning * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14b96c0bc5Shenning * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15b96c0bc5Shenning * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16b96c0bc5Shenning * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17b96c0bc5Shenning * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18b96c0bc5Shenning */
19b96c0bc5Shenning
20b96c0bc5Shenning #include <sys/types.h>
21b96c0bc5Shenning #include <sys/socket.h>
22b96c0bc5Shenning #include <sys/uio.h>
23b96c0bc5Shenning
24b96c0bc5Shenning #include <errno.h>
25b96c0bc5Shenning #include <fcntl.h>
26b96c0bc5Shenning #include <string.h>
27b96c0bc5Shenning #include <syslog.h>
28b96c0bc5Shenning #include <unistd.h>
2998071651Sderaadt #include "monitor.h"
30b96c0bc5Shenning
31b96c0bc5Shenning void
send_fd(int sock,int fd)32b96c0bc5Shenning send_fd(int sock, int fd)
33b96c0bc5Shenning {
34b96c0bc5Shenning struct msghdr msg;
350827ab61Sderaadt union {
360827ab61Sderaadt struct cmsghdr hdr;
370827ab61Sderaadt char buf[CMSG_SPACE(sizeof(int))];
380827ab61Sderaadt } cmsgbuf;
39b96c0bc5Shenning struct cmsghdr *cmsg;
40b96c0bc5Shenning struct iovec vec;
41b96c0bc5Shenning int result = 0;
42b96c0bc5Shenning ssize_t n;
43b96c0bc5Shenning
44b96c0bc5Shenning memset(&msg, 0, sizeof(msg));
45b96c0bc5Shenning
46b96c0bc5Shenning if (fd >= 0) {
470827ab61Sderaadt msg.msg_control = (caddr_t)&cmsgbuf.buf;
48da15c7b9Sderaadt msg.msg_controllen = sizeof(cmsgbuf.buf);
49b96c0bc5Shenning cmsg = CMSG_FIRSTHDR(&msg);
50b96c0bc5Shenning cmsg->cmsg_len = CMSG_LEN(sizeof(int));
51b96c0bc5Shenning cmsg->cmsg_level = SOL_SOCKET;
52b96c0bc5Shenning cmsg->cmsg_type = SCM_RIGHTS;
53b96c0bc5Shenning *(int *)CMSG_DATA(cmsg) = fd;
54b96c0bc5Shenning } else
55b96c0bc5Shenning result = errno;
56b96c0bc5Shenning
57b96c0bc5Shenning vec.iov_base = &result;
58b96c0bc5Shenning vec.iov_len = sizeof(int);
59b96c0bc5Shenning msg.msg_iov = &vec;
60b96c0bc5Shenning msg.msg_iovlen = 1;
61b96c0bc5Shenning
62b96c0bc5Shenning if ((n = sendmsg(sock, &msg, 0)) == -1)
63b96c0bc5Shenning syslog(LOG_WARNING, "send_fd: sendmsg(%d): %m", sock);
64b96c0bc5Shenning if (n != sizeof(int))
65*55c3341cSjca syslog(LOG_WARNING, "send_fd: sendmsg: expected sent 1 got %zd",
66*55c3341cSjca n);
67b96c0bc5Shenning }
68b96c0bc5Shenning
69b96c0bc5Shenning int
recv_fd(int sock)70b96c0bc5Shenning recv_fd(int sock)
71b96c0bc5Shenning {
72b96c0bc5Shenning struct msghdr msg;
730827ab61Sderaadt union {
740827ab61Sderaadt struct cmsghdr hdr;
750827ab61Sderaadt char buf[CMSG_SPACE(sizeof(int))];
760827ab61Sderaadt } cmsgbuf;
77b96c0bc5Shenning struct cmsghdr *cmsg;
78b96c0bc5Shenning struct iovec vec;
79b96c0bc5Shenning ssize_t n;
80b96c0bc5Shenning int result;
81b96c0bc5Shenning int fd;
82b96c0bc5Shenning
83b96c0bc5Shenning memset(&msg, 0, sizeof(msg));
84b96c0bc5Shenning vec.iov_base = &result;
85b96c0bc5Shenning vec.iov_len = sizeof(int);
86b96c0bc5Shenning msg.msg_iov = &vec;
87b96c0bc5Shenning msg.msg_iovlen = 1;
880827ab61Sderaadt msg.msg_control = &cmsgbuf.buf;
89da15c7b9Sderaadt msg.msg_controllen = sizeof(cmsgbuf.buf);
90b96c0bc5Shenning
91a592c95fSderaadt if ((n = recvmsg(sock, &msg, 0)) == -1) {
92b96c0bc5Shenning syslog(LOG_WARNING, "recv_fd: recvmsg(%d): %m", sock);
93a592c95fSderaadt return -1;
94a592c95fSderaadt }
95b96c0bc5Shenning if (n != sizeof(int))
96b96c0bc5Shenning syslog(LOG_WARNING,
97*55c3341cSjca "recv_fd: recvmsg: expected received 1 got %zd", n);
98b96c0bc5Shenning if (result == 0) {
99b96c0bc5Shenning cmsg = CMSG_FIRSTHDR(&msg);
100b96c0bc5Shenning if (cmsg == NULL) {
101b96c0bc5Shenning syslog(LOG_WARNING, "recv_fd: no message header");
102b96c0bc5Shenning return (-1);
103b96c0bc5Shenning }
104b96c0bc5Shenning if (cmsg->cmsg_type != SCM_RIGHTS)
105b96c0bc5Shenning syslog(LOG_WARNING, "recv_fd: expected type %d got %d",
106b96c0bc5Shenning SCM_RIGHTS, cmsg->cmsg_type);
107b96c0bc5Shenning fd = (*(int *)CMSG_DATA(cmsg));
108b96c0bc5Shenning return (fd);
109b96c0bc5Shenning } else {
110b96c0bc5Shenning errno = result;
111b96c0bc5Shenning return (-1);
112b96c0bc5Shenning }
113b96c0bc5Shenning }
114