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