1*ee42e03cSdjm /* $OpenBSD: privsep_fdpass.c,v 1.2 2004/08/13 02:51:48 djm Exp $ */ 20296baa5Scanacar 30296baa5Scanacar /* 40296baa5Scanacar * Copyright 2001 Niels Provos <provos@citi.umich.edu> 50296baa5Scanacar * All rights reserved. 60296baa5Scanacar * 70296baa5Scanacar * Copyright (c) 2002 Matthieu Herrb 80296baa5Scanacar * All rights reserved. 90296baa5Scanacar * 100296baa5Scanacar * Redistribution and use in source and binary forms, with or without 110296baa5Scanacar * modification, are permitted provided that the following conditions 120296baa5Scanacar * are met: 130296baa5Scanacar * 140296baa5Scanacar * - Redistributions of source code must retain the above copyright 150296baa5Scanacar * notice, this list of conditions and the following disclaimer. 160296baa5Scanacar * - Redistributions in binary form must reproduce the above 170296baa5Scanacar * copyright notice, this list of conditions and the following 180296baa5Scanacar * disclaimer in the documentation and/or other materials provided 190296baa5Scanacar * with the distribution. 200296baa5Scanacar * 210296baa5Scanacar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 220296baa5Scanacar * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 230296baa5Scanacar * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 240296baa5Scanacar * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 250296baa5Scanacar * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 260296baa5Scanacar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 270296baa5Scanacar * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 280296baa5Scanacar * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 290296baa5Scanacar * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 300296baa5Scanacar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 310296baa5Scanacar * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 320296baa5Scanacar * POSSIBILITY OF SUCH DAMAGE. 330296baa5Scanacar */ 340296baa5Scanacar #include <sys/param.h> 350296baa5Scanacar #include <sys/uio.h> 360296baa5Scanacar #include <sys/types.h> 370296baa5Scanacar #include <sys/socket.h> 380296baa5Scanacar #include <sys/stat.h> 390296baa5Scanacar #include <err.h> 400296baa5Scanacar #include <errno.h> 410296baa5Scanacar #include <fcntl.h> 420296baa5Scanacar #include <signal.h> 430296baa5Scanacar #include <stdio.h> 440296baa5Scanacar #include <stdlib.h> 450296baa5Scanacar #include <string.h> 460296baa5Scanacar #include <unistd.h> 470296baa5Scanacar #include "pflogd.h" 480296baa5Scanacar 490296baa5Scanacar void 500296baa5Scanacar send_fd(int sock, int fd) 510296baa5Scanacar { 520296baa5Scanacar struct msghdr msg; 530296baa5Scanacar char tmp[CMSG_SPACE(sizeof(int))]; 540296baa5Scanacar struct cmsghdr *cmsg; 550296baa5Scanacar struct iovec vec; 560296baa5Scanacar int result = 0; 570296baa5Scanacar ssize_t n; 580296baa5Scanacar 590296baa5Scanacar memset(&msg, 0, sizeof(msg)); 600296baa5Scanacar 610296baa5Scanacar if (fd >= 0) { 620296baa5Scanacar msg.msg_control = (caddr_t)tmp; 630296baa5Scanacar msg.msg_controllen = CMSG_LEN(sizeof(int)); 640296baa5Scanacar cmsg = CMSG_FIRSTHDR(&msg); 650296baa5Scanacar cmsg->cmsg_len = CMSG_LEN(sizeof(int)); 660296baa5Scanacar cmsg->cmsg_level = SOL_SOCKET; 670296baa5Scanacar cmsg->cmsg_type = SCM_RIGHTS; 680296baa5Scanacar *(int *)CMSG_DATA(cmsg) = fd; 690296baa5Scanacar } else { 700296baa5Scanacar result = errno; 710296baa5Scanacar } 720296baa5Scanacar 730296baa5Scanacar vec.iov_base = &result; 740296baa5Scanacar vec.iov_len = sizeof(int); 750296baa5Scanacar msg.msg_iov = &vec; 760296baa5Scanacar msg.msg_iovlen = 1; 770296baa5Scanacar 780296baa5Scanacar if ((n = sendmsg(sock, &msg, 0)) == -1) 790296baa5Scanacar warn("%s: sendmsg(%d)", __func__, sock); 800296baa5Scanacar if (n != sizeof(int)) 810296baa5Scanacar warnx("%s: sendmsg: expected sent 1 got %ld", 820296baa5Scanacar __func__, (long)n); 830296baa5Scanacar } 840296baa5Scanacar 850296baa5Scanacar int 860296baa5Scanacar receive_fd(int sock) 870296baa5Scanacar { 880296baa5Scanacar struct msghdr msg; 890296baa5Scanacar char tmp[CMSG_SPACE(sizeof(int))]; 900296baa5Scanacar struct cmsghdr *cmsg; 910296baa5Scanacar struct iovec vec; 920296baa5Scanacar ssize_t n; 930296baa5Scanacar int result; 940296baa5Scanacar int fd; 950296baa5Scanacar 960296baa5Scanacar memset(&msg, 0, sizeof(msg)); 970296baa5Scanacar vec.iov_base = &result; 980296baa5Scanacar vec.iov_len = sizeof(int); 990296baa5Scanacar msg.msg_iov = &vec; 1000296baa5Scanacar msg.msg_iovlen = 1; 1010296baa5Scanacar msg.msg_control = tmp; 1020296baa5Scanacar msg.msg_controllen = sizeof(tmp); 1030296baa5Scanacar 1040296baa5Scanacar if ((n = recvmsg(sock, &msg, 0)) == -1) 1050296baa5Scanacar warn("%s: recvmsg", __func__); 1060296baa5Scanacar if (n != sizeof(int)) 1070296baa5Scanacar warnx("%s: recvmsg: expected received 1 got %ld", 1080296baa5Scanacar __func__, (long)n); 1090296baa5Scanacar if (result == 0) { 1100296baa5Scanacar cmsg = CMSG_FIRSTHDR(&msg); 111*ee42e03cSdjm if (cmsg == NULL) { 112*ee42e03cSdjm warnx("%s: no message header", __func__); 113*ee42e03cSdjm return -1; 114*ee42e03cSdjm } 1150296baa5Scanacar if (cmsg->cmsg_type != SCM_RIGHTS) 1160296baa5Scanacar warnx("%s: expected type %d got %d", __func__, 1170296baa5Scanacar SCM_RIGHTS, cmsg->cmsg_type); 1180296baa5Scanacar fd = (*(int *)CMSG_DATA(cmsg)); 1190296baa5Scanacar return fd; 1200296baa5Scanacar } else { 1210296baa5Scanacar errno = result; 1220296baa5Scanacar return -1; 1230296baa5Scanacar } 1240296baa5Scanacar } 125