diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /usr.sbin/rpc.bootparamd |
initial import of NetBSD tree
Diffstat (limited to 'usr.sbin/rpc.bootparamd')
-rw-r--r-- | usr.sbin/rpc.bootparamd/Makefile | 22 | ||||
-rw-r--r-- | usr.sbin/rpc.bootparamd/bootparamd.c | 383 | ||||
-rw-r--r-- | usr.sbin/rpc.bootparamd/bootparams.5 | 78 | ||||
-rw-r--r-- | usr.sbin/rpc.bootparamd/pathnames.h | 10 | ||||
-rw-r--r-- | usr.sbin/rpc.bootparamd/rpc.bootparamd.8 | 62 |
5 files changed, 555 insertions, 0 deletions
diff --git a/usr.sbin/rpc.bootparamd/Makefile b/usr.sbin/rpc.bootparamd/Makefile new file mode 100644 index 00000000000..9a275277b92 --- /dev/null +++ b/usr.sbin/rpc.bootparamd/Makefile @@ -0,0 +1,22 @@ +# $Id: Makefile,v 1.1 1995/10/18 08:48:05 deraadt Exp $ + +CFLAGS+=-DYP + +PROG= rpc.bootparamd +SRCS= bootparamd.c bootparam_prot_svc.c +MAN= bootparams.5 rpc.bootparamd.8 +MLINKS= rpc.bootparamd.8 bootparamd.8 + +DPADD= ${LIBRPCSVC} +LDADD= -lrpcsvc + +bootparam_prot_svc.c: ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x + rm -f bootparam_prot.x + ln -s ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.x . + rm -f bootparam_prot.h + ln -s ${DESTDIR}/usr/include/rpcsvc/bootparam_prot.h . + rpcgen -m -o $@ bootparam_prot.x + +CLEANFILES += bootparam_prot_svc.c bootparam_prot.x bootparam_prot.h + +.include <bsd.prog.mk> diff --git a/usr.sbin/rpc.bootparamd/bootparamd.c b/usr.sbin/rpc.bootparamd/bootparamd.c new file mode 100644 index 00000000000..bd0dabebfcc --- /dev/null +++ b/usr.sbin/rpc.bootparamd/bootparamd.c @@ -0,0 +1,383 @@ +/* + * This code is not copyright, and is placed in the public domain. + * Feel free to use and modify. Please send modifications and/or + * suggestions + bug fixes to Klas Heggemann <klas@nada.kth.se> + * + * Various small changes by Theo de Raadt <deraadt@fsa.ca> + * Parser rewritten (adding YP support) by Roland McGrath <roland@frob.com> + * + * $Id: bootparamd.c,v 1.1 1995/10/18 08:48:05 deraadt Exp $ + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <rpc/rpc.h> +#include <rpcsvc/bootparam_prot.h> +#include <stdio.h> +#include <netdb.h> +#include <ctype.h> +#include <syslog.h> +#include <string.h> +#include "pathnames.h" + +#define MAXLEN 800 + +struct hostent *he; +static char buffer[MAXLEN]; +static char hostname[MAX_MACHINE_NAME]; +static char askname[MAX_MACHINE_NAME]; +static char path[MAX_PATH_LEN]; +static char domain_name[MAX_MACHINE_NAME]; + +extern void bootparamprog_1 __P((struct svc_req *, SVCXPRT *)); + +int _rpcsvcdirty = 0; +int _rpcpmstart = 0; +int debug = 0; +int dolog = 0; +unsigned long route_addr, inet_addr(); +struct sockaddr_in my_addr; +char *progname; +char *bootpfile = _PATH_BOOTPARAMS; + +extern char *optarg; +extern int optind; + +void +usage() +{ + fprintf(stderr, + "usage: rpc.bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n"); +} + + +/* + * ever familiar + */ +int +main(argc, argv) + int argc; + char **argv; +{ + SVCXPRT *transp; + int i, s, pid; + char *rindex(); + struct hostent *he; + struct stat buf; + char *optstring; + char c; + + progname = rindex(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + while ((c = getopt(argc, argv, "dsr:f:")) != EOF) + switch (c) { + case 'd': + debug = 1; + break; + case 'r': + if (isdigit(*optarg)) { + route_addr = inet_addr(optarg); + break; + } + he = gethostbyname(optarg); + if (!he) { + fprintf(stderr, "%s: No such host %s\n", + progname, optarg); + usage(); + exit(1); + } + bcopy(he->h_addr, (char *) &route_addr, sizeof(route_addr)); + break; + case 'f': + bootpfile = optarg; + break; + case 's': + dolog = 1; +#ifndef LOG_DAEMON + openlog(progname, 0, 0); +#else + openlog(progname, 0, LOG_DAEMON); + setlogmask(LOG_UPTO(LOG_NOTICE)); +#endif + break; + default: + usage(); + exit(1); + } + + if (stat(bootpfile, &buf)) { + fprintf(stderr, "%s: ", progname); + perror(bootpfile); + exit(1); + } + if (!route_addr) { + get_myaddress(&my_addr); + bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof(route_addr)); + } + if (!debug) + daemon(); + + (void) pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS); + + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + fprintf(stderr, "cannot create udp service.\n"); + exit(1); + } + if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, + bootparamprog_1, IPPROTO_UDP)) { + fprintf(stderr, + "bootparamd: unable to register BOOTPARAMPROG version %d, udp)\n", + BOOTPARAMVERS); + exit(1); + } + svc_run(); + fprintf(stderr, "svc_run returned\n"); + exit(1); +} + +bp_whoami_res * +bootparamproc_whoami_1_svc(whoami, rqstp) + bp_whoami_arg *whoami; + struct svc_req *rqstp; +{ + long haddr; + static bp_whoami_res res; + + if (debug) + fprintf(stderr, "whoami got question for %d.%d.%d.%d\n", + 255 & whoami->client_address.bp_address_u.ip_addr.net, + 255 & whoami->client_address.bp_address_u.ip_addr.host, + 255 & whoami->client_address.bp_address_u.ip_addr.lh, + 255 & whoami->client_address.bp_address_u.ip_addr.impno); + if (dolog) + syslog(LOG_NOTICE, "whoami got question for %d.%d.%d.%d\n", + 255 & whoami->client_address.bp_address_u.ip_addr.net, + 255 & whoami->client_address.bp_address_u.ip_addr.host, + 255 & whoami->client_address.bp_address_u.ip_addr.lh, + 255 & whoami->client_address.bp_address_u.ip_addr.impno); + + bcopy((char *) &whoami->client_address.bp_address_u.ip_addr, (char *) &haddr, + sizeof(haddr)); + he = gethostbyaddr((char *) &haddr, sizeof(haddr), AF_INET); + if (!he) + goto failed; + + if (debug) + fprintf(stderr, "This is host %s\n", he->h_name); + if (dolog) + syslog(LOG_NOTICE, "This is host %s\n", he->h_name); + + strcpy(askname, he->h_name); + if (!lookup_bootparam(askname, hostname, NULL, NULL, NULL)) { + res.client_name = hostname; + getdomainname(domain_name, MAX_MACHINE_NAME); + res.domain_name = domain_name; + + if (res.router_address.address_type != IP_ADDR_TYPE) { + res.router_address.address_type = IP_ADDR_TYPE; + bcopy(&route_addr, &res.router_address.bp_address_u.ip_addr, 4); + } + if (debug) + fprintf(stderr, "Returning %s %s %d.%d.%d.%d\n", + res.client_name, res.domain_name, + 255 & res.router_address.bp_address_u.ip_addr.net, + 255 & res.router_address.bp_address_u.ip_addr.host, + 255 & res.router_address.bp_address_u.ip_addr.lh, + 255 & res.router_address.bp_address_u.ip_addr.impno); + if (dolog) + syslog(LOG_NOTICE, "Returning %s %s %d.%d.%d.%d\n", + res.client_name, res.domain_name, + 255 & res.router_address.bp_address_u.ip_addr.net, + 255 & res.router_address.bp_address_u.ip_addr.host, + 255 & res.router_address.bp_address_u.ip_addr.lh, + 255 & res.router_address.bp_address_u.ip_addr.impno); + + return (&res); + } +failed: + if (debug) + fprintf(stderr, "whoami failed\n"); + if (dolog) + syslog(LOG_NOTICE, "whoami failed\n"); + return (NULL); +} + + +bp_getfile_res * +bootparamproc_getfile_1_svc(getfile, rqstp) + bp_getfile_arg *getfile; + struct svc_req *rqstp; +{ + char *where, *index(); + static bp_getfile_res res; + int err; + + if (debug) + fprintf(stderr, "getfile got question for \"%s\" and file \"%s\"\n", + getfile->client_name, getfile->file_id); + + if (dolog) + syslog(LOG_NOTICE, "getfile got question for \"%s\" and file \"%s\"\n", + getfile->client_name, getfile->file_id); + + he = NULL; + he = gethostbyname(getfile->client_name); + if (!he) + goto failed; + + strcpy(askname, he->h_name); + err = lookup_bootparam(askname, NULL, getfile->file_id, + &res.server_name, &res.server_path); + if (err == 0) { + he = gethostbyname(res.server_name); + if (!he) + goto failed; + bcopy(he->h_addr, &res.server_address.bp_address_u.ip_addr, 4); + res.server_address.address_type = IP_ADDR_TYPE; + } else if (err == ENOENT && !strcmp(getfile->file_id, "dump")) { + /* Special for dump, answer with null strings. */ + res.server_name[0] = '\0'; + res.server_path[0] = '\0'; + bzero(&res.server_address.bp_address_u.ip_addr, 4); + } else { +failed: + if (debug) + fprintf(stderr, "getfile failed for %s\n", + getfile->client_name); + if (dolog) + syslog(LOG_NOTICE, + "getfile failed for %s\n", getfile->client_name); + return (NULL); + } + + if (debug) + fprintf(stderr, + "returning server:%s path:%s address: %d.%d.%d.%d\n", + res.server_name, res.server_path, + 255 & res.server_address.bp_address_u.ip_addr.net, + 255 & res.server_address.bp_address_u.ip_addr.host, + 255 & res.server_address.bp_address_u.ip_addr.lh, + 255 & res.server_address.bp_address_u.ip_addr.impno); + if (dolog) + syslog(LOG_NOTICE, + "returning server:%s path:%s address: %d.%d.%d.%d\n", + res.server_name, res.server_path, + 255 & res.server_address.bp_address_u.ip_addr.net, + 255 & res.server_address.bp_address_u.ip_addr.host, + 255 & res.server_address.bp_address_u.ip_addr.lh, + 255 & res.server_address.bp_address_u.ip_addr.impno); + return (&res); +} + + +int +lookup_bootparam(client, client_canonical, id, server, path) + char *client; + char *client_canonical; + char *id; + char **server; + char **path; +{ + FILE *f = fopen(bootpfile, "r"); +#ifdef YP + static char *ypbuf = NULL; + static int ypbuflen = 0; +#endif + static char buf[BUFSIZ]; + char *bp, *word; + size_t idlen = id == NULL ? 0 : strlen(id); + int contin = 0; + int found = 0; + + if (f == NULL) + return EINVAL; /* ? */ + + while (fgets(buf, sizeof buf, f)) { + int wascontin = contin; + contin = buf[strlen(buf) - 2] == '\\'; + bp = buf + strspn(buf, " \t\n"); + + switch (wascontin) { + case -1: + /* Continuation of uninteresting line */ + contin *= -1; + continue; + case 0: + /* New line */ + contin *= -1; + if (*bp == '#') + continue; + if ((word = strsep(&bp, " \t\n")) == NULL) + continue; +#ifdef YP + /* A + in the file means try YP now */ + if (!strcmp(word, "+")) { + char *ypdom; + + if (yp_get_default_domain(&ypdom) || + yp_match(ypdom, "bootparams", client, + strlen(client), &ypbuf, &ypbuflen)) + continue; + bp = ypbuf; + word = client; + contin *= -1; + break; + } +#endif + /* See if this line's client is the one we are + * looking for */ + if (strcmp(word, client) != 0) { + /* + * If it didn't match, try getting the + * canonical host name of the client + * on this line and comparing that to + * the client we are looking for + */ + struct hostent *hp = gethostbyname(word); + if (hp == NULL || strcmp(hp->h_name, client)) + continue; + } + contin *= -1; + break; + case 1: + /* Continued line we want to parse below */ + break; + } + + if (client_canonical) + strncpy(client_canonical, word, MAX_MACHINE_NAME); + + /* We have found a line for CLIENT */ + if (id == NULL) { + (void) fclose(f); + return 0; + } + + /* Look for a value for the parameter named by ID */ + while ((word = strsep(&bp, " \t\n")) != NULL) { + if (!strncmp(word, id, idlen) && word[idlen] == '=') { + /* We have found the entry we want */ + *server = &word[idlen + 1]; + *path = strchr(*server, ':'); + if (*path == NULL) + /* Malformed entry */ + continue; + *(*path)++ = '\0'; + (void) fclose(f); + return 0; + } + } + + found = 1; + } + + (void) fclose(f); + return found ? ENOENT : EPERM; +} diff --git a/usr.sbin/rpc.bootparamd/bootparams.5 b/usr.sbin/rpc.bootparamd/bootparams.5 new file mode 100644 index 00000000000..06a965144af --- /dev/null +++ b/usr.sbin/rpc.bootparamd/bootparams.5 @@ -0,0 +1,78 @@ +.\" +.\" Copyright (c) 1994 Gordon W. Ross +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $Id: bootparams.5,v 1.1 1995/10/18 08:48:05 deraadt Exp $ +.\" +.Dd October 2, 1994 +.Dt BOOTPARAMS 5 +.Os +.Sh NAME +.Nm bootparams +.Nd boot parameter database +.Sh SYNOPSIS +.Nm /etc/bootparams +.Sh DESCRIPTION +The +.Nm bootparams +file specifies the boot parameters that +.Xr diskless +clients may request when booting over the network. +Each client supported by this server must have an entry in the +.Nm bootparams +file containing the pathnames for its +.Nm root +and (optionally) +.Nm swap +areas. +.Pp +Each line in the file +(other than comment lines that begin with a #) +specifies the client name followed by the pathnames that +the client may request by their logical names. +The components of the line are delimited with blank or tab, +and may be continued onto multiple lines with a backslash. +.Pp +For example: +.Bd -literal -offset indent +dummy root=/export/dummy/root \\ + swap=/export/dummy/swap \\ + dump=/export/dummy/swap +.Ed +.Pp +When the client named "dummy" requests the pathname for +its logical "root" it will be given the pathname +.Dq Pa "/export/dummy/root" +as the response to its +.Tn RPC +request. +.Sh FILES +.Bl -tag -width /etc/bootparams -compact +.It Pa /etc/bootparams +default configuration file +.El +.Sh "SEE ALSO" +.Xr diskless 8 , +.Xr rpc.bootparamd 8 diff --git a/usr.sbin/rpc.bootparamd/pathnames.h b/usr.sbin/rpc.bootparamd/pathnames.h new file mode 100644 index 00000000000..f8048ead3a1 --- /dev/null +++ b/usr.sbin/rpc.bootparamd/pathnames.h @@ -0,0 +1,10 @@ +/* + * Written Roland McGrath <roland@frob.com> 10/15/93. + * Public domain. + * + * $Id: pathnames.h,v 1.1 1995/10/18 08:48:05 deraadt Exp $ + */ + +#include <paths.h> + +#define _PATH_BOOTPARAMS "/etc/bootparams" diff --git a/usr.sbin/rpc.bootparamd/rpc.bootparamd.8 b/usr.sbin/rpc.bootparamd/rpc.bootparamd.8 new file mode 100644 index 00000000000..ceb52e8f2d4 --- /dev/null +++ b/usr.sbin/rpc.bootparamd/rpc.bootparamd.8 @@ -0,0 +1,62 @@ +.\" $Id: rpc.bootparamd.8,v 1.1 1995/10/18 08:48:06 deraadt Exp $ +.\" @(#)bootparamd.8 +.Dd Jan 8, 1994 +.Dt BOOTPARAMD 8 +.Os NetBSD +.Sh NAME +.Nm bootparamd , +.Nm rpc.bootparamd +.Nd boot parameter server +.Sh SYNOPSIS +.Nm /usr/sbin/rpc.bootparamd +.Op Fl d +.Op Fl s +.Op Fl r router +.Op Fl f file +.Sh DESCRIPTION +.Nm \&Bootparamd +is a server process that provides information to diskless clients +necessary for booting. It consults the file +.Dq Pa /etc/bootparams . +It should normally be started from +.Dq Pa /etc/rc . +.Pp +This version will allow the use of aliases on the hostname in the +.Dq Pa /etc/bootparams +file. The hostname returned in response to the booting client's whoami request +will be the name that appears in the config file, not the canonical name. +In this way you can keep the answer short enough +so that machines that cannot handle long hostnames won't fail during boot. +.Pp +While parsing, if a line containing just ``+'' is found, and +the YP subsystem is active, the YP map +.Pa bootparams +will be searched immediately. +.Sh OPTIONS +.Bl -tag -width indent +.It Fl d +Display the debugging information. The daemon does not fork in this +case. +.It Fl s +Log the debugging information with syslog. +.It Fl r +Set the default router (a hostname or IP-address). +This defaults to the machine running the server. +.It Fl f +Specify the file to use as boot parameter file instead of +.Dq Pa /etc/bootparams . +.El +.Pp +.Sh FILES +.Bl -tag -width /etc/bootparams -compact +.It Pa /etc/bootparams +default configuration file +.El +.Sh "SEE ALSO" +.Xr bootparams 5 +.Sh BUGS +You may find the syslog loggings too verbose. +.Pp +It's not clear if the non-cannonical hack mentioned above is a good idea. +.Sh AUTHOR +Originally written by Klas Heggemann <klas@nada.kth.se> |