-static int privileged, unprivileged;
-void
-priv_privileged_fd(int fd)
-{
- privileged = fd;
-}
-void
-priv_unprivileged_fd(int fd)
-{
- unprivileged = fd;
-}
-int
-priv_fd(enum priv_context ctx)
-{
- switch (ctx) {
- case PRIV_PRIVILEGED: return privileged;
- case PRIV_UNPRIVILEGED: return unprivileged;
- }
- return -1; /* Not possible */
-}
-
-/*
- * Copyright 2001 Niels Provos <provos@citi.umich.edu>
- * All rights reserved.
- *
- * Copyright (c) 2002 Matthieu Herrb
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-void
-send_fd(enum priv_context ctx, int fd)
-{
- struct msghdr msg;
- union {
- struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int))];
- } cmsgbuf;
- struct cmsghdr *cmsg;
- struct iovec vec;
- int result = 0;
- ssize_t n;
-
- memset(&msg, 0, sizeof(msg));
- memset(&cmsgbuf.buf, 0, sizeof(cmsgbuf.buf));
-
- if (fd >= 0) {
- msg.msg_control = (caddr_t)&cmsgbuf.buf;
- msg.msg_controllen = sizeof(cmsgbuf.buf);
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
- } else {
- result = errno;
- }
-
- vec.iov_base = &result;
- vec.iov_len = sizeof(int);
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
-
- if ((n = sendmsg(priv_fd(ctx), &msg, 0)) == -1)
- log_warn("privsep", "sendmsg(%d)", priv_fd(ctx));
- if (n != sizeof(int))
- log_warnx("privsep", "sendmsg: expected sent 1 got %ld",
- (long)n);
-}
-
-int
-receive_fd(enum priv_context ctx)
-{
- struct msghdr msg;
- union {
- struct cmsghdr hdr;
- char buf[CMSG_SPACE(sizeof(int))];
- } cmsgbuf;
- struct cmsghdr *cmsg;
- struct iovec vec;
- ssize_t n;
- int result;
- int fd;
-
- memset(&msg, 0, sizeof(msg));
- vec.iov_base = &result;
- vec.iov_len = sizeof(int);
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_control = &cmsgbuf.buf;
- msg.msg_controllen = sizeof(cmsgbuf.buf);
-
- if ((n = recvmsg(priv_fd(ctx), &msg, 0)) == -1)
- log_warn("privsep", "recvmsg");
- if (n != sizeof(int))
- log_warnx("privsep", "recvmsg: expected received 1 got %ld",
- (long)n);
- if (result == 0) {
- cmsg = CMSG_FIRSTHDR(&msg);
- if (cmsg == NULL) {
- log_warnx("privsep", "no message header");
- return -1;
- }
- if (cmsg->cmsg_type != SCM_RIGHTS)
- log_warnx("privsep", "expected type %d got %d",
- SCM_RIGHTS, cmsg->cmsg_type);
- memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
- return fd;
- } else {
- errno = result;
- return -1;
- }
-}
-