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:
parent
f51fb78533
commit
4eb0218ace
@ -38,6 +38,13 @@
|
|||||||
# xargs -n1 | sort | uniq -d;
|
# xargs -n1 | sort | uniq -d;
|
||||||
# done
|
# 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
|
# 20130302: CODAFS support removed
|
||||||
OLD_FILES+=usr/share/man/man4/coda.4.gz
|
OLD_FILES+=usr/share/man/man4/coda.4.gz
|
||||||
# 20130302: XFS support removed
|
# 20130302: XFS support removed
|
||||||
|
@ -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.
|
|
@ -1,3 +0,0 @@
|
|||||||
tcp/ tcp tcp/
|
|
||||||
tcplisten/ tcplisten tcplisten/
|
|
||||||
fs/ file fs/
|
|
@ -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 */
|
|
@ -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);
|
|
@ -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,
|
|
||||||
};
|
|
@ -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>
|
|
@ -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>
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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.
|
|
@ -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);
|
|
||||||
}
|
|
@ -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 */
|
|
@ -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
|
|
@ -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);
|
|
@ -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 }
|
|
||||||
};
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user