Index: head/sbin/mount_portal/activate.c =================================================================== --- head/sbin/mount_portal/activate.c (revision 37428) +++ head/sbin/mount_portal/activate.c (revision 37429) @@ -1,215 +1,214 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: activate.c,v 1.3 1997/02/22 14:32:53 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include -#include +#include +#include #include #include #include -#include #include #include #include "portald.h" /* * Scan the providers list and call the * appropriate function. */ static int activate_argv(pcr, key, v, so, fdp) 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(so, pcr, key, klen) 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 <= sizeof(*pcr)) return (EINVAL); n -= sizeof(*pcr); key[n] = '\0'; return (0); } static void send_reply(so, fd, error) int so; int fd; int error; { int n; struct iovec iov; struct msghdr msg; struct { struct cmsghdr cmsg; int fd; } 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.fd = fd; ctl.cmsg.cmsg_len = sizeof(ctl); ctl.cmsg.cmsg_level = SOL_SOCKET; ctl.cmsg.cmsg_type = SCM_RIGHTS; msg.msg_control = (caddr_t) &ctl; msg.msg_controllen = ctl.cmsg.cmsg_len; } /* * Send to kernel... */ if ((n = sendmsg(so, &msg, MSG_EOR)) < 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, 2) < 0) syslog(LOG_ERR, "shutdown: %s", strerror(errno)); #endif /* * Throw away the open file descriptor */ (void) close(fd); } void activate(q, so) 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); } Index: head/sbin/mount_portal/conf.c =================================================================== --- head/sbin/mount_portal/conf.c (revision 37428) +++ head/sbin/mount_portal/conf.c (revision 37429) @@ -1,337 +1,340 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + +#include +#include #include #include -#include #include -#include -#include +#include #include #include #include #include #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(elem, pred) qelem *elem, *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(elem) 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(siz) 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(p0, q0) 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(cline, lno) 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:%s: 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(p) 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(q0, xq) 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(q0, fp) 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(q, conf) 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(q0, key) 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); } Index: head/sbin/mount_portal/mount_portal.8 =================================================================== --- head/sbin/mount_portal/mount_portal.8 (revision 37428) +++ head/sbin/mount_portal/mount_portal.8 (revision 37429) @@ -1,137 +1,137 @@ .\" .\" 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 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 +.\" $Id$ .\" -.\" .Dd March 27, 1994 .Dt MOUNT_PORTAL 8 .Os BSD 4.4 .Sh NAME .Nm mount_portal .Nd mount the portal daemon .Sh SYNOPSIS .Nm mount_portal .Op Fl o Ar options .Ar /etc/portal.conf .Ar mount_point .Sh DESCRIPTION The -.Nm mount_portal +.Nm command attaches an instance of the portal daemon to the global filesystem namespace. The conventional mount point is .Pa /p . -.PA /dev . +.\" .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 filesystem 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 Currently, two sub-namespaces are implemented: .Pa tcp and .Pa fs . The .Pa tcp namespace takes a hostname and a port (slash separated) and creates an open TCP/IP connection. 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. .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 tcp/ tcp tcp/ fs/ file fs/ .Ed .Sh FILES .Bl -tag -width /p/* -compact .It Pa /p/* .El .Sh SEE ALSO .Xr mount 2 , .Xr unmount 2 , .Xr fstab 5 , .Xr mount 8 .Sh CAVEATS This filesystem may not be NFS-exported. .Sh HISTORY The -.Nm mount_portal +.Nm utility first appeared in .Bx 4.4 . Index: head/sbin/mount_portal/mount_portal.c =================================================================== --- head/sbin/mount_portal/mount_portal.c (revision 37428) +++ head/sbin/mount_portal/mount_portal.c (revision 37429) @@ -1,292 +1,291 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 char copyright[] = "@(#) Copyright (c) 1992, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/* +#if 0 static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95"; -*/ +#endif static const char rcsid[] = - "$Id: mount_portal.c,v 1.11 1997/03/24 05:53:12 imp Exp $"; + "$Id$"; #endif /* not lint */ #include #include -#include #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include "mntopts.h" #include "pathnames.h" #include "portald.h" struct mntopt mopts[] = { MOPT_STDOPTS, { NULL } }; static void usage __P((void)) __dead2; static sig_atomic_t readcf; /* Set when SIGHUP received */ static void sighup(sig) int sig; { readcf ++; } static void sigchld(sig) int sig; { 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(argc, argv) int argc; char *argv[]; { struct portal_args args; struct sockaddr_un un; char *conf; char *mountpt; int mntflags = 0; char tag[32]; struct vfsconf vfc; 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]; mountpt = argv[optind+1]; /* * 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; error = getvfsbyname("portal", &vfc); if (error && vfsisloadable("portal")) { if (vfsload("portal")) err(EX_OSERR, "vfsload(portal)"); endvfsent(); error = getvfsbyname("portal", &vfc); } if (error) errx(EX_OSERR, "portal filesystem is not available"); rc = mount(vfc.vfc_name, mountpt, mntflags, &args); if (rc < 0) err(1, NULL); /* * Everything is ready to go - now is a good time to fork */ daemon(0, 0); /* * 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; int rc; /* * 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)fprintf(stderr, "usage: mount_portal [-o options] config mount-point\n"); exit(EX_USAGE); } Index: head/sbin/mount_portal/pt_conf.c =================================================================== --- head/sbin/mount_portal/pt_conf.c (revision 37428) +++ head/sbin/mount_portal/pt_conf.c (revision 37429) @@ -1,51 +1,54 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ + +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ #include #include #include "portald.h" provider providers[] = { { "exec", portal_exec }, { "file", portal_file }, { "tcp", portal_tcp }, { 0, 0 } }; Index: head/sbin/mount_portal/pt_exec.c =================================================================== --- head/sbin/mount_portal/pt_exec.c (revision 37428) +++ head/sbin/mount_portal/pt_exec.c (revision 37429) @@ -1,61 +1,60 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include #include -#include #include "portald.h" int portal_exec(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { return (ENOEXEC); } Index: head/sbin/mount_portal/pt_file.c =================================================================== --- head/sbin/mount_portal/pt_file.c (revision 37428) +++ head/sbin/mount_portal/pt_file.c (revision 37429) @@ -1,108 +1,109 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_file.c,v 1.5 1997/02/22 14:32:56 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include +#include +#include #include #include #include #include "portald.h" int portal_file(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { int fd; char pbuf[MAXPATHLEN]; int error; gid_t gidset[NGROUPS]; int i; 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 for (i = 0; i < pcr->pcr_ngroups; i++) gidset[i] = pcr->pcr_groups[i]; if (setgroups(pcr->pcr_ngroups, gidset) < 0) return (errno); if (seteuid(pcr->pcr_uid) < 0) return (errno); /* dmb convert kernel flags to oflags, see */ fd = open(pbuf, (pcr->pcr_flag)-1, 0777); if (fd < 0) error = errno; else error = 0; if (seteuid((uid_t) 0) < 0) { /* XXX - should reset gidset too */ error = errno; syslog(LOG_ERR, "setcred: %s", strerror(error)); 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); } Index: head/sbin/mount_portal/pt_tcp.c =================================================================== --- head/sbin/mount_portal/pt_tcp.c (revision 37428) +++ head/sbin/mount_portal/pt_tcp.c (revision 37429) @@ -1,165 +1,167 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_tcp.c,v 1.5 1997/03/11 12:35:00 peter Exp $ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include +#include #include +#include #include #include #include #include #include #include #include #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 unrecognised suffix is an error. + * An unrecognized suffix is an error. */ int portal_tcp(pcr, key, v, kso, fdp) struct portal_cred *pcr; char *key; char **v; int kso; 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 >= 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, 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); } Index: head/sbin/mount_portalfs/activate.c =================================================================== --- head/sbin/mount_portalfs/activate.c (revision 37428) +++ head/sbin/mount_portalfs/activate.c (revision 37429) @@ -1,215 +1,214 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: activate.c,v 1.3 1997/02/22 14:32:53 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include -#include +#include +#include #include #include #include -#include #include #include #include "portald.h" /* * Scan the providers list and call the * appropriate function. */ static int activate_argv(pcr, key, v, so, fdp) 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(so, pcr, key, klen) 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 <= sizeof(*pcr)) return (EINVAL); n -= sizeof(*pcr); key[n] = '\0'; return (0); } static void send_reply(so, fd, error) int so; int fd; int error; { int n; struct iovec iov; struct msghdr msg; struct { struct cmsghdr cmsg; int fd; } 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.fd = fd; ctl.cmsg.cmsg_len = sizeof(ctl); ctl.cmsg.cmsg_level = SOL_SOCKET; ctl.cmsg.cmsg_type = SCM_RIGHTS; msg.msg_control = (caddr_t) &ctl; msg.msg_controllen = ctl.cmsg.cmsg_len; } /* * Send to kernel... */ if ((n = sendmsg(so, &msg, MSG_EOR)) < 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, 2) < 0) syslog(LOG_ERR, "shutdown: %s", strerror(errno)); #endif /* * Throw away the open file descriptor */ (void) close(fd); } void activate(q, so) 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); } Index: head/sbin/mount_portalfs/conf.c =================================================================== --- head/sbin/mount_portalfs/conf.c (revision 37428) +++ head/sbin/mount_portalfs/conf.c (revision 37429) @@ -1,337 +1,340 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + +#include +#include #include #include -#include #include -#include -#include +#include #include #include #include #include #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(elem, pred) qelem *elem, *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(elem) 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(siz) 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(p0, q0) 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(cline, lno) 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:%s: 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(p) 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(q0, xq) 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(q0, fp) 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(q, conf) 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(q0, key) 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); } Index: head/sbin/mount_portalfs/mount_portalfs.8 =================================================================== --- head/sbin/mount_portalfs/mount_portalfs.8 (revision 37428) +++ head/sbin/mount_portalfs/mount_portalfs.8 (revision 37429) @@ -1,137 +1,137 @@ .\" .\" 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 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 +.\" $Id$ .\" -.\" .Dd March 27, 1994 .Dt MOUNT_PORTAL 8 .Os BSD 4.4 .Sh NAME .Nm mount_portal .Nd mount the portal daemon .Sh SYNOPSIS .Nm mount_portal .Op Fl o Ar options .Ar /etc/portal.conf .Ar mount_point .Sh DESCRIPTION The -.Nm mount_portal +.Nm command attaches an instance of the portal daemon to the global filesystem namespace. The conventional mount point is .Pa /p . -.PA /dev . +.\" .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 filesystem 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 Currently, two sub-namespaces are implemented: .Pa tcp and .Pa fs . The .Pa tcp namespace takes a hostname and a port (slash separated) and creates an open TCP/IP connection. 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. .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 tcp/ tcp tcp/ fs/ file fs/ .Ed .Sh FILES .Bl -tag -width /p/* -compact .It Pa /p/* .El .Sh SEE ALSO .Xr mount 2 , .Xr unmount 2 , .Xr fstab 5 , .Xr mount 8 .Sh CAVEATS This filesystem may not be NFS-exported. .Sh HISTORY The -.Nm mount_portal +.Nm utility first appeared in .Bx 4.4 . Index: head/sbin/mount_portalfs/mount_portalfs.c =================================================================== --- head/sbin/mount_portalfs/mount_portalfs.c (revision 37428) +++ head/sbin/mount_portalfs/mount_portalfs.c (revision 37429) @@ -1,292 +1,291 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 char copyright[] = "@(#) Copyright (c) 1992, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/* +#if 0 static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95"; -*/ +#endif static const char rcsid[] = - "$Id: mount_portal.c,v 1.11 1997/03/24 05:53:12 imp Exp $"; + "$Id$"; #endif /* not lint */ #include #include -#include #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include "mntopts.h" #include "pathnames.h" #include "portald.h" struct mntopt mopts[] = { MOPT_STDOPTS, { NULL } }; static void usage __P((void)) __dead2; static sig_atomic_t readcf; /* Set when SIGHUP received */ static void sighup(sig) int sig; { readcf ++; } static void sigchld(sig) int sig; { 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(argc, argv) int argc; char *argv[]; { struct portal_args args; struct sockaddr_un un; char *conf; char *mountpt; int mntflags = 0; char tag[32]; struct vfsconf vfc; 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]; mountpt = argv[optind+1]; /* * 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; error = getvfsbyname("portal", &vfc); if (error && vfsisloadable("portal")) { if (vfsload("portal")) err(EX_OSERR, "vfsload(portal)"); endvfsent(); error = getvfsbyname("portal", &vfc); } if (error) errx(EX_OSERR, "portal filesystem is not available"); rc = mount(vfc.vfc_name, mountpt, mntflags, &args); if (rc < 0) err(1, NULL); /* * Everything is ready to go - now is a good time to fork */ daemon(0, 0); /* * 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; int rc; /* * 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)fprintf(stderr, "usage: mount_portal [-o options] config mount-point\n"); exit(EX_USAGE); } Index: head/sbin/mount_portalfs/pt_conf.c =================================================================== --- head/sbin/mount_portalfs/pt_conf.c (revision 37428) +++ head/sbin/mount_portalfs/pt_conf.c (revision 37429) @@ -1,51 +1,54 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ + +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ #include #include #include "portald.h" provider providers[] = { { "exec", portal_exec }, { "file", portal_file }, { "tcp", portal_tcp }, { 0, 0 } }; Index: head/sbin/mount_portalfs/pt_exec.c =================================================================== --- head/sbin/mount_portalfs/pt_exec.c (revision 37428) +++ head/sbin/mount_portalfs/pt_exec.c (revision 37429) @@ -1,61 +1,60 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include #include -#include #include "portald.h" int portal_exec(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { return (ENOEXEC); } Index: head/sbin/mount_portalfs/pt_file.c =================================================================== --- head/sbin/mount_portalfs/pt_file.c (revision 37428) +++ head/sbin/mount_portalfs/pt_file.c (revision 37429) @@ -1,108 +1,109 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_file.c,v 1.5 1997/02/22 14:32:56 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include +#include +#include #include #include #include #include "portald.h" int portal_file(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { int fd; char pbuf[MAXPATHLEN]; int error; gid_t gidset[NGROUPS]; int i; 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 for (i = 0; i < pcr->pcr_ngroups; i++) gidset[i] = pcr->pcr_groups[i]; if (setgroups(pcr->pcr_ngroups, gidset) < 0) return (errno); if (seteuid(pcr->pcr_uid) < 0) return (errno); /* dmb convert kernel flags to oflags, see */ fd = open(pbuf, (pcr->pcr_flag)-1, 0777); if (fd < 0) error = errno; else error = 0; if (seteuid((uid_t) 0) < 0) { /* XXX - should reset gidset too */ error = errno; syslog(LOG_ERR, "setcred: %s", strerror(error)); 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); } Index: head/sbin/mount_portalfs/pt_tcp.c =================================================================== --- head/sbin/mount_portalfs/pt_tcp.c (revision 37428) +++ head/sbin/mount_portalfs/pt_tcp.c (revision 37429) @@ -1,165 +1,167 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_tcp.c,v 1.5 1997/03/11 12:35:00 peter Exp $ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include +#include #include +#include #include #include #include #include #include #include #include #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 unrecognised suffix is an error. + * An unrecognized suffix is an error. */ int portal_tcp(pcr, key, v, kso, fdp) struct portal_cred *pcr; char *key; char **v; int kso; 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 >= 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, 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); } Index: head/usr.sbin/mount_portalfs/activate.c =================================================================== --- head/usr.sbin/mount_portalfs/activate.c (revision 37428) +++ head/usr.sbin/mount_portalfs/activate.c (revision 37429) @@ -1,215 +1,214 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: activate.c,v 1.3 1997/02/22 14:32:53 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include -#include +#include +#include #include #include #include -#include #include #include #include "portald.h" /* * Scan the providers list and call the * appropriate function. */ static int activate_argv(pcr, key, v, so, fdp) 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(so, pcr, key, klen) 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 <= sizeof(*pcr)) return (EINVAL); n -= sizeof(*pcr); key[n] = '\0'; return (0); } static void send_reply(so, fd, error) int so; int fd; int error; { int n; struct iovec iov; struct msghdr msg; struct { struct cmsghdr cmsg; int fd; } 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.fd = fd; ctl.cmsg.cmsg_len = sizeof(ctl); ctl.cmsg.cmsg_level = SOL_SOCKET; ctl.cmsg.cmsg_type = SCM_RIGHTS; msg.msg_control = (caddr_t) &ctl; msg.msg_controllen = ctl.cmsg.cmsg_len; } /* * Send to kernel... */ if ((n = sendmsg(so, &msg, MSG_EOR)) < 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, 2) < 0) syslog(LOG_ERR, "shutdown: %s", strerror(errno)); #endif /* * Throw away the open file descriptor */ (void) close(fd); } void activate(q, so) 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); } Index: head/usr.sbin/mount_portalfs/conf.c =================================================================== --- head/usr.sbin/mount_portalfs/conf.c (revision 37428) +++ head/usr.sbin/mount_portalfs/conf.c (revision 37429) @@ -1,337 +1,340 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + +#include +#include #include #include -#include #include -#include -#include +#include #include #include #include #include #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(elem, pred) qelem *elem, *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(elem) 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(siz) 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(p0, q0) 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(cline, lno) 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:%s: 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(p) 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(q0, xq) 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(q0, fp) 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(q, conf) 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(q0, key) 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); } Index: head/usr.sbin/mount_portalfs/mount_portalfs.8 =================================================================== --- head/usr.sbin/mount_portalfs/mount_portalfs.8 (revision 37428) +++ head/usr.sbin/mount_portalfs/mount_portalfs.8 (revision 37429) @@ -1,137 +1,137 @@ .\" .\" 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 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 +.\" $Id$ .\" -.\" .Dd March 27, 1994 .Dt MOUNT_PORTAL 8 .Os BSD 4.4 .Sh NAME .Nm mount_portal .Nd mount the portal daemon .Sh SYNOPSIS .Nm mount_portal .Op Fl o Ar options .Ar /etc/portal.conf .Ar mount_point .Sh DESCRIPTION The -.Nm mount_portal +.Nm command attaches an instance of the portal daemon to the global filesystem namespace. The conventional mount point is .Pa /p . -.PA /dev . +.\" .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 filesystem 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 Currently, two sub-namespaces are implemented: .Pa tcp and .Pa fs . The .Pa tcp namespace takes a hostname and a port (slash separated) and creates an open TCP/IP connection. 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. .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 tcp/ tcp tcp/ fs/ file fs/ .Ed .Sh FILES .Bl -tag -width /p/* -compact .It Pa /p/* .El .Sh SEE ALSO .Xr mount 2 , .Xr unmount 2 , .Xr fstab 5 , .Xr mount 8 .Sh CAVEATS This filesystem may not be NFS-exported. .Sh HISTORY The -.Nm mount_portal +.Nm utility first appeared in .Bx 4.4 . Index: head/usr.sbin/mount_portalfs/mount_portalfs.c =================================================================== --- head/usr.sbin/mount_portalfs/mount_portalfs.c (revision 37428) +++ head/usr.sbin/mount_portalfs/mount_portalfs.c (revision 37429) @@ -1,292 +1,291 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 char copyright[] = "@(#) Copyright (c) 1992, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/* +#if 0 static char sccsid[] = "@(#)mount_portal.c 8.6 (Berkeley) 4/26/95"; -*/ +#endif static const char rcsid[] = - "$Id: mount_portal.c,v 1.11 1997/03/24 05:53:12 imp Exp $"; + "$Id$"; #endif /* not lint */ #include #include -#include #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include "mntopts.h" #include "pathnames.h" #include "portald.h" struct mntopt mopts[] = { MOPT_STDOPTS, { NULL } }; static void usage __P((void)) __dead2; static sig_atomic_t readcf; /* Set when SIGHUP received */ static void sighup(sig) int sig; { readcf ++; } static void sigchld(sig) int sig; { 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(argc, argv) int argc; char *argv[]; { struct portal_args args; struct sockaddr_un un; char *conf; char *mountpt; int mntflags = 0; char tag[32]; struct vfsconf vfc; 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]; mountpt = argv[optind+1]; /* * 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; error = getvfsbyname("portal", &vfc); if (error && vfsisloadable("portal")) { if (vfsload("portal")) err(EX_OSERR, "vfsload(portal)"); endvfsent(); error = getvfsbyname("portal", &vfc); } if (error) errx(EX_OSERR, "portal filesystem is not available"); rc = mount(vfc.vfc_name, mountpt, mntflags, &args); if (rc < 0) err(1, NULL); /* * Everything is ready to go - now is a good time to fork */ daemon(0, 0); /* * 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; int rc; /* * 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)fprintf(stderr, "usage: mount_portal [-o options] config mount-point\n"); exit(EX_USAGE); } Index: head/usr.sbin/mount_portalfs/pt_conf.c =================================================================== --- head/usr.sbin/mount_portalfs/pt_conf.c (revision 37428) +++ head/usr.sbin/mount_portalfs/pt_conf.c (revision 37429) @@ -1,51 +1,54 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ + +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ #include #include #include "portald.h" provider providers[] = { { "exec", portal_exec }, { "file", portal_file }, { "tcp", portal_tcp }, { 0, 0 } }; Index: head/usr.sbin/mount_portalfs/pt_exec.c =================================================================== --- head/usr.sbin/mount_portalfs/pt_exec.c (revision 37428) +++ head/usr.sbin/mount_portalfs/pt_exec.c (revision 37429) @@ -1,61 +1,60 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id$ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include #include -#include #include "portald.h" int portal_exec(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { return (ENOEXEC); } Index: head/usr.sbin/mount_portalfs/pt_file.c =================================================================== --- head/usr.sbin/mount_portalfs/pt_file.c (revision 37428) +++ head/usr.sbin/mount_portalfs/pt_file.c (revision 37429) @@ -1,108 +1,109 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_file.c,v 1.5 1997/02/22 14:32:56 peter Exp $ */ -#include -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include #include +#include +#include #include #include #include #include "portald.h" int portal_file(pcr, key, v, so, fdp) struct portal_cred *pcr; char *key; char **v; int so; int *fdp; { int fd; char pbuf[MAXPATHLEN]; int error; gid_t gidset[NGROUPS]; int i; 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 for (i = 0; i < pcr->pcr_ngroups; i++) gidset[i] = pcr->pcr_groups[i]; if (setgroups(pcr->pcr_ngroups, gidset) < 0) return (errno); if (seteuid(pcr->pcr_uid) < 0) return (errno); /* dmb convert kernel flags to oflags, see */ fd = open(pbuf, (pcr->pcr_flag)-1, 0777); if (fd < 0) error = errno; else error = 0; if (seteuid((uid_t) 0) < 0) { /* XXX - should reset gidset too */ error = errno; syslog(LOG_ERR, "setcred: %s", strerror(error)); 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); } Index: head/usr.sbin/mount_portalfs/pt_tcp.c =================================================================== --- head/usr.sbin/mount_portalfs/pt_tcp.c (revision 37428) +++ head/usr.sbin/mount_portalfs/pt_tcp.c (revision 37429) @@ -1,165 +1,167 @@ /* * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 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 - * - * $Id: pt_tcp.c,v 1.5 1997/03/11 12:35:00 peter Exp $ */ -#include -#include -#include +#ifndef lint +static const char rcsid[] = + "$Id$"; +#endif /* not lint */ + #include +#include #include +#include #include #include #include #include #include #include #include #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 unrecognised suffix is an error. + * An unrecognized suffix is an error. */ int portal_tcp(pcr, key, v, kso, fdp) struct portal_cred *pcr; char *key; char **v; int kso; 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 >= 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, 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); }