xref: /openbsd/sbin/pflogd/privsep_fdpass.c (revision 0296baa5)
1*0296baa5Scanacar /*	$OpenBSD: privsep_fdpass.c,v 1.1 2003/10/22 18:51:55 canacar Exp $	*/
2*0296baa5Scanacar 
3*0296baa5Scanacar /*
4*0296baa5Scanacar  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
5*0296baa5Scanacar  * All rights reserved.
6*0296baa5Scanacar  *
7*0296baa5Scanacar  * Copyright (c) 2002 Matthieu Herrb
8*0296baa5Scanacar  * All rights reserved.
9*0296baa5Scanacar  *
10*0296baa5Scanacar  * Redistribution and use in source and binary forms, with or without
11*0296baa5Scanacar  * modification, are permitted provided that the following conditions
12*0296baa5Scanacar  * are met:
13*0296baa5Scanacar  *
14*0296baa5Scanacar  *    - Redistributions of source code must retain the above copyright
15*0296baa5Scanacar  *      notice, this list of conditions and the following disclaimer.
16*0296baa5Scanacar  *    - Redistributions in binary form must reproduce the above
17*0296baa5Scanacar  *      copyright notice, this list of conditions and the following
18*0296baa5Scanacar  *      disclaimer in the documentation and/or other materials provided
19*0296baa5Scanacar  *      with the distribution.
20*0296baa5Scanacar  *
21*0296baa5Scanacar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*0296baa5Scanacar  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*0296baa5Scanacar  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24*0296baa5Scanacar  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25*0296baa5Scanacar  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26*0296baa5Scanacar  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27*0296baa5Scanacar  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28*0296baa5Scanacar  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29*0296baa5Scanacar  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*0296baa5Scanacar  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31*0296baa5Scanacar  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32*0296baa5Scanacar  * POSSIBILITY OF SUCH DAMAGE.
33*0296baa5Scanacar  */
34*0296baa5Scanacar #include <sys/param.h>
35*0296baa5Scanacar #include <sys/uio.h>
36*0296baa5Scanacar #include <sys/types.h>
37*0296baa5Scanacar #include <sys/socket.h>
38*0296baa5Scanacar #include <sys/stat.h>
39*0296baa5Scanacar #include <err.h>
40*0296baa5Scanacar #include <errno.h>
41*0296baa5Scanacar #include <fcntl.h>
42*0296baa5Scanacar #include <signal.h>
43*0296baa5Scanacar #include <stdio.h>
44*0296baa5Scanacar #include <stdlib.h>
45*0296baa5Scanacar #include <string.h>
46*0296baa5Scanacar #include <unistd.h>
47*0296baa5Scanacar #include "pflogd.h"
48*0296baa5Scanacar 
49*0296baa5Scanacar void
50*0296baa5Scanacar send_fd(int sock, int fd)
51*0296baa5Scanacar {
52*0296baa5Scanacar 	struct msghdr msg;
53*0296baa5Scanacar 	char tmp[CMSG_SPACE(sizeof(int))];
54*0296baa5Scanacar 	struct cmsghdr *cmsg;
55*0296baa5Scanacar 	struct iovec vec;
56*0296baa5Scanacar 	int result = 0;
57*0296baa5Scanacar 	ssize_t n;
58*0296baa5Scanacar 
59*0296baa5Scanacar 	memset(&msg, 0, sizeof(msg));
60*0296baa5Scanacar 
61*0296baa5Scanacar 	if (fd >= 0) {
62*0296baa5Scanacar 		msg.msg_control = (caddr_t)tmp;
63*0296baa5Scanacar 		msg.msg_controllen = CMSG_LEN(sizeof(int));
64*0296baa5Scanacar 		cmsg = CMSG_FIRSTHDR(&msg);
65*0296baa5Scanacar 		cmsg->cmsg_len = CMSG_LEN(sizeof(int));
66*0296baa5Scanacar 		cmsg->cmsg_level = SOL_SOCKET;
67*0296baa5Scanacar 		cmsg->cmsg_type = SCM_RIGHTS;
68*0296baa5Scanacar 		*(int *)CMSG_DATA(cmsg) = fd;
69*0296baa5Scanacar 	} else {
70*0296baa5Scanacar 		result = errno;
71*0296baa5Scanacar 	}
72*0296baa5Scanacar 
73*0296baa5Scanacar 	vec.iov_base = &result;
74*0296baa5Scanacar 	vec.iov_len = sizeof(int);
75*0296baa5Scanacar 	msg.msg_iov = &vec;
76*0296baa5Scanacar 	msg.msg_iovlen = 1;
77*0296baa5Scanacar 
78*0296baa5Scanacar 	if ((n = sendmsg(sock, &msg, 0)) == -1)
79*0296baa5Scanacar 		warn("%s: sendmsg(%d)", __func__, sock);
80*0296baa5Scanacar 	if (n != sizeof(int))
81*0296baa5Scanacar 		warnx("%s: sendmsg: expected sent 1 got %ld",
82*0296baa5Scanacar 		    __func__, (long)n);
83*0296baa5Scanacar }
84*0296baa5Scanacar 
85*0296baa5Scanacar int
86*0296baa5Scanacar receive_fd(int sock)
87*0296baa5Scanacar {
88*0296baa5Scanacar 	struct msghdr msg;
89*0296baa5Scanacar 	char tmp[CMSG_SPACE(sizeof(int))];
90*0296baa5Scanacar 	struct cmsghdr *cmsg;
91*0296baa5Scanacar 	struct iovec vec;
92*0296baa5Scanacar 	ssize_t n;
93*0296baa5Scanacar 	int result;
94*0296baa5Scanacar 	int fd;
95*0296baa5Scanacar 
96*0296baa5Scanacar 	memset(&msg, 0, sizeof(msg));
97*0296baa5Scanacar 	vec.iov_base = &result;
98*0296baa5Scanacar 	vec.iov_len = sizeof(int);
99*0296baa5Scanacar 	msg.msg_iov = &vec;
100*0296baa5Scanacar 	msg.msg_iovlen = 1;
101*0296baa5Scanacar 	msg.msg_control = tmp;
102*0296baa5Scanacar 	msg.msg_controllen = sizeof(tmp);
103*0296baa5Scanacar 
104*0296baa5Scanacar 	if ((n = recvmsg(sock, &msg, 0)) == -1)
105*0296baa5Scanacar 		warn("%s: recvmsg", __func__);
106*0296baa5Scanacar 	if (n != sizeof(int))
107*0296baa5Scanacar 		warnx("%s: recvmsg: expected received 1 got %ld",
108*0296baa5Scanacar 		    __func__, (long)n);
109*0296baa5Scanacar 	if (result == 0) {
110*0296baa5Scanacar 		cmsg = CMSG_FIRSTHDR(&msg);
111*0296baa5Scanacar 		if (cmsg->cmsg_type != SCM_RIGHTS)
112*0296baa5Scanacar 			warnx("%s: expected type %d got %d", __func__,
113*0296baa5Scanacar 			    SCM_RIGHTS, cmsg->cmsg_type);
114*0296baa5Scanacar 		fd = (*(int *)CMSG_DATA(cmsg));
115*0296baa5Scanacar 		return fd;
116*0296baa5Scanacar 	} else {
117*0296baa5Scanacar 		errno = result;
118*0296baa5Scanacar 		return -1;
119*0296baa5Scanacar 	}
120*0296baa5Scanacar }
121