diff options
| author | deraadt <deraadt@NetBSD.org> | 1994-01-08 13:22:03 +0000 |
|---|---|---|
| committer | deraadt <deraadt@NetBSD.org> | 1994-01-08 13:22:03 +0000 |
| commit | ae99bc57e379be82dd5ac963d30fb035657570e5 (patch) | |
| tree | 6b800e1c4b76f55dd089571136319fb4d4d41c6f /usr.sbin/rpc.bootparamd/bootparamd.c | |
| parent | b38fa5acf8ff8ba95e8e03cc133abfc0bbe2504f (diff) | |
rpc.bootparamd written by Klas Heggemann <klas@nada.kth.se>
(yes, it belongs in usr.sbin, not libexec)
Diffstat (limited to 'usr.sbin/rpc.bootparamd/bootparamd.c')
| -rw-r--r-- | usr.sbin/rpc.bootparamd/bootparamd.c | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/usr.sbin/rpc.bootparamd/bootparamd.c b/usr.sbin/rpc.bootparamd/bootparamd.c new file mode 100644 index 00000000000..e7daf533b35 --- /dev/null +++ b/usr.sbin/rpc.bootparamd/bootparamd.c @@ -0,0 +1,407 @@ +/* + * 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> + * + * $Id: bootparamd.c,v 1.1 1994/01/08 13:22:04 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> + +#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(); + +int debug = 0; +int dolog = 0; +unsigned long route_addr, inet_addr(); +struct sockaddr_in my_addr; +char *progname; +char *bootpfile = "/etc/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(whoami) + bp_whoami_arg *whoami; +{ + 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 (checkhost(askname, hostname)) { + 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(getfile) + bp_getfile_arg *getfile; +{ + char *where, *index(); + static bp_getfile_res res; + + 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); + if (getthefile(askname, getfile->file_id, buffer)) { + if (where = index(buffer, ':')) { + /* buffer is re-written to contain the name of the + * info of file */ + strncpy(hostname, buffer, where - buffer); + hostname[where - buffer] = '\0'; + where++; + strcpy(path, where); + he = gethostbyname(hostname); + if (!he) + goto failed; + bcopy(he->h_addr, &res.server_address.bp_address_u.ip_addr, 4); + res.server_name = hostname; + res.server_path = path; + res.server_address.address_type = IP_ADDR_TYPE; + } else { /* special for dump, answer with null strings */ + if (!strcmp(getfile->file_id, "dump")) { + res.server_name[0] = '\0'; + res.server_path[0] = '\0'; + bzero(&res.server_address.bp_address_u.ip_addr, 4); + } else + goto failed; + } + 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); + } +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); +} + + +/* + * getthefile return 1 and fills the buffer with the information + * of the file, e g "host:/export/root/client" if it can be found. + * If the host is in the database, but the file is not, the buffer + * will be empty. (This makes it possible to give the special + * empty answer for the file "dump") + */ +getthefile(askname, fileid, buffer) + char *askname; + char *fileid, *buffer; +{ + FILE *bpf; + char *where; + + int ch, pch, fid_len, res = 0; + int match = 0; + char info[MAX_FILEID + MAX_PATH_LEN + MAX_MACHINE_NAME + 3]; + + bpf = fopen(bootpfile, "r"); + if (!bpf) { + fprintf(stderr, "No %s\n", bootpfile); + exit(1); + } + while (fscanf(bpf, "%s", hostname) > 0 && !match) { + if (*hostname != '#') { /* comment */ + if (!strcmp(hostname, askname)) { + match = 1; + } else { + he = gethostbyname(hostname); + if (he && !strcmp(he->h_name, askname)) + match = 1; + } + } + /* skip to next entry */ + if (match) + break; + pch = ch = getc(bpf); + while (!(ch == '\n' && pch != '\\') && ch != EOF) { + pch = ch; + ch = getc(bpf); + } + } + + /* if match is true we read the rest of the line to get the info of + * the file */ + + if (match) { + fid_len = strlen(fileid); + while (!res && (fscanf(bpf, "%s", info)) > 0) { /* read a string */ + ch = getc(bpf); /* and a character */ + if (*info != '#') { /* Comment ? */ + if (!strncmp(info, fileid, fid_len) && + *(info + fid_len) == '=') { + where = info + fid_len + 1; + if (isprint(*where)) { + strcpy(buffer, where); + res = 1; + break; + } + } else { + while (isspace(ch) && ch != '\n') + ch = getc(bpf); + if (ch == '\n') { + res = -1; + break; + } + if (ch == '\\') { + ch = getc(bpf); + if (ch == '\n') + continue; + ungetc(ch, bpf); + ungetc('\\', bpf); + } else + ungetc(ch, bpf); + } + } else + break; + } + } + if (fclose(bpf)) { + fprintf(stderr, "Could not close %s\n", bootpfile); + } + if (res == -1) + buffer[0] = '\0'; /* host found, file not */ + return (match); +} + + +/* + * checkhost puts the hostname found in the database file in + * the hostname-variable and returns 1, if askname is a valid + * name for a host in the database + */ +checkhost(askname, hostname) + char *askname; + char *hostname; +{ + int ch, pch; + FILE *bpf; + int res = 0; + + bpf = fopen(bootpfile, "r"); + if (!bpf) { + fprintf(stderr, "No %s\n", bootpfile); + exit(1); + } + while (fscanf(bpf, "%s", hostname) > 0) { + if (!strcmp(hostname, askname)) { + /* return true for match of hostname */ + res = 1; + break; + } else { + /* check the alias list */ + he = NULL; + he = gethostbyname(hostname); + if (he && !strcmp(askname, he->h_name)) { + res = 1; + break; + } + } + /* skip to next entry */ + pch = ch = getc(bpf); + while (!(ch == '\n' && pch != '\\') && ch != EOF) { + pch = ch; + ch = getc(bpf); + } + } + fclose(bpf); + return (res); +} |
