1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-22 11:17:19 +00:00

Garbage collect PORTALFS bits which are now completely disconnected from

the tree since few months.

This patch is not targeted for MFC.
This commit is contained in:
Attilio Rao 2013-03-02 16:43:28 +00:00
parent f51fb78533
commit 4eb0218ace
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=247640
22 changed files with 7 additions and 3005 deletions

View File

@ -38,6 +38,13 @@
# xargs -n1 | sort | uniq -d;
# done
# 20130302: PORTALFS support removed
OLD_FILES+=usr/include/fs/portalfs/portal.h
OLD_DIRS+=usr/include/fs/portalfs
OLD_FILES+=usr/share/examples/portal/README
OLD_FILES+=usr/share/examples/portal/portal.conf
OLD_DIRS+=usr/share/examples/portal
OLD_FILES+=usr/share/man/man8/mount_portalfs.8.gz
# 20130302: CODAFS support removed
OLD_FILES+=usr/share/man/man4/coda.4.gz
# 20130302: XFS support removed

View File

@ -1,65 +0,0 @@
$FreeBSD$
This contains a couple of examples for using the portal filing system.
The portal file system provides a way of obtaining a file descriptor
to a filesystem object (i.e. something that is accessed by open(2),
pipe(2), socket(2) or socketpair(2)) via the filesystem namespace.
At present the only file descriptor supported are TCP sockets and
files.
NOTE!!!! The portal file system is experimental in nature and should
not be considered secure, use with caution.
First off mount the filesystem using something like:
# mount_portalfs /usr/share/examples/portal/portal.conf /p
Then you should be able to do things like
# cat /p/tcp/localhost/daytime
Sun Nov 22 17:50:09 1998
(assuming inetd is running the daytime service, by default it is off)
Welcome to FreeBSD!
# mkdir -p /tmp/root
# cd /tmp/root
# mkdir bin p
# cp /bin/sh /bin/cat bin
# mount_portalfs /usr/share/examples/portal/portal.conf /tmp/root/p
# chroot /tmp/root
# pwd
/
# echo *
bin p
# cat /etc/motd
cat: /etc/motd: No such file or directory
# cat /p/fs/etc/motd
FreeBSD 2.2.6-RELEASE (COMPUTER) #0: Sat Aug 22 17:11:37 BST 1998
Welcome to FreeBSD!
Finally, a very simple example of the listening server is available,
fire up two xterms. In the first
xterm-1$ cat /p/tcplisten/ANY/6666
(the ANY is a wildcard just like using INADDR_ANY, any resolvable host
can be used).
In the second xterm
xterm-2$ echo "hello there" >/p/tcp/localhost/6666
You should see the "hello there" string appear on the first terminal.
Unprivilged users can't create servers on privalged ports.
xterm-1$ cat /p/tcplisten/ANY/666
cat: /p/tcplisten/ANY/666: Operation not permitted
but root can
xterm-1# cat /p/tcplisten/ANY/666
In the second
xterm-2$ echo "hello there" >/p/tcp/localhost/666
should produce the expected response.
You can also swap the client/server read and write commands etc.

View File

@ -1,3 +0,0 @@
tcp/ tcp tcp/
tcplisten/ tcplisten tcplisten/
fs/ file fs/

View File

@ -1,67 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)portal.h 8.4 (Berkeley) 1/21/94
*
* $FreeBSD$
*/
struct portal_args {
char *pa_config; /* Config file */
int pa_socket; /* Socket to server */
};
struct portal_cred {
int pcr_flag; /* File open mode */
uid_t pcr_uid; /* From ucred */
short pcr_ngroups; /* From ucred */
gid_t pcr_groups[XU_NGROUPS]; /* From ucred */
};
#ifdef _KERNEL
struct portalmount {
struct vnode *pm_root; /* Root node */
struct file *pm_server; /* Held reference to server socket */
};
struct portalnode {
int pt_size; /* Length of Arg */
char *pt_arg; /* Arg to send to server */
int pt_fileid; /* cookie */
};
#define VFSTOPORTAL(mp) ((struct portalmount *)((mp)->mnt_data))
#define VTOPORTAL(vp) ((struct portalnode *)(vp)->v_data)
#define PORTAL_ROOTFILEID 2
extern struct vop_vector portal_vnodeops;
#endif /* _KERNEL */

View File

@ -1,263 +0,0 @@
/*-
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)portal_vfsops.c 8.11 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
/*
* Portal Filesystem
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/capability.h>
#include <sys/domain.h>
#include <sys/filedesc.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
#include <sys/file.h> /* Must come after sys/malloc.h */
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/vnode.h>
#include <fs/portalfs/portal.h>
static MALLOC_DEFINE(M_PORTALFSMNT, "portal_mount", "PORTAL mount structure");
static vfs_unmount_t portal_unmount;
static vfs_root_t portal_root;
static vfs_statfs_t portal_statfs;
static const char *portal_opts[] = {
"socket", "config",
NULL
};
static int
portal_cmount(struct mntarg *ma, void *data, uint64_t flags)
{
struct portal_args args;
int error;
if (data == NULL)
return (EINVAL);
error = copyin(data, &args, sizeof args);
if (error)
return (error);
ma = mount_argf(ma, "socket", "%d", args.pa_socket);
ma = mount_argsu(ma, "config", args.pa_config, MAXPATHLEN);
error = kernel_mount(ma, flags);
return (error);
}
/*
* Mount the per-process file descriptors (/dev/fd)
*/
static int
portal_mount(struct mount *mp)
{
struct file *fp;
struct portalmount *fmp;
struct socket *so;
struct vnode *rvp;
struct thread *td;
struct portalnode *pn;
int error, v;
char *p;
td = curthread;
if (vfs_filteropt(mp->mnt_optnew, portal_opts))
return (EINVAL);
error = vfs_scanopt(mp->mnt_optnew, "socket", "%d", &v);
if (error != 1)
return (EINVAL);
error = vfs_getopt(mp->mnt_optnew, "config", (void **)&p, NULL);
if (error)
return (error);
/*
* Capsicum is not incompatible with portalfs, but we don't really
* know what rights are required. In the spirit of "better safe than
* sorry", pretend that all rights are required for now.
*/
if ((error = fget(td, v, CAP_MASK_VALID, &fp)) != 0)
return (error);
if (fp->f_type != DTYPE_SOCKET) {
fdrop(fp, td);
return(ENOTSOCK);
}
so = fp->f_data; /* XXX race against userland */
if (so->so_proto->pr_domain->dom_family != AF_UNIX) {
fdrop(fp, td);
return (ESOCKTNOSUPPORT);
}
pn = malloc(sizeof(struct portalnode),
M_TEMP, M_WAITOK);
fmp = malloc(sizeof(struct portalmount),
M_PORTALFSMNT, M_WAITOK); /* XXX */
error = getnewvnode("portal", mp, &portal_vnodeops, &rvp); /* XXX */
if (error) {
free(fmp, M_PORTALFSMNT);
free(pn, M_TEMP);
fdrop(fp, td);
return (error);
}
error = insmntque(rvp, mp); /* XXX: Too early for mpsafe fs */
if (error != 0) {
free(fmp, M_PORTALFSMNT);
free(pn, M_TEMP);
fdrop(fp, td);
return (error);
}
rvp->v_data = pn;
rvp->v_type = VDIR;
rvp->v_vflag |= VV_ROOT;
VTOPORTAL(rvp)->pt_arg = 0;
VTOPORTAL(rvp)->pt_size = 0;
VTOPORTAL(rvp)->pt_fileid = PORTAL_ROOTFILEID;
fmp->pm_root = rvp;
fhold(fp);
fmp->pm_server = fp;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
MNT_IUNLOCK(mp);
mp->mnt_data = fmp;
vfs_getnewfsid(mp);
vfs_mountedfrom(mp, p);
fdrop(fp, td);
return (0);
}
static int
portal_unmount(mp, mntflags)
struct mount *mp;
int mntflags;
{
int error, flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
/*
* Clear out buffer cache. I don't think we
* ever get anything cached at this level at the
* moment, but who knows...
*/
#ifdef notyet
mntflushbuf(mp, 0);
if (mntinvalbuf(mp, 1))
return (EBUSY);
#endif
/* There is 1 extra root vnode reference (pm_root). */
error = vflush(mp, 1, flags, curthread);
if (error)
return (error);
/*
* Shutdown the socket. This will cause the select in the
* daemon to wake up, and then the accept will get ECONNABORTED
* which it interprets as a request to go and bury itself.
*/
soshutdown(VFSTOPORTAL(mp)->pm_server->f_data, 2);
/*
* Discard reference to underlying file. Must call closef because
* this may be the last reference.
*/
closef(VFSTOPORTAL(mp)->pm_server, (struct thread *) 0);
/*
* Finally, throw away the portalmount structure
*/
free(mp->mnt_data, M_PORTALFSMNT); /* XXX */
mp->mnt_data = NULL;
return (0);
}
static int
portal_root(mp, flags, vpp)
struct mount *mp;
int flags;
struct vnode **vpp;
{
struct vnode *vp;
/*
* Return locked reference to root.
*/
vp = VFSTOPORTAL(mp)->pm_root;
VREF(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
*vpp = vp;
return (0);
}
static int
portal_statfs(mp, sbp)
struct mount *mp;
struct statfs *sbp;
{
sbp->f_flags = 0;
sbp->f_bsize = DEV_BSIZE;
sbp->f_iosize = DEV_BSIZE;
sbp->f_blocks = 2; /* 1K to keep df happy */
sbp->f_bfree = 0;
sbp->f_bavail = 0;
sbp->f_files = 1; /* Allow for "." */
sbp->f_ffree = 0; /* See comments above */
return (0);
}
static struct vfsops portal_vfsops = {
.vfs_cmount = portal_cmount,
.vfs_mount = portal_mount,
.vfs_root = portal_root,
.vfs_statfs = portal_statfs,
.vfs_unmount = portal_unmount,
};
VFS_SET(portal_vfsops, portalfs, VFCF_SYNTHETIC);

View File

@ -1,586 +0,0 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)portal_vnops.c 8.14 (Berkeley) 5/21/95
*
* $FreeBSD$
*/
/*
* Portal Filesystem
*/
#include "opt_capsicum.h"
#include <sys/param.h>
#include <sys/capability.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/systm.h>
#include <sys/un.h>
#include <sys/unpcb.h>
#include <sys/vnode.h>
#include <fs/portalfs/portal.h>
#include <net/vnet.h>
static int portal_fileid = PORTAL_ROOTFILEID+1;
static void portal_closefd(struct thread *td, int fd);
static int portal_connect(struct socket *so, struct socket *so2);
static vop_getattr_t portal_getattr;
static vop_lookup_t portal_lookup;
static vop_open_t portal_open;
static vop_readdir_t portal_readdir;
static vop_reclaim_t portal_reclaim;
static vop_setattr_t portal_setattr;
static void
portal_closefd(td, fd)
struct thread *td;
int fd;
{
int error;
error = kern_close(td, fd);
/*
* We should never get an error, and there isn't anything
* we could do if we got one, so just print a message.
*/
if (error)
printf("portal_closefd: error = %d\n", error);
}
/*
* vp is the current namei directory
* cnp is the name to locate in that directory...
*/
static int
portal_lookup(ap)
struct vop_lookup_args /* {
struct vnode * a_dvp;
struct vnode ** a_vpp;
struct componentname * a_cnp;
} */ *ap;
{
struct componentname *cnp = ap->a_cnp;
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
struct portalnode *pt;
int error;
struct vnode *fvp = NULL;
char *path;
int size;
*vpp = NULLVP;
if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
return (EROFS);
if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp;
VREF(dvp);
return (0);
}
KASSERT((cnp->cn_flags & ISDOTDOT) == 0,
("portal_lookup: Can not handle dotdot lookups."));
/*
* Do the MALLOC before the getnewvnode since doing so afterward
* might cause a bogus v_data pointer to get dereferenced
* elsewhere if MALLOC should block.
*/
pt = malloc(sizeof(struct portalnode),
M_TEMP, M_WAITOK);
error = getnewvnode("portal", dvp->v_mount, &portal_vnodeops, &fvp);
if (error) {
free(pt, M_TEMP);
goto bad;
}
fvp->v_type = VREG;
fvp->v_data = pt;
/*
* Save all of the remaining pathname and
* advance the namei next pointer to the end
* of the string.
*/
for (size = 0, path = pname; *path; path++)
size++;
cnp->cn_consume = size - cnp->cn_namelen;
pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK);
pt->pt_size = size+1;
bcopy(pname, pt->pt_arg, pt->pt_size);
pt->pt_fileid = portal_fileid++;
*vpp = fvp;
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
error = insmntque(fvp, dvp->v_mount);
if (error != 0) {
*vpp = NULLVP;
return (error);
}
return (0);
bad:;
if (fvp)
vrele(fvp);
return (error);
}
static int
portal_connect(so, so2)
struct socket *so;
struct socket *so2;
{
/* from unp_connect, bypassing the namei stuff... */
struct socket *so3;
struct unpcb *unp2;
struct unpcb *unp3;
if (so2 == 0)
return (ECONNREFUSED);
if (so->so_type != so2->so_type)
return (EPROTOTYPE);
if ((so2->so_options & SO_ACCEPTCONN) == 0)
return (ECONNREFUSED);
CURVNET_SET(so2->so_vnet);
if ((so3 = sonewconn(so2, 0)) == 0) {
CURVNET_RESTORE();
return (ECONNREFUSED);
}
CURVNET_RESTORE();
unp2 = sotounpcb(so2);
unp3 = sotounpcb(so3);
if (unp2->unp_addr)
unp3->unp_addr = (struct sockaddr_un *)
sodupsockaddr((struct sockaddr *)unp2->unp_addr,
M_NOWAIT);
so2 = so3;
return (soconnect2(so, so2));
}
static int
portal_open(ap)
struct vop_open_args /* {
struct vnode *a_vp;
int a_mode;
struct ucred *a_cred;
struct thread *a_td;
} */ *ap;
{
struct socket *so = NULL;
struct portalnode *pt;
struct thread *td = ap->a_td;
struct vnode *vp = ap->a_vp;
struct uio auio;
struct iovec aiov[2];
int res;
struct mbuf *cm = NULL;
struct cmsghdr *cmsg;
int newfds;
int *ip;
int fd;
int error;
int len;
struct portalmount *fmp;
struct file *fp;
struct portal_cred pcred;
#ifdef CAPABILITY_MODE
/*
* This may require access to a global namespace (e.g. an IP address);
* disallow it entirely, as we do open(2).
*/
if (IN_CAPABILITY_MODE(td)) {
#ifdef KTRACE
if (KTRPOINT(td, KTR_CAPFAIL))
ktrcapfail(CAPFAIL_SYSCALL, 0, 0);
#endif
return (ECAPMODE);
}
#endif
/*
* Nothing to do when opening the root node.
*/
if (vp->v_vflag & VV_ROOT)
return (0);
/*
* Can't be opened unless the caller is set up
* to deal with the side effects. Check for this
* by testing whether td_dupfd has been set.
*/
if (td->td_dupfd >= 0)
return (ENODEV);
pt = VTOPORTAL(vp);
fmp = VFSTOPORTAL(vp->v_mount);
/*
* Create a new socket.
*/
error = socreate(AF_UNIX, &so, SOCK_STREAM, 0, ap->a_cred,
ap->a_td);
if (error)
goto bad;
/*
* Reserve some buffer space
*/
res = pt->pt_size + sizeof(pcred) + 512; /* XXX */
error = soreserve(so, res, res);
if (error)
goto bad;
/*
* Kick off connection
*/
error = portal_connect(so, fmp->pm_server->f_data);
if (error)
goto bad;
/*
* Wait for connection to complete
*/
/*
* XXX: Since the mount point is holding a reference on the
* underlying server socket, it is not easy to find out whether
* the server process is still running. To handle this problem
* we loop waiting for the new socket to be connected (something
* which will only happen if the server is still running) or for
* the reference count on the server socket to drop to 1, which
* will happen if the server dies. Sleep for 5 second intervals
* and keep polling the reference count. XXX.
*/
SOCK_LOCK(so);
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
if (fmp->pm_server->f_count == 1) {
SOCK_UNLOCK(so);
error = ECONNREFUSED;
goto bad;
}
(void) msleep((caddr_t) &so->so_timeo, SOCK_MTX(so), PSOCK,
"portalcon", 5 * hz);
}
SOCK_UNLOCK(so);
if (so->so_error) {
error = so->so_error;
goto bad;
}
/*
* Set miscellaneous flags
*/
SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_timeo = 0;
so->so_rcv.sb_flags |= SB_NOINTR;
SOCKBUF_UNLOCK(&so->so_rcv);
SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_timeo = 0;
so->so_snd.sb_flags |= SB_NOINTR;
SOCKBUF_UNLOCK(&so->so_snd);
pcred.pcr_flag = ap->a_mode;
pcred.pcr_uid = ap->a_cred->cr_uid;
pcred.pcr_ngroups = MIN(ap->a_cred->cr_ngroups, XU_NGROUPS);
bcopy(ap->a_cred->cr_groups, pcred.pcr_groups,
pcred.pcr_ngroups * sizeof(gid_t));
aiov[0].iov_base = (caddr_t) &pcred;
aiov[0].iov_len = sizeof(pcred);
aiov[1].iov_base = pt->pt_arg;
aiov[1].iov_len = pt->pt_size;
auio.uio_iov = aiov;
auio.uio_iovcnt = 2;
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_td = td;
auio.uio_offset = 0;
auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len;
error = sosend(so, (struct sockaddr *) 0, &auio,
(struct mbuf *) 0, (struct mbuf *) 0, 0 , td);
if (error)
goto bad;
len = auio.uio_resid = sizeof(int);
do {
struct mbuf *m = NULL;
int flags = MSG_WAITALL;
error = soreceive(so, (struct sockaddr **) 0, &auio,
&m, &cm, &flags);
if (error)
goto bad;
/*
* Grab an error code from the mbuf.
*/
if (m) {
m = m_pullup(m, sizeof(int)); /* Needed? */
if (m) {
error = *(mtod(m, int *));
m_freem(m);
} else {
error = EINVAL;
}
} else {
if (cm == 0) {
error = ECONNRESET; /* XXX */
#ifdef notdef
break;
#endif
}
}
} while (cm == 0 && auio.uio_resid == len && !error);
if (cm == 0)
goto bad;
if (auio.uio_resid) {
error = 0;
#ifdef notdef
error = EMSGSIZE;
goto bad;
#endif
}
/*
* XXX: Break apart the control message, and retrieve the
* received file descriptor. Note that more than one descriptor
* may have been received, or that the rights chain may have more
* than a single mbuf in it. What to do?
*/
cmsg = mtod(cm, struct cmsghdr *);
newfds = (cmsg->cmsg_len - sizeof(*cmsg)) / sizeof (int);
if (newfds == 0) {
error = ECONNREFUSED;
goto bad;
}
/*
* At this point the rights message consists of a control message
* header, followed by a data region containing a vector of
* integer file descriptors. The fds were allocated by the action
* of receiving the control message.
*/
ip = (int *) (cmsg + 1);
fd = *ip++;
if (newfds > 1) {
/*
* Close extra fds.
*/
int i;
printf("portal_open: %d extra fds\n", newfds - 1);
for (i = 1; i < newfds; i++) {
portal_closefd(td, *ip);
ip++;
}
}
/*
* Check that the mode the file is being opened for is a subset
* of the mode of the existing descriptor.
*/
if ((error = fget(td, fd, 0, &fp)) != 0)
goto bad;
if (((ap->a_mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) {
fdrop(fp, td);
portal_closefd(td, fd);
error = EACCES;
goto bad;
}
fdrop(fp, td);
/*
* Save the dup fd in the proc structure then return the
* special error code (ENXIO) which causes magic things to
* happen in vn_open. The whole concept is, well, hmmm.
*/
td->td_dupfd = fd;
error = ENXIO;
bad:;
/*
* And discard the control message.
*/
if (cm) {
m_freem(cm);
}
if (so) {
soshutdown(so, 2);
soclose(so);
}
return (error);
}
static int
portal_getattr(ap)
struct vop_getattr_args /* {
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct vattr *vap = ap->a_vap;
vap->va_uid = 0;
vap->va_gid = 0;
vap->va_size = DEV_BSIZE;
vap->va_blocksize = DEV_BSIZE;
nanotime(&vap->va_atime);
vap->va_mtime = vap->va_atime;
vap->va_ctime = vap->va_mtime;
vap->va_gen = 0;
vap->va_flags = 0;
vap->va_rdev = NODEV;
/* vap->va_qbytes = 0; */
vap->va_bytes = 0;
vap->va_filerev = 0;
/* vap->va_qsize = 0; */
if (vp->v_vflag & VV_ROOT) {
vap->va_type = VDIR;
vap->va_mode = S_IRUSR|S_IWUSR|S_IXUSR|
S_IRGRP|S_IWGRP|S_IXGRP|
S_IROTH|S_IWOTH|S_IXOTH;
vap->va_nlink = 2;
vap->va_fileid = 2;
} else {
vap->va_type = VREG;
vap->va_mode = S_IRUSR|S_IWUSR|
S_IRGRP|S_IWGRP|
S_IROTH|S_IWOTH;
vap->va_nlink = 1;
vap->va_fileid = VTOPORTAL(vp)->pt_fileid;
}
return (0);
}
static int
portal_setattr(ap)
struct vop_setattr_args /* {
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
} */ *ap;
{
/*
* Can't mess with the root vnode
*/
if (ap->a_vp->v_vflag & VV_ROOT)
return (EACCES);
if (ap->a_vap->va_flags != VNOVAL)
return (EOPNOTSUPP);
return (0);
}
/*
* Fake readdir, just return empty directory.
* It is hard to deal with '.' and '..' so don't bother.
*/
static int
portal_readdir(ap)
struct vop_readdir_args /* {
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
int *a_eofflag;
u_long *a_cookies;
int a_ncookies;
} */ *ap;
{
/*
* We don't allow exporting portal mounts, and currently local
* requests do not need cookies.
*/
if (ap->a_ncookies)
panic("portal_readdir: not hungry");
return (0);
}
static int
portal_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
} */ *ap;
{
struct portalnode *pt = VTOPORTAL(ap->a_vp);
if (pt->pt_arg) {
free((caddr_t) pt->pt_arg, M_TEMP);
pt->pt_arg = 0;
}
free(ap->a_vp->v_data, M_TEMP);
ap->a_vp->v_data = 0;
return (0);
}
struct vop_vector portal_vnodeops = {
.vop_default = &default_vnodeops,
.vop_access = VOP_NULL,
.vop_getattr = portal_getattr,
.vop_lookup = portal_lookup,
.vop_open = portal_open,
.vop_pathconf = vop_stdpathconf,
.vop_readdir = portal_readdir,
.vop_reclaim = portal_reclaim,
.vop_setattr = portal_setattr,
};

View File

@ -1,10 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../fs/portalfs
KMOD= portalfs
SRCS= vnode_if.h \
portal_vfsops.c portal_vnops.c \
opt_capsicum.h
.include <bsd.kmod.mk>

View File

@ -1,15 +0,0 @@
# From: @(#)Makefile 8.3 (Berkeley) 3/27/94
# $FreeBSD$
PROG= mount_portalfs
SRCS= mount_portalfs.c activate.c conf.c cred.c getmntopts.c pt_conf.c \
pt_exec.c pt_file.c pt_pipe.c pt_tcp.c pt_tcplisten.c
MAN= mount_portalfs.8
MOUNT= ${.CURDIR}/../../sbin/mount
CFLAGS+=-I${MOUNT}
WARNS?= 3
.PATH: ${MOUNT}
.include <bsd.prog.mk>

View File

@ -1,195 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)activate.c 8.3 (Berkeley) 4/28/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/uio.h>
#include "portald.h"
/*
* Scan the providers list and call the
* appropriate function.
*/
static int activate_argv(struct portal_cred *pcr, char *key, char **v, int so,
int *fdp)
{
provider *pr;
for (pr = providers; pr->pr_match; pr++)
if (strcmp(v[0], pr->pr_match) == 0)
return ((*pr->pr_func)(pcr, key, v, so, fdp));
return (ENOENT);
}
static int get_request(int so, struct portal_cred *pcr, char *key, int klen)
{
struct iovec iov[2];
struct msghdr msg;
int n;
iov[0].iov_base = (caddr_t) pcr;
iov[0].iov_len = sizeof(*pcr);
iov[1].iov_base = key;
iov[1].iov_len = klen;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = iov;
msg.msg_iovlen = 2;
n = recvmsg(so, &msg, 0);
if (n < 0)
return (errno);
if (n <= (int)sizeof(*pcr))
return (EINVAL);
n -= sizeof(*pcr);
key[n] = '\0';
return (0);
}
static void send_reply(int so, int fd, int error)
{
int n;
struct iovec iov;
struct msghdr msg;
union {
struct cmsghdr cmsg;
char control[CMSG_SPACE(sizeof(int))];
} ctl;
/*
* Line up error code. Don't worry about byte ordering
* because we must be sending to the local machine.
*/
iov.iov_base = (caddr_t) &error;
iov.iov_len = sizeof(error);
/*
* Build a msghdr
*/
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
/*
* If there is a file descriptor to send then
* construct a suitable rights control message.
*/
if (fd >= 0) {
ctl.cmsg.cmsg_len = CMSG_LEN(sizeof(int));
ctl.cmsg.cmsg_level = SOL_SOCKET;
ctl.cmsg.cmsg_type = SCM_RIGHTS;
*((int *)CMSG_DATA(&ctl.cmsg)) = fd;
msg.msg_control = (caddr_t) &ctl;
msg.msg_controllen = ctl.cmsg.cmsg_len;
}
/*
* Send to kernel...
*/
if ((n = sendmsg(so, &msg, 0)) < 0)
syslog(LOG_ERR, "send: %s", strerror(errno));
#ifdef DEBUG
fprintf(stderr, "sent %d bytes\n", n);
#endif
sleep(1); /*XXX*/
#ifdef notdef
if (shutdown(so, SHUT_RDWR) < 0)
syslog(LOG_ERR, "shutdown: %s", strerror(errno));
#endif
/*
* Throw away the open file descriptor
*/
(void) close(fd);
}
void activate(qelem *q, int so)
{
struct portal_cred pcred;
char key[MAXPATHLEN+1];
int error;
char **v;
int fd = -1;
/*
* Read the key from the socket
*/
error = get_request(so, &pcred, key, sizeof(key));
if (error) {
syslog(LOG_ERR, "activate: recvmsg: %s", strerror(error));
goto drop;
}
#ifdef DEBUG
fprintf(stderr, "lookup key %s\n", key);
#endif
/*
* Find a match in the configuration file
*/
v = conf_match(q, key);
/*
* If a match existed, then find an appropriate portal
* otherwise simply return ENOENT.
*/
if (v) {
error = activate_argv(&pcred, key, v, so, &fd);
if (error)
fd = -1;
else if (fd < 0)
error = -1;
} else {
error = ENOENT;
}
if (error >= 0)
send_reply(so, fd, error);
drop:;
close(so);
}

View File

@ -1,318 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)conf.c 8.2 (Berkeley) 3/27/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <regex.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include "portald.h"
#define ALLOC(ty) (xmalloc(sizeof(ty)))
typedef struct path path;
struct path {
qelem p_q; /* 2-way linked list */
int p_lno; /* Line number of this record */
char *p_args; /* copy of arg string (malloc) */
char *p_key; /* Pathname to match (also p_argv[0]) */
regex_t p_rx; /* RE to match against pathname () */
int p_rxvalid; /* non-zero if valid regular expression */
int p_argc; /* number of elements in arg string */
char **p_argv; /* argv[] pointers into arg string (malloc) */
};
static char *conf_file; /* XXX for regerror */
static path *curp; /* XXX for regerror */
/*
* Add an element to a 2-way list,
* just after (pred)
*/
static void ins_que(qelem *elem, qelem *pred)
{
qelem *p = pred->q_forw;
elem->q_back = pred;
elem->q_forw = p;
pred->q_forw = elem;
p->q_back = elem;
}
/*
* Remove an element from a 2-way list
*/
static void rem_que(qelem *elem)
{
qelem *p = elem->q_forw;
qelem *p2 = elem->q_back;
p2->q_forw = p;
p->q_back = p2;
}
/*
* Error checking malloc
*/
static void *xmalloc(unsigned siz)
{
void *p = malloc(siz);
if (p)
return (p);
syslog(LOG_ALERT, "malloc: failed to get %d bytes", siz);
exit(1);
}
/*
* Insert the path in the list.
* If there is already an element with the same key then
* the *second* one is ignored (return 0). If the key is
* not found then the path is added to the end of the list
* and 1 is returned.
*/
static int pinsert(path *p0, qelem *q0)
{
qelem *q;
if (p0->p_argc == 0)
return (0);
for (q = q0->q_forw; q != q0; q = q->q_forw) {
path *p = (path *) q;
if (strcmp(p->p_key, p0->p_key) == 0)
return (0);
}
ins_que(&p0->p_q, q0->q_back);
return (1);
}
static path *palloc(char *cline, int lno)
{
int c;
char *s;
char *key;
path *p;
char **ap;
/*
* Implement comment chars
*/
s = strchr(cline, '#');
if (s)
*s = 0;
/*
* Do a pass through the string to count the number
* of arguments
*/
c = 0;
key = strdup(cline);
for (s = key; s != NULL; ) {
char *val;
while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
;
if (val)
c++;
}
c++;
free(key);
if (c <= 1)
return (0);
/*
* Now do another pass and generate a new path structure
*/
p = ALLOC(path);
p->p_argc = 0;
p->p_argv = xmalloc(c * sizeof(char *));
p->p_args = strdup(cline);
ap = p->p_argv;
for (s = p->p_args; s != NULL; ) {
char *val;
while ((val = strsep(&s, " \t\n")) != NULL && *val == '\0')
;
if (val) {
*ap++ = val;
p->p_argc++;
}
}
*ap = 0;
#ifdef DEBUG
for (c = 0; c < p->p_argc; c++)
printf("%sv[%d] = %s\n", c?"\t":"", c, p->p_argv[c]);
#endif
p->p_key = p->p_argv[0];
if (strpbrk(p->p_key, RE_CHARS)) {
int val;
curp = p; /* XXX */
val = regcomp(&p->p_rx, p->p_key, REG_EXTENDED | REG_NOSUB);
if (val) {
char errbuf[_POSIX2_LINE_MAX];
regerror(val, &p->p_rx, errbuf, sizeof errbuf);
syslog(LOG_ERR, "%s:%d: regcomp %s: %s",
conf_file, curp->p_lno, curp->p_key, errbuf);
regfree(&p->p_rx);
p->p_rxvalid = 0;
} else {
p->p_rxvalid = 1;
}
curp = 0; /* XXX */
} else {
p->p_rxvalid = 0;
}
p->p_lno = lno;
return (p);
}
/*
* Free a path structure
*/
static void pfree(path *p)
{
free(p->p_args);
if (p->p_rxvalid) {
regfree(&p->p_rx);
}
free((char *) p->p_argv);
free((char *) p);
}
/*
* Discard all currently held path structures on q0.
* and add all the ones on xq.
*/
static void preplace(qelem *q0, qelem *xq)
{
/*
* While the list is not empty,
* take the first element off the list
* and free it.
*/
while (q0->q_forw != q0) {
qelem *q = q0->q_forw;
rem_que(q);
pfree((path *) q);
}
while (xq->q_forw != xq) {
qelem *q = xq->q_forw;
rem_que(q);
ins_que(q, q0);
}
}
/*
* Read the lines from the configuration file and
* add them to the list of paths.
*/
static void readfp(qelem *q0, FILE *fp)
{
char cline[LINE_MAX];
int nread = 0;
qelem q;
/*
* Make a new empty list.
*/
q.q_forw = q.q_back = &q;
/*
* Read the lines from the configuration file.
*/
while (fgets(cline, sizeof(cline), fp)) {
path *p = palloc(cline, nread+1);
if (p && !pinsert(p, &q))
pfree(p);
nread++;
}
/*
* If some records were read, then throw
* away the old list and replace with the
* new one.
*/
if (nread)
preplace(q0, &q);
}
/*
* Read the configuration file (conf) and replace
* the existing path list with the new version.
* If the file is not readable, then no changes take place
*/
void conf_read(qelem *q, char *conf)
{
FILE *fp = fopen(conf, "r");
if (fp) {
conf_file = conf; /* XXX */
readfp(q, fp);
conf_file = 0; /* XXX */
(void) fclose(fp);
} else {
syslog(LOG_ERR, "open config file \"%s\": %s", conf, strerror(errno));
}
}
char **conf_match(qelem *q0, char *key)
{
qelem *q;
for (q = q0->q_forw; q != q0; q = q->q_forw) {
path *p = (path *) q;
if (p->p_rxvalid) {
if (!regexec(&p->p_rx, key, 0, 0, 0)) {
return p->p_argv + 1;
}
} else {
if (strncmp(p->p_key, key, strlen(p->p_key)) == 0)
return (p->p_argv+1);
}
}
return (0);
}

View File

@ -1,75 +0,0 @@
/*-
* Copyright (C) 2005 Diomidis Spinellis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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 AUTHOR 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 AUTHOR 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.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include "portald.h"
/*
* Set the process's credentials to those specified in user,
* saving the existing ones in save.
* Return 0 on success, -1 (with errno set) on error.
*/
int
set_user_credentials(struct portal_cred *user, struct portal_cred *save)
{
save->pcr_uid = geteuid();
if ((save->pcr_ngroups = getgroups(NGROUPS_MAX, save->pcr_groups)) < 0)
return (-1);
if (setgroups(user->pcr_ngroups, user->pcr_groups) < 0)
return (-1);
if (seteuid(user->pcr_uid) < 0)
return (-1);
return (0);
}
/*
* Restore the process's credentials to the ones specified in save.
* Log failures using LOG_ERR.
* Return 0 on success, -1 (with errno set) on error.
*/
int
restore_credentials(struct portal_cred *save)
{
if (seteuid(save->pcr_uid) < 0) {
syslog(LOG_ERR, "seteuid: %m");
return (-1);
}
if (setgroups(save->pcr_ngroups, save->pcr_groups) < 0) {
syslog(LOG_ERR, "setgroups: %m");
return (-1);
}
return (0);
}

View File

@ -1,216 +0,0 @@
.\"
.\" Copyright (c) 1993, 1994
.\" The Regents of the University of California. All rights reserved.
.\" All rights reserved.
.\"
.\" This code is derived from software donated to Berkeley by
.\" Jan-Simon Pendry.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. 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.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
.\"
.\" @(#)mount_portal.8 8.3 (Berkeley) 3/27/94
.\" $FreeBSD$
.\"
.Dd March 11, 2005
.Dt MOUNT_PORTALFS 8
.Os
.Sh NAME
.Nm mount_portalfs
.Nd mount the portal daemon
.Sh SYNOPSIS
.Nm
.Op Fl o Ar options
.Ar /etc/portal.conf
.Ar mount_point
.Sh DESCRIPTION
The
.Nm
utility attaches an instance of the portal daemon
to the global file system namespace.
The conventional mount point is
.Pa /p .
.\" .PA /dev .
This command is normally executed by
.Xr mount 8
at boot time.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl o
Options are specified with a
.Fl o
flag followed by a comma separated string of options.
See the
.Xr mount 8
man page for possible options and their meanings.
.El
.Pp
The portal daemon provides an
.Em open
service.
Objects opened under the portal mount point are
dynamically created by the portal daemon according
to rules specified in the named configuration file.
Using this mechanism allows descriptors such as sockets
to be made available in the file system namespace.
.Pp
The portal daemon works by being passed the full pathname
of the object being opened.
The daemon creates an appropriate descriptor according
to the rules in the configuration file, and then passes the descriptor back
to the calling process as the result of the open system call.
.Sh NAMESPACE
By convention, the portal daemon divides the namespace into sub-namespaces,
each of which handles objects of a particular type.
.Pp
The following sub-namespaces are currently implemented:
.Pa fs ,
.Pa pipe ,
.Pa tcp ,
and
.Pa tcplisten .
.Pp
The
.Pa fs
namespace opens the named file, starting back at the root directory.
This can be used to provide a controlled escape path from
a chrooted environment.
.Pp
The
.Pa pipe
namespace executes the named command, starting back at the root directory.
The command's arguments can be provided after the command's name,
by separating them with spaces or tabs.
Files opened for reading in the
.Pa pipe
namespace will receive their input from the command's standard output;
files opened for writing will send the data of write operations
to the command's standard input.
.Pp
The
.Pa tcp
namespace takes a slash separated hostname and a port and
creates an open TCP/IP connection.
.Pp
The
.Pa tcplisten
namespace takes a slash separated hostname and port and creates a TCP/IP
socket bound to the given hostname-port pair.
The hostname may be
specified as "ANY" to allow any other host to connect to the socket.
A
port number of 0 will dynamically allocate a port, this can be
discovered by calling
.Xr getsockname 2
with the returned file descriptor.
Privileged ports can only be bound to
by the super-user.
.Sh "CONFIGURATION FILE"
The configuration file contains a list of rules.
Each rule takes one line and consists of two or more
whitespace separated fields.
A hash (``#'') character causes the remainder of a line to
be ignored.
Blank lines are ignored.
.Pp
The first field is a pathname prefix to match
against the requested pathname.
If a match is found, the second field
tells the daemon what type of object to create.
Subsequent fields are passed to the creation function.
.Bd -literal
# @(#)portal.conf 5.1 (Berkeley) 7/13/92
tcplisten/ tcplisten tcplisten/
tcp/ tcp tcp/
fs/ file fs/
pipe/ pipe pipe/
.Ed
.Sh FILES
.Bl -tag -width /p/* -compact
.It Pa /p/*
.El
.Sh EXAMPLES
Display the greeting of the
.Fx
.Tn SMTP
server.
.Pp
.Dl "head -1 /p/tcp/mx1.freebsd.org/smtp"
.Pp
Implement a (single-threaded) echo server:
.Bd -literal -offset indent
while :
do
(exec 3<>/p/tcplisten/ANY/echo && cat -u <&3 >&3)
done
.Ed
.Pp
Gather data from two sources.
Verify that two remote files are identical:
.Bd -literal -offset indent
diff -q '/p/pipe/usr/bin/fetch -o - \\
ftp://ftp1.freebsd.org/pub/FreeBSD/README.TXT' \\
'/p/pipe/usr/bin/fetch -o - \\
ftp://ftp2.freebsd.org/pub/FreeBSD/README.TXT'
.Ed
.Pp
Scatter data to two sinks.
Record a remote
.Tn CD
.Tn ISO
image and calculate its checksum:
.Bd -literal -offset indent
fetch -o - ftp://ftp5.freebsd.org/.../disc.iso |
tee '/p/pipe/usr/local/bin/cdrecord -' |
md5
.Ed
.Pp
Create an
.Tn XML
view of the password file:
.Bd -literal -offset indent
ln -s '/p/pipe/usr/local/bin/passwd2xml /etc/passwd' \\
/etc/passwd.xml"
.Ed
.Sh SEE ALSO
.Xr mount 2 ,
.Xr unmount 2 ,
.Xr fstab 5 ,
.Xr mount 8
.Rs
.%A "W. Richard Stevens"
.%A "Jan-Simon Pendry"
.%T "Portals in 4.4BSD"
.%B "USENIX 1995 Technical Conference Proceedings"
.%O "Berkeley, CA"
.%I "Peter Honeyman"
.Re
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .
.Sh CAVEATS
This file system may not be NFS-exported.

View File

@ -1,281 +0,0 @@
/*
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1992, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#if 0
static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95";
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/mount.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "mntopts.h"
#include "pathnames.h"
#include "portald.h"
struct mntopt mopts[] = {
MOPT_STDOPTS,
MOPT_END
};
static void usage(void) __dead2;
static volatile sig_atomic_t readcf; /* Set when SIGHUP received */
static void sighup(int sig __unused)
{
readcf ++;
}
static void sigchld(int sig __unused)
{
pid_t pid;
while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0)
;
/* wrtp - waitpid _doesn't_ return 0 when no children! */
#ifdef notdef
if (pid < 0 && errno != ECHILD)
syslog(LOG_WARNING, "waitpid: %s", strerror(errno));
#endif
}
int
main(int argc, char *argv[])
{
struct portal_args args;
struct sockaddr_un un;
char *conf;
char mountpt[MAXPATHLEN];
int mntflags = 0;
char tag[32];
mode_t um;
qelem q;
int rc;
int so;
int error = 0;
/*
* Crack command line args
*/
int ch;
while ((ch = getopt(argc, argv, "o:")) != -1) {
switch (ch) {
case 'o':
getmntopts(optarg, mopts, &mntflags, 0);
break;
default:
error = 1;
break;
}
}
if (optind != (argc - 2))
error = 1;
if (error)
usage();
/*
* Get config file and mount point
*/
conf = argv[optind];
if (conf[0] != '/') {
(void)fprintf(stderr,
"The configuration file must be specified"
"through an absolute file path.\n");
exit(EX_USAGE);
}
/* resolve the mountpoint with realpath(3) */
if (checkpath(argv[optind+1], mountpt) != 0)
err(EX_USAGE, "%s", mountpt);
/*
* Construct the listening socket
*/
un.sun_family = AF_UNIX;
if (sizeof(_PATH_TMPPORTAL) >= sizeof(un.sun_path)) {
errx(EX_SOFTWARE, "portal socket name too long");
}
strcpy(un.sun_path, _PATH_TMPPORTAL);
mktemp(un.sun_path);
un.sun_len = strlen(un.sun_path);
so = socket(AF_UNIX, SOCK_STREAM, 0);
if (so < 0) {
err(EX_OSERR, "socket");
}
um = umask(077);
(void) unlink(un.sun_path);
if (bind(so, (struct sockaddr *) &un, sizeof(un)) < 0)
err(1, NULL);
(void) unlink(un.sun_path);
(void) umask(um);
(void) listen(so, 5);
args.pa_socket = so;
sprintf(tag, "portal:%d", getpid());
args.pa_config = tag;
rc = mount("portalfs", mountpt, mntflags, &args);
if (rc < 0)
err(1, NULL);
/*
* Everything is ready to go - now is a good time to fork
*/
#ifndef DEBUG
daemon(0, 0);
#endif
/*
* Start logging (and change name)
*/
openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON);
q.q_forw = q.q_back = &q;
readcf = 1;
signal(SIGCHLD, sigchld);
signal(SIGHUP, sighup);
/*
* Just loop waiting for new connections and activating them
*/
for (;;) {
struct sockaddr_un un2;
int len2 = sizeof(un2);
int so2;
pid_t pid;
fd_set fdset;
/*
* Check whether we need to re-read the configuration file
*/
if (readcf) {
#ifdef DEBUG
printf ("re-reading configuration file\n");
#endif
readcf = 0;
conf_read(&q, conf);
continue;
}
/*
* Accept a new connection
* Will get EINTR if a signal has arrived, so just
* ignore that error code
*/
FD_ZERO(&fdset);
FD_SET(so, &fdset);
rc = select(so+1, &fdset, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
if (rc < 0) {
if (errno == EINTR)
continue;
syslog(LOG_ERR, "select: %s", strerror(errno));
exit(EX_OSERR);
}
if (rc == 0)
break;
so2 = accept(so, (struct sockaddr *) &un2, &len2);
if (so2 < 0) {
/*
* The unmount function does a shutdown on the socket
* which will generated ECONNABORTED on the accept.
*/
if (errno == ECONNABORTED)
break;
if (errno != EINTR) {
syslog(LOG_ERR, "accept: %s", strerror(errno));
exit(EX_OSERR);
}
continue;
}
/*
* Now fork a new child to deal with the connection
*/
eagain:;
switch (pid = fork()) {
case -1:
if (errno == EAGAIN) {
sleep(1);
goto eagain;
}
syslog(LOG_ERR, "fork: %s", strerror(errno));
break;
case 0:
(void) close(so);
activate(&q, so2);
exit(0);
default:
(void) close(so2);
break;
}
}
syslog(LOG_INFO, "%s unmounted", mountpt);
exit(0);
}
static void
usage(void)
{
(void)fprintf(stderr,
"usage: mount_portalfs [-o options] config mount-point\n");
exit(EX_USAGE);
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/5/93
*
* $FreeBSD$
*/
#include <paths.h>
#define _PATH_TMPPORTAL "/tmp/portalXXXXXXXXXX" /* Scratch socket name */

View File

@ -1,7 +0,0 @@
# @(#)portal.conf 8.1 (Berkeley) 6/5/93
# $FreeBSD$
tcplisten/ tcplisten tcplisten/
tcp/ tcp tcp/
fs/ file fs/
pipe/ pipe pipe/
foo/ exec ./bar bar baz

View File

@ -1,86 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)portald.h 8.1 (Berkeley) 6/5/93
*
* $FreeBSD$
*/
#include <sys/cdefs.h>
#include <sys/ucred.h>
#include <fs/portalfs/portal.h>
/*
* Meta-chars in an RE. Paths in the config file containing
* any of these characters will be matched using regexec, other
* paths will be prefix-matched.
*/
#define RE_CHARS ".|()[]*+?\\^$"
typedef struct qelem qelem;
struct qelem {
qelem *q_forw;
qelem *q_back;
};
typedef struct provider provider;
struct provider {
const char *pr_match;
int (*pr_func)(struct portal_cred *,
char *key, char **v, int so, int *fdp);
};
extern provider providers[];
/*
* Portal providers
*/
extern int portal_exec(struct portal_cred *,
char *key, char **v, int so, int *fdp);
extern int portal_file(struct portal_cred *,
char *key, char **v, int so, int *fdp);
extern int portal_pipe(struct portal_cred *,
char *key, char **v, int so, int *fdp);
extern int portal_tcp(struct portal_cred *,
char *key, char **v, int so, int *fdp);
extern int portal_tcplisten(struct portal_cred *,
char *key, char **v, int so, int *fdp);
/*
* Global functions
*/
extern void activate(qelem *q, int so);
extern char **conf_match(qelem *q, char *key);
extern void conf_read(qelem *q, char *conf);
extern int set_user_credentials(struct portal_cred *user,
struct portal_cred *save_area);
extern int restore_credentials(struct portal_cred *save_area);

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pt_conf.c 8.1 (Berkeley) 6/5/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include "portald.h"
provider providers[] = {
{ "exec", portal_exec },
{ "file", portal_file },
{ "pipe", portal_pipe },
{ "tcp", portal_tcp },
{ "tcplisten", portal_tcplisten },
{ 0, 0 }
};

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pt_exec.c 8.1 (Berkeley) 6/5/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include "portald.h"
int portal_exec(struct portal_cred *pcr __unused, char *key __unused,
char **v __unused, int so __unused, int *fdp __unused)
{
return (ENOEXEC);
}

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pt_file.c 8.3 (Berkeley) 7/3/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include "portald.h"
int portal_file(struct portal_cred *pcr,
char *key, char **v, int so __unused, int *fdp)
{
int fd;
char pbuf[MAXPATHLEN];
int error;
struct portal_cred save_area;
pbuf[0] = '/';
strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
#ifdef DEBUG
printf("path = %s, uid = %d, gid = %d\n", pbuf, pcr->pcr_uid, pcr->pcr_groups[0]);
printf ("fflag = %x, oflag = %x\n", pcr->pcr_flag, (pcr->pcr_flag)-1);
#endif
if (set_user_credentials(pcr, &save_area) < 0)
return (errno);
/* dmb convert kernel flags to oflags, see <fcntl.h> */
fd = open(pbuf, (pcr->pcr_flag)-1, 0777);
if (fd < 0)
error = errno;
else
error = 0;
if (restore_credentials(&save_area) < 0) {
error = errno;
if (fd >= 0) {
(void) close(fd);
fd = -1;
}
}
if (error == 0)
*fdp = fd;
#ifdef DEBUG
fprintf(stderr, "pt_file returns *fdp = %d, error = %d\n", *fdp, error);
#endif
return (error);
}

View File

@ -1,229 +0,0 @@
/*-
* Copyright (C) 2005 Diomidis Spinellis. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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 AUTHOR 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 AUTHOR 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.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include "portald.h"
/* Usage conventions for the pipe's endpoints. */
#define READ_END 0
#define WRITE_END 1
static int errlog(void);
static int parse_argv(char *args, char **argv);
int portal_pipe(struct portal_cred *pcr, char *key, char **v,
int kso __unused, int *fdp)
{
int fd[2]; /* Pipe endpoints. */
int caller_end; /* The pipe end we will use. */
int process_end; /* The pipe end the spawned process will use. */
int redirect_fd; /* The fd to redirect on the spawned process. */
char pbuf[MAXPATHLEN];
int error = 0;
int i;
char **argv;
int argc;
struct portal_cred save_area;
/* Validate open mode, and assign roles. */
if ((pcr->pcr_flag & FWRITE) && (pcr->pcr_flag & FREAD))
/* Don't allow both on a single fd. */
return (EINVAL);
else if (pcr->pcr_flag & FREAD) {
/*
* The caller reads from the pipe,
* the spawned process writes to it.
*/
caller_end = READ_END;
process_end = WRITE_END;
redirect_fd = STDOUT_FILENO;
} else if (pcr->pcr_flag & FWRITE) {
/*
* The caller writes to the pipe,
* the spawned process reads from it.
*/
caller_end = WRITE_END;
process_end = READ_END;
redirect_fd = STDIN_FILENO;
} else
return (EINVAL);
/* Get and check command line. */
pbuf[0] = '/';
strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
argc = parse_argv(pbuf, NULL);
if (argc == 0)
return (ENOENT);
/* Swap privileges. */
if (set_user_credentials(pcr, &save_area) < 0)
return (errno);
/* Redirect and spawn the specified process. */
fd[READ_END] = fd[WRITE_END] = -1;
if (pipe(fd) < 0) {
error = errno;
goto done;
}
switch (fork()) {
case -1: /* Error */
error = errno;
break;
default: /* Parent */
(void)close(fd[process_end]);
break;
case 0: /* Child */
argv = (char **)malloc((argc + 1) * sizeof(char *));
if (argv == 0) {
syslog(LOG_ALERT,
"malloc: failed to get space for %d pointers",
argc + 1);
exit(EXIT_FAILURE);
}
parse_argv(pbuf, argv);
if (dup2(fd[process_end], redirect_fd) < 0) {
syslog(LOG_ERR, "dup2: %m");
exit(EXIT_FAILURE);
}
(void)close(fd[caller_end]);
(void)close(fd[process_end]);
if (errlog() < 0) {
syslog(LOG_ERR, "errlog: %m");
exit(EXIT_FAILURE);
}
if (execv(argv[0], argv) < 0) {
syslog(LOG_ERR, "execv(%s): %m", argv[0]);
exit(EXIT_FAILURE);
}
/* NOTREACHED */
}
done:
/* Re-establish our privileges. */
if (restore_credentials(&save_area) < 0)
error = errno;
/* Set return fd value. */
if (error == 0)
*fdp = fd[caller_end];
else {
for (i = 0; i < 2; i++)
if (fd[i] >= 0)
(void)close(fd[i]);
*fdp = -1;
}
return (error);
}
/*
* Redirect stderr to the system log.
* Return 0 if ok.
* Return -1 with errno set on error.
*/
static int
errlog(void)
{
int fd[2];
char buff[1024];
FILE *f;
int ret = 0;
if (pipe(fd) < 0)
return (-1);
switch (fork()) {
case -1: /* Error */
return (-1);
case 0: /* Child */
if ((f = fdopen(fd[READ_END], "r")) == NULL) {
syslog(LOG_ERR, "fdopen: %m");
exit(EXIT_FAILURE);
}
(void)close(fd[WRITE_END]);
while (fgets(buff, sizeof(buff), f) != NULL)
syslog(LOG_ERR, "exec: %s", buff);
exit(EXIT_SUCCESS);
/* NOTREACHED */
default: /* Parent */
if (dup2(fd[WRITE_END], STDERR_FILENO) < 0)
ret = -1;
(void)close(fd[READ_END]);
(void)close(fd[WRITE_END]);
break;
}
return (ret);
}
/*
* Parse the args string as a space-separated argument vector.
* If argv is not NULL, split the string into its constituent
* components, and set argv to point to the beginning of each
* string component; NULL-terminating argv.
* Return the number of string components.
*/
static int
parse_argv(char *args, char **argv)
{
int count = 0;
char *p;
enum {WORD, SPACE} state = SPACE;
for (p = args; *p; p++)
switch (state) {
case WORD:
if (isspace(*p)) {
if (argv)
*p = '\0';
state = SPACE;
}
break;
case SPACE:
if (!isspace(*p)) {
if (argv)
argv[count] = p;
count++;
state = WORD;
}
}
if (argv)
argv[count] = NULL;
return (count);
}

View File

@ -1,157 +0,0 @@
/*
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pt_tcp.c 8.5 (Berkeley) 4/28/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "portald.h"
/*
* Key will be tcp/host/port[/"priv"]
* Create a TCP socket connected to the
* requested host and port.
* Some trailing suffix values have special meanings.
* An unrecognized suffix is an error.
*/
int portal_tcp(struct portal_cred *pcr, char *key, char **v,
int kso __unused, int *fdp)
{
char host[MAXHOSTNAMELEN];
char port[MAXHOSTNAMELEN];
char *p = key + (v[1] ? strlen(v[1]) : 0);
char *q;
struct hostent *hp;
struct servent *sp;
struct in_addr **ipp;
struct in_addr *ip[2];
struct in_addr ina;
u_short s_port;
int priv = 0;
struct sockaddr_in sain;
q = strchr(p, '/');
if (q == 0 || q - p >= (int)sizeof(host))
return (EINVAL);
*q = '\0';
strcpy(host, p);
p = q + 1;
q = strchr(p, '/');
if (q)
*q = '\0';
if (strlen(p) >= sizeof(port))
return (EINVAL);
strcpy(port, p);
if (q) {
p = q + 1;
if (strcmp(p, "priv") == 0) {
if (pcr->pcr_uid == 0)
priv = 1;
else
return (EPERM);
} else {
return (EINVAL);
}
}
hp = gethostbyname(host);
if (hp != 0) {
ipp = (struct in_addr **) hp->h_addr_list;
} else {
ina.s_addr = inet_addr(host);
if (ina.s_addr == INADDR_NONE)
return (EINVAL);
ip[0] = &ina;
ip[1] = 0;
ipp = ip;
}
#ifdef DEBUG
printf ("inet address for %s is %s\n", host, inet_ntoa(*ipp[0]));
#endif
sp = getservbyname(port, "tcp");
if (sp != NULL) {
s_port = (u_short)sp->s_port;
} else {
s_port = strtoul(port, &p, 0);
if (s_port == 0 || *p != '\0')
return (EINVAL);
s_port = htons(s_port);
}
#ifdef DEBUG
printf ("port number for %s is %d\n", port, (int)ntohs(s_port));
#endif
memset(&sain, 0, sizeof(sain));
sain.sin_len = sizeof(sain);
sain.sin_family = AF_INET;
sain.sin_port = s_port;
while (ipp[0]) {
int so;
if (priv)
so = rresvport((int *) 0);
else
so = socket(AF_INET, SOCK_STREAM, 0);
if (so < 0) {
syslog(LOG_ERR, "socket: %m");
return (errno);
}
sain.sin_addr = *ipp[0];
if (connect(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
*fdp = so;
return (0);
}
(void) close(so);
ipp++;
}
return (errno);
}

View File

@ -1,201 +0,0 @@
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
* Jan-Simon Pendry.
*
* Modified by Duncan Barclay.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pt_tcp.c 8.3 (Berkeley) 3/27/94
*
* pt_tcp.c,v 1.1.1.1 1994/05/26 06:34:34 rgrimes Exp
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/syslog.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "portald.h"
/*
* Key will be tcplisten/host/port
*
* Create a TCP socket bound to the requested host and port.
* If the host is "ANY" the receiving address will be set to INADDR_ANY.
* If the port is 0 the caller must find out the returned port number
* using a call to getsockname.
*
* XXX! The owner of the socket will be root rather then the user. This
* may cause remote auth (identd) to return unexpected results.
*
*/
int portal_tcplisten(struct portal_cred *pcr, char *key, char **v,
int kso __unused, int *fdp)
{
char host[MAXHOSTNAMELEN];
char port[MAXHOSTNAMELEN];
char *p = key + (v[1] ? strlen(v[1]) : 0);
char *q;
struct hostent *hp;
struct servent *sp;
struct in_addr **ipp = NULL;
struct in_addr *ip[2];
struct in_addr ina;
u_short s_port;
int any = 0;
struct sockaddr_in sain;
q = strchr(p, '/');
if (q == 0 || q - p >= (int)sizeof(host))
return (EINVAL);
*q = '\0';
snprintf(host, sizeof(host), "%s", p);
p = q + 1;
q = strchr(p, '/');
if (q)
*q = '\0';
if (strlen(p) >= sizeof(port))
return (EINVAL);
snprintf(port, sizeof(port), "%s", p);
if (strcmp(host, "ANY") == 0) {
any = 1;
} else {
hp = gethostbyname(host);
if (hp != 0) {
ipp = (struct in_addr **) hp->h_addr_list;
} else {
ina.s_addr = inet_addr(host);
if (ina.s_addr == INADDR_NONE)
return (EINVAL);
ip[0] = &ina;
ip[1] = 0;
ipp = ip;
}
}
#ifdef DEBUG
if (any)
printf("INADDR_ANY to be used for hostname\n");
else
printf("inet address for %s is %s\n", host, inet_ntoa(*ipp[0]));
#endif
sp = getservbyname(port, "tcp");
if (sp != NULL) {
s_port = (u_short) sp->s_port;
} else {
s_port = strtoul(port, &p, 0);
if (*p != '\0')
return (EINVAL);
s_port = htons(s_port);
}
if ((ntohs(s_port) != 0) &&
(ntohs(s_port) <= IPPORT_RESERVED) &&
(pcr->pcr_uid != 0))
return (EPERM);
#ifdef DEBUG
printf("port number for %s is %d\n", port, ntohs(s_port));
#endif
memset(&sain, 0, sizeof(sain));
sain.sin_len = sizeof(sain);
sain.sin_family = AF_INET;
sain.sin_port = s_port;
if (any) {
int so;
int sock;
so = socket(AF_INET, SOCK_STREAM, 0);
if (so < 0) {
syslog(LOG_ERR, "socket: %m");
return (errno);
}
sain.sin_addr.s_addr = INADDR_ANY;
if (bind(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
listen(so, 1);
if ((sock = accept(so, (struct sockaddr *)0, (int *)0)) == -1) {
syslog(LOG_ERR, "accept: %m");
(void) close(so);
return (errno);
}
*fdp = sock;
(void) close(so);
return (0);
}
syslog(LOG_ERR, "bind: %m");
(void) close(so);
return (errno);
}
while (ipp[0]) {
int so;
int sock;
so = socket(AF_INET, SOCK_STREAM, 0);
if (so < 0) {
syslog(LOG_ERR, "socket: %m");
return (errno);
}
sain.sin_addr = *ipp[0];
if (bind(so, (struct sockaddr *) &sain, sizeof(sain)) == 0) {
listen(so, 1);
if ((sock = accept(so, (struct sockaddr *)0, (int *)0)) == -1) {
syslog(LOG_ERR, "accept: %m");
(void) close(so);
return (errno);
}
*fdp = sock;
(void) close(so);
return (0);
}
(void) close(so);
ipp++;
}
syslog(LOG_ERR, "bind: %m");
return (errno);
}