diff options
Diffstat (limited to 'sbin/mount_portal')
-rw-r--r-- | sbin/mount_portal/Makefile | 15 | ||||
-rw-r--r-- | sbin/mount_portal/activate.c | 215 | ||||
-rw-r--r-- | sbin/mount_portal/conf.c | 329 | ||||
-rw-r--r-- | sbin/mount_portal/mount_portal.8 | 136 | ||||
-rw-r--r-- | sbin/mount_portal/mount_portal.c | 261 | ||||
-rw-r--r-- | sbin/mount_portal/pathnames.h | 44 | ||||
-rw-r--r-- | sbin/mount_portal/portal.conf | 7 | ||||
-rw-r--r-- | sbin/mount_portal/portald.h | 82 | ||||
-rw-r--r-- | sbin/mount_portal/pt_conf.c | 51 | ||||
-rw-r--r-- | sbin/mount_portal/pt_exec.c | 61 | ||||
-rw-r--r-- | sbin/mount_portal/pt_file.c | 106 | ||||
-rw-r--r-- | sbin/mount_portal/pt_tcp.c | 158 |
12 files changed, 1465 insertions, 0 deletions
diff --git a/sbin/mount_portal/Makefile b/sbin/mount_portal/Makefile new file mode 100644 index 0000000..1f17d24 --- /dev/null +++ b/sbin/mount_portal/Makefile @@ -0,0 +1,15 @@ +# @(#)Makefile 8.3 (Berkeley) 3/27/94 + +PROG= mount_portal +SRCS= mount_portal.c activate.c conf.c getmntopts.c pt_conf.c \ + pt_exec.c pt_file.c pt_tcp.c +MAN8= mount_portal.0 + +MOUNT= ${.CURDIR}/../mount +CFLAGS+= -I/sys -I${MOUNT} +.PATH: ${MOUNT} + +DPADD= $(LIBCOMPAT) +LDADD= -lcompat + +.include <bsd.prog.mk> diff --git a/sbin/mount_portal/activate.c b/sbin/mount_portal/activate.c new file mode 100644 index 0000000..3361798 --- /dev/null +++ b/sbin/mount_portal/activate.c @@ -0,0 +1,215 @@ +/* + * 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.2 (Berkeley) 3/27/94 + * + * $Id: activate.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/syslog.h> +#include <sys/uio.h> + +#include "portald.h" + +/* + * Scan the providers list and call the + * appropriate function. + */ +static int activate_argv(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; + + bzero((char *) &msg, 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 + */ + bzero((char *) &msg, 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); +} diff --git a/sbin/mount_portal/conf.c b/sbin/mount_portal/conf.c new file mode 100644 index 0000000..18833b6 --- /dev/null +++ b/sbin/mount_portal/conf.c @@ -0,0 +1,329 @@ +/* + * 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: conf.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <limits.h> +#include <regexp.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/syslog.h> + +#include "portald.h" + +#define ALLOC(ty) (xmalloc(sizeof(ty))) + +typedef struct path path; +struct path { + qelem p_q; /* 2-way linked list */ + int p_lno; /* Line number of this record */ + char *p_args; /* copy of arg string (malloc) */ + char *p_key; /* Pathname to match (also p_argv[0]) */ + regexp *p_re; /* RE to match against pathname (malloc) */ + 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); + +} + +void regerror(s) +const char *s; +{ + syslog(LOG_ERR, "%s:%s: regcomp %s: %s", + conf_file, curp->p_lno, curp->p_key, s); +} + +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)) { + curp = p; /* XXX */ + p->p_re = regcomp(p->p_key); + curp = 0; /* XXX */ + } else { + p->p_re = 0; + } + p->p_lno = lno; + + return (p); +} + +/* + * Free a path structure + */ +static void pfree(p) +path *p; +{ + free(p->p_args); + if (p->p_re) + free((char *) p->p_re); + 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_re) { + if (regexec(p->p_re, key)) + return (p->p_argv+1); + } else { + if (strncmp(p->p_key, key, strlen(p->p_key)) == 0) + return (p->p_argv+1); + } + } + + return (0); +} diff --git a/sbin/mount_portal/mount_portal.8 b/sbin/mount_portal/mount_portal.8 new file mode 100644 index 0000000..0df6531 --- /dev/null +++ b/sbin/mount_portal/mount_portal.8 @@ -0,0 +1,136 @@ +.\" +.\" 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 +.\" +.\" +.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 +command attaches an instance of the portal daemon +to the global filesystem namespace. +The conventional mount point is +.Pa /p . +.PA /dev . +This command is normally executed by +.Xr mount 8 +at boot time. +.Pp +The options are as follows: +.Bl -tag -width indent +.It Fl o +Options are specified with a +.Fl o +flag followed by a comma separated string of options. +See the +.Xr mount 8 +man page for possible options and their meanings. +.El +.Pp +The portal daemon provides an +.Em open +service. +Objects opened under the portal mount point are +dynamically created by the portal daemon according +to rules specified in the named configuration file. +Using this mechanism allows descriptors such as sockets +to be made available in the 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 +utility first appeared in 4.4BSD. diff --git a/sbin/mount_portal/mount_portal.c b/sbin/mount_portal/mount_portal.c new file mode 100644 index 0000000..ae5345d --- /dev/null +++ b/sbin/mount_portal/mount_portal.c @@ -0,0 +1,261 @@ +/* + * 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 +static char sccsid[] = "@(#)mount_portal.c 8.4 (Berkeley) 3/27/94"; +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/syslog.h> +#include <sys/mount.h> + +#include <err.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "mntopts.h" +#include "pathnames.h" +#include "portald.h" + +struct mntopt mopts[] = { + MOPT_STDOPTS, + { NULL } +}; + +static void usage __P((void)); + +static sig_atomic_t readcf; /* Set when SIGHUP received */ + +static void sigchld(sig) +int sig; +{ + pid_t pid; + + while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0) + ; + if (pid < 0) + syslog(LOG_WARNING, "waitpid: %s", strerror(errno)); +} + +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]; + + qelem q; + int rc; + int so; + int error = 0; + + /* + * Crack command line args + */ + int ch; + + while ((ch = getopt(argc, argv, "o:")) != EOF) { + switch (ch) { + case 'o': + getmntopts(optarg, mopts, &mntflags); + 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)) { + fprintf(stderr, "mount_portal: portal socket name too long\n"); + exit(1); + } + 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) { + fprintf(stderr, "mount_portal: socket: %s\n", strerror(errno)); + exit(1); + } + (void) unlink(un.sun_path); + if (bind(so, (struct sockaddr *) &un, sizeof(un)) < 0) + err(1, NULL); + (void) unlink(un.sun_path); + + (void) listen(so, 5); + + args.pa_socket = so; + sprintf(tag, "portal:%d", getpid()); + args.pa_config = tag; + + rc = mount(MOUNT_PORTAL, mountpt, mntflags, &args); + if (rc < 0) + err(1, NULL); + +#ifdef notdef + /* + * Everything is ready to go - now is a good time to fork + */ + daemon(0, 0); +#endif + + /* + * Start logging (and change name) + */ + openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON); + + q.q_forw = q.q_back = &q; + readcf = 1; + + signal(SIGCHLD, sigchld); + + /* + * 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) { + 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_SET(so, &fdset); + rc = select(so+1, &fdset, (void *) 0, (void *) 0, (void *) 0); + if (rc < 0) { + if (errno == EINTR) + continue; + syslog(LOG_ERR, "select: %s", strerror(errno)); + exit(1); + } + 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(1); + } + 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); + break; + 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(1); +} diff --git a/sbin/mount_portal/pathnames.h b/sbin/mount_portal/pathnames.h new file mode 100644 index 0000000..2532114 --- /dev/null +++ b/sbin/mount_portal/pathnames.h @@ -0,0 +1,44 @@ +/* + * 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. + * + * @(#)pathnames.h 8.1 (Berkeley) 6/5/93 + * + * $Id: pathnames.h,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $ + */ + +#include <paths.h> + +#define _PATH_TMPPORTAL "/tmp/portalXXXXXX" /* Scratch socket name */ diff --git a/sbin/mount_portal/portal.conf b/sbin/mount_portal/portal.conf new file mode 100644 index 0000000..5b5a773 --- /dev/null +++ b/sbin/mount_portal/portal.conf @@ -0,0 +1,7 @@ +# @(#)portal.conf 8.1 (Berkeley) 6/5/93 +# $Id: portal.conf,v 1.1 1992/05/27 06:50:13 jsp Exp jsp $ +tcplisten/ tcplisten tcplisten/ +tcp/ tcp tcp/ +fs/ file fs/ +pipe/ pipe +foo/ exec ./bar bar baz diff --git a/sbin/mount_portal/portald.h b/sbin/mount_portal/portald.h new file mode 100644 index 0000000..fbe111b --- /dev/null +++ b/sbin/mount_portal/portald.h @@ -0,0 +1,82 @@ +/* + * 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. + * + * @(#)portald.h 8.1 (Berkeley) 6/5/93 + * + * $Id: portald.h,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ + */ + +#include <sys/cdefs.h> +#include <miscfs/portal/portal.h> + +/* + * Meta-chars in an RE. Paths in the config file containing + * any of these characters will be matched using regexec, other + * paths will be prefix-matched. + */ +#define RE_CHARS ".|()[]*+?\\^$" + +typedef struct qelem qelem; + +struct qelem { + qelem *q_forw; + qelem *q_back; +}; + +typedef struct provider provider; +struct provider { + char *pr_match; + int (*pr_func) __P((struct portal_cred *, + char *key, char **v, int so, int *fdp)); +}; +extern provider providers[]; + +/* + * Portal providers + */ +extern int portal_exec __P((struct portal_cred *, + char *key, char **v, int so, int *fdp)); +extern int portal_file __P((struct portal_cred *, + char *key, char **v, int so, int *fdp)); +extern int portal_tcp __P((struct portal_cred *, + char *key, char **v, int so, int *fdp)); + +/* + * Global functions + */ +extern void activate __P((qelem *q, int so)); +extern char **conf_match __P((qelem *q, char *key)); +extern void conf_read __P((qelem *q, char *conf)); diff --git a/sbin/mount_portal/pt_conf.c b/sbin/mount_portal/pt_conf.c new file mode 100644 index 0000000..d1eba94 --- /dev/null +++ b/sbin/mount_portal/pt_conf.c @@ -0,0 +1,51 @@ +/* + * 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: pt_conf.c,v 1.2 1992/05/27 07:09:27 jsp Exp jsp $ + */ + +#include <sys/types.h> +#include <sys/param.h> +#include "portald.h" + +provider providers[] = { + { "exec", portal_exec }, + { "file", portal_file }, + { "tcp", portal_tcp }, + { 0, 0 } +}; diff --git a/sbin/mount_portal/pt_exec.c b/sbin/mount_portal/pt_exec.c new file mode 100644 index 0000000..06e3382 --- /dev/null +++ b/sbin/mount_portal/pt_exec.c @@ -0,0 +1,61 @@ +/* + * 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: pt_exec.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/syslog.h> + +#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); +} + diff --git a/sbin/mount_portal/pt_file.c b/sbin/mount_portal/pt_file.c new file mode 100644 index 0000000..ace35c0 --- /dev/null +++ b/sbin/mount_portal/pt_file.c @@ -0,0 +1,106 @@ +/* + * 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.2 (Berkeley) 3/27/94 + * + * $Id: pt_file.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/syslog.h> + +#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; + int 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]); +#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); + + fd = open(pbuf, O_RDWR|O_CREAT, 0666); + 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); +} diff --git a/sbin/mount_portal/pt_tcp.c b/sbin/mount_portal/pt_tcp.c new file mode 100644 index 0000000..18a53ce --- /dev/null +++ b/sbin/mount_portal/pt_tcp.c @@ -0,0 +1,158 @@ +/* + * 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_tcp.c 8.3 (Berkeley) 3/27/94 + * + * $Id: pt_tcp.c,v 1.1 1992/05/25 21:43:09 jsp Exp jsp $ + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <strings.h> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +#include "portald.h" + +/* + * Key will be tcp/host/port[/"priv"] + * Create a TCP socket connected to the + * requested host and port. + * Some trailing suffix values have special meanings. + * An unrecognised 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; + int 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; + } + + sp = getservbyname(port, "tcp"); + if (sp != 0) + s_port = sp->s_port; + else { + s_port = atoi(port); + if (s_port == 0) + return (EINVAL); + } + + bzero(&sain, 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); +} |