X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/1c15e88899094343f75aeba04122cd96a96b428e..af359dea2e5ab3e937b62107ecd6a51d78189ed7:/usr/src/usr.sbin/amd/amq/amq.c diff --git a/usr/src/usr.sbin/amd/amq/amq.c b/usr/src/usr.sbin/amd/amq/amq.c index 77c132979b..02cc97bd5e 100644 --- a/usr/src/usr.sbin/amd/amq/amq.c +++ b/usr/src/usr.sbin/amd/amq/amq.c @@ -1,6 +1,4 @@ /* - * $Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $ - * * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -9,19 +7,38 @@ * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * - * Redistribution and use in source and binary forms are permitted provided - * that: (1) source distributions retain this entire copyright notice and - * comment, and (2) distributions including binaries display the following - * acknowledgement: ``This product includes software developed by the - * University of California, Berkeley and its contributors'' in the - * documentation or other materials provided with the distribution and in - * all advertising materials mentioning features or use of this software. - * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * 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. + * + * @(#)amq.c 5.3 (Berkeley) 5/12/91 + * + * $Id: amq.c,v 5.2.1.5 91/05/07 22:18:45 jsp Alpha $ + * */ /* @@ -37,8 +54,8 @@ char copyright[] = "\ #endif /* not lint */ #ifndef lint -static char rcsid[] = "$Id: amq.c,v 5.2 90/06/23 22:20:07 jsp Rel $"; -static char sccsid[] = "@(#)amq.c 5.1 (Berkeley) 6/29/90"; +static char rcsid[] = "$Id: amq.c,v 5.2.1.5 91/05/07 22:18:45 jsp Alpha $"; +static char sccsid[] = "@(#)amq.c 5.3 (Berkeley) 5/12/91"; #endif /* not lint */ #include "am.h" @@ -47,14 +64,18 @@ static char sccsid[] = "@(#)amq.c 5.1 (Berkeley) 6/29/90"; #include #include +static int privsock(); + char *progname; static int flush_flag; static int minfo_flag; static int unmount_flag; static int stats_flag; +static int getvers_flag; static char *debug_opts; static char *logfile; -static char *xlog_opt; +static char *mount_map; +static char *xlog_optstr; static char localhost[] = "localhost"; static char *def_server = localhost; @@ -88,7 +109,7 @@ int *twid; } break; case Full: { - struct tm *tp = localtime(&mt->mt_mounttime); + struct tm *tp = localtime((time_t *) &mt->mt_mounttime); printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ @@ -111,7 +132,7 @@ printf("%-*.*s %-*.*s %-*.*s %s\n\t%-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d } break; case Stats: { - struct tm *tp = localtime(&mt->mt_mounttime); + struct tm *tp = localtime((time_t *) &mt->mt_mounttime); printf("%-*.*s %-5d %-7d %-6d %-7d %-7d %-6d %02d/%02d/%02d %02d:%02d:%02d\n", *dwid, *dwid, *mt->mt_directory ? mt->mt_directory : "/", /* XXX */ @@ -261,7 +282,10 @@ char *argv[]; int errs = 0; char *server; struct sockaddr_in server_addr; - int s = RPC_ANYSOCK; + + /* In order to pass the Amd security check, we must use a priv port. */ + int s; + CLIENT *clnt; struct hostent *hp; int nodefault = 0; @@ -282,10 +306,11 @@ char *argv[]; /* * Parse arguments */ - while ((opt_ch = getopt(argc, argv, "fh:l:msux:D:")) != EOF) + while ((opt_ch = getopt(argc, argv, "fh:l:msuvx:D:M:")) != EOF) switch (opt_ch) { case 'f': flush_flag = 1; + nodefault = 1; break; case 'h': @@ -304,14 +329,21 @@ char *argv[]; case 's': stats_flag = 1; + nodefault = 1; break; case 'u': unmount_flag = 1; + nodefault = 1; + break; + + case 'v': + getvers_flag = 1; + nodefault = 1; break; case 'x': - xlog_opt = optarg; + xlog_optstr = optarg; nodefault = 1; break; @@ -320,16 +352,26 @@ char *argv[]; nodefault = 1; break; + case 'M': + mount_map = optarg; + nodefault = 1; + break; + default: errs = 1; break; } + if (optind == argc) { + if (unmount_flag) + errs = 1; + } + if (errs) { show_usage: fprintf(stderr, "\ -Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ -\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts]\n", progname); +Usage: %s [-h host] [[-f] [-m] [-v] [-s]] | [[-u] directory ...]] |\n\ +\t[-l logfile|\"syslog\"] [-x log_flags] [-D dbg_opts] [-M mapent]\n", progname); exit(1); } @@ -346,17 +388,24 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ /* * Get address of server */ - if ((hp = gethostbyname(server)) == 0) { + if ((hp = gethostbyname(server)) == 0 && strcmp(server, localhost) != 0) { fprintf(stderr, "%s: Can't get address of %s\n", progname, server); exit(1); } bzero(&server_addr, sizeof server_addr); server_addr.sin_family = AF_INET; - server_addr.sin_addr = *(struct in_addr *) hp->h_addr; + if (hp) { + bcopy((voidp) hp->h_addr, (voidp) &server_addr.sin_addr, + sizeof(server_addr.sin_addr)); + } else { + /* fake "localhost" */ + server_addr.sin_addr.s_addr = htonl(0x7f000001); + } /* * Create RPC endpoint */ + s = privsock(); clnt = clntudp_create(&server_addr, AMQ_PROGRAM, AMQ_VERSION, TIMEOUT, &s); if (clnt == 0) { fprintf(stderr, "%s: ", progname); @@ -385,14 +434,14 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ /* * Control logging */ - if (xlog_opt) { + if (xlog_optstr) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_XLOG; - opt.as_str = xlog_opt; + opt.as_str = xlog_optstr; rc = amqproc_setopt_1(&opt, clnt); if (!rc || *rc) { - fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_opt); + fprintf(stderr, "%s: setting log level to \"%s\" failed\n", progname, xlog_optstr); errs = 1; } } @@ -415,7 +464,7 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ /* * Flush map cache */ - if (logfile) { + if (flush_flag) { int *rc; amq_setopt opt; opt.as_opt = AMOPT_FLUSHMAPC; @@ -444,6 +493,38 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ } } + /* + * Mount map + */ + if (mount_map) { + int *rc; + do { + rc = amqproc_mount_1(&mount_map, clnt); + } while (rc && *rc < 0); + if (!rc || *rc > 0) { + if (rc) + errno = *rc; + else + errno = ETIMEDOUT; + fprintf(stderr, "%s: could not start new ", progname); + perror("autmount point"); + } + } + + /* + * Get Version + */ + if (getvers_flag) { + amq_string *spp = amqproc_getvers_1((voidp) 0, clnt); + if (spp && *spp) { + printf("%s.\n", *spp); + free(*spp); + } else { + fprintf(stderr, "%s: failed to get version information\n", progname); + errs = 1; + } + } + /* * Apply required operation to all remaining arguments */ @@ -466,12 +547,6 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ int mwid = 0, dwid = 0, twid = 0; show_mt(mt, Calc, &mwid, &dwid, &twid); mwid++; dwid++, twid++; -#ifdef notdef - printf("\t%s\n%-*.*s %-*.*s %-*.*s %s\n", - "Uid Getattr Lookup RdDir RdLnk Statfs Mounted@", - dwid, dwid, "What", twid, twid, "Type", mwid, mwid, "Info", "Where"); - show_mt(mt, Full, &mwid, &dwid, &twid); -#endif /* notdef */ printf("%-*.*s Uid Getattr Lookup RdDir RdLnk Statfs Mounted@\n", dwid, dwid, "What"); show_mt(mt, Stats, &mwid, &dwid, &twid); @@ -522,6 +597,54 @@ Usage: %s [-h host] [[-f] [-m] | | [-s] | [[-u] directory ...]] |\n\ exit(errs); } +/* + * udpresport creates a datagram socket and attempts to bind it to a + * secure port. + * returns: The bound socket, or -1 to indicate an error. + */ +static int udpresport() +{ + int alport; + struct sockaddr_in addr; + int sock; + + /* Use internet address family */ + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + return -1; + for (alport = IPPORT_RESERVED-1; alport > IPPORT_RESERVED/2 + 1; alport--) { + addr.sin_port = htons((u_short)alport); + if (bind(sock, (struct sockaddr *)&addr, sizeof (addr)) >= 0) + return sock; + if (errno != EADDRINUSE) { + close(sock); + return -1; + } + } + close(sock); + errno = EAGAIN; + return -1; +} + +/* + * Privsock() calls udpresport() to attempt to bind a socket to a secure + * port. If udpresport() fails, privsock returns a magic socket number which + * indicates to RPC that it should make its own socket. + * returns: A privileged socket # or RPC_ANYSOCK. + */ +static int privsock() +{ + int sock = udpresport(); + + if (sock < 0) { + errno = 0; + /* Couldn't get a secure port, let RPC make an insecure one */ + sock = RPC_ANYSOCK; + } + return sock; +} + #ifdef DEBUG xfree(f, l, p) char *f, *l;