1223637Sbz/* $OpenBSD: privsep_fdpass.c,v 1.5 2008/03/24 16:11:08 deraadt Exp $ */ 2130614Smlaier 3130614Smlaier/* 4130614Smlaier * Copyright 2001 Niels Provos <provos@citi.umich.edu> 5130614Smlaier * All rights reserved. 6130614Smlaier * 7130614Smlaier * Copyright (c) 2002 Matthieu Herrb 8130614Smlaier * All rights reserved. 9130614Smlaier * 10130614Smlaier * Redistribution and use in source and binary forms, with or without 11130614Smlaier * modification, are permitted provided that the following conditions 12130614Smlaier * are met: 13130614Smlaier * 14130614Smlaier * - Redistributions of source code must retain the above copyright 15130614Smlaier * notice, this list of conditions and the following disclaimer. 16130614Smlaier * - Redistributions in binary form must reproduce the above 17130614Smlaier * copyright notice, this list of conditions and the following 18130614Smlaier * disclaimer in the documentation and/or other materials provided 19130614Smlaier * with the distribution. 20130614Smlaier * 21130614Smlaier * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22130614Smlaier * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23130614Smlaier * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24130614Smlaier * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25130614Smlaier * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26130614Smlaier * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27130614Smlaier * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28130614Smlaier * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29130614Smlaier * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30130614Smlaier * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31130614Smlaier * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32130614Smlaier * POSSIBILITY OF SUCH DAMAGE. 33130614Smlaier */ 34130614Smlaier#include <sys/param.h> 35130614Smlaier#include <sys/uio.h> 36130614Smlaier#include <sys/types.h> 37130614Smlaier#include <sys/socket.h> 38130614Smlaier#include <sys/stat.h> 39130614Smlaier#include <err.h> 40130614Smlaier#include <errno.h> 41130614Smlaier#include <fcntl.h> 42130614Smlaier#include <signal.h> 43130614Smlaier#include <stdio.h> 44130614Smlaier#include <stdlib.h> 45130614Smlaier#include <string.h> 46130614Smlaier#include <unistd.h> 47130614Smlaier#include "pflogd.h" 48130614Smlaier 49130614Smlaiervoid 50130614Smlaiersend_fd(int sock, int fd) 51130614Smlaier{ 52130614Smlaier struct msghdr msg; 53223637Sbz union { 54223637Sbz struct cmsghdr hdr; 55223637Sbz char buf[CMSG_SPACE(sizeof(int))]; 56223637Sbz } cmsgbuf; 57130614Smlaier struct cmsghdr *cmsg; 58130614Smlaier struct iovec vec; 59130614Smlaier int result = 0; 60130614Smlaier ssize_t n; 61130614Smlaier 62130614Smlaier memset(&msg, 0, sizeof(msg)); 63130614Smlaier 64130614Smlaier if (fd >= 0) { 65223637Sbz msg.msg_control = (caddr_t)&cmsgbuf.buf; 66223637Sbz msg.msg_controllen = sizeof(cmsgbuf.buf); 67130614Smlaier cmsg = CMSG_FIRSTHDR(&msg); 68130614Smlaier cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 69130614Smlaier cmsg->cmsg_level = SOL_SOCKET; 70130614Smlaier cmsg->cmsg_type = SCM_RIGHTS; 71130614Smlaier *(int *)CMSG_DATA(cmsg) = fd; 72130614Smlaier } else { 73130614Smlaier result = errno; 74130614Smlaier } 75130614Smlaier 76130614Smlaier vec.iov_base = &result; 77130614Smlaier vec.iov_len = sizeof(int); 78130614Smlaier msg.msg_iov = &vec; 79130614Smlaier msg.msg_iovlen = 1; 80130614Smlaier 81130614Smlaier if ((n = sendmsg(sock, &msg, 0)) == -1) 82130614Smlaier warn("%s: sendmsg(%d)", __func__, sock); 83130614Smlaier if (n != sizeof(int)) 84130614Smlaier warnx("%s: sendmsg: expected sent 1 got %ld", 85130614Smlaier __func__, (long)n); 86130614Smlaier} 87130614Smlaier 88130614Smlaierint 89130614Smlaierreceive_fd(int sock) 90130614Smlaier{ 91130614Smlaier struct msghdr msg; 92223637Sbz union { 93223637Sbz struct cmsghdr hdr; 94223637Sbz char buf[CMSG_SPACE(sizeof(int))]; 95223637Sbz } cmsgbuf; 96130614Smlaier struct cmsghdr *cmsg; 97130614Smlaier struct iovec vec; 98130614Smlaier ssize_t n; 99130614Smlaier int result; 100130614Smlaier int fd; 101130614Smlaier 102130614Smlaier memset(&msg, 0, sizeof(msg)); 103130614Smlaier vec.iov_base = &result; 104130614Smlaier vec.iov_len = sizeof(int); 105130614Smlaier msg.msg_iov = &vec; 106130614Smlaier msg.msg_iovlen = 1; 107223637Sbz msg.msg_control = &cmsgbuf.buf; 108223637Sbz msg.msg_controllen = sizeof(cmsgbuf.buf); 109130614Smlaier 110130614Smlaier if ((n = recvmsg(sock, &msg, 0)) == -1) 111130614Smlaier warn("%s: recvmsg", __func__); 112130614Smlaier if (n != sizeof(int)) 113130614Smlaier warnx("%s: recvmsg: expected received 1 got %ld", 114130614Smlaier __func__, (long)n); 115130614Smlaier if (result == 0) { 116130614Smlaier cmsg = CMSG_FIRSTHDR(&msg); 117145837Smlaier if (cmsg == NULL) { 118145837Smlaier warnx("%s: no message header", __func__); 119145837Smlaier return -1; 120145837Smlaier } 121130614Smlaier if (cmsg->cmsg_type != SCM_RIGHTS) 122130614Smlaier warnx("%s: expected type %d got %d", __func__, 123130614Smlaier SCM_RIGHTS, cmsg->cmsg_type); 124130614Smlaier fd = (*(int *)CMSG_DATA(cmsg)); 125130614Smlaier return fd; 126130614Smlaier } else { 127130614Smlaier errno = result; 128130614Smlaier return -1; 129130614Smlaier } 130130614Smlaier} 131