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