diff options
author | David Miner <dminer@opensolaris.org> | 2010-07-23 18:33:39 -0400 |
---|---|---|
committer | David Miner <dminer@opensolaris.org> | 2010-07-23 18:33:39 -0400 |
commit | 22ce47f7854e0848adf05feb75b97e65da1c8d8f (patch) | |
tree | b9ff479c4cac8d0d147a9153e10870d6d77aeb28 /usr/src/cmd/cmd-inet/usr.lib | |
parent | 8f605d57121d83ba412586f242ee8eefd2e08a0b (diff) | |
download | illumos-gate-22ce47f7854e0848adf05feb75b97e65da1c8d8f.tar.gz |
6960361 wanboot-cgi's name resolution can send clients to unreachable addresses
6960356 Network-independent wanboot client configuration
Diffstat (limited to 'usr/src/cmd/cmd-inet/usr.lib')
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/wanboot/wanboot-cgi/wanboot-cgi.c | 150 |
1 files changed, 75 insertions, 75 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/wanboot/wanboot-cgi/wanboot-cgi.c b/usr/src/cmd/cmd-inet/usr.lib/wanboot/wanboot-cgi/wanboot-cgi.c index d18366398c..c24626d9a9 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/wanboot/wanboot-cgi/wanboot-cgi.c +++ b/usr/src/cmd/cmd-inet/usr.lib/wanboot/wanboot-cgi/wanboot-cgi.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,10 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" #include <stdio.h> #include <stdlib.h> @@ -42,6 +39,7 @@ #include <sys/sysmacros.h> #include <sys/mman.h> #include <sys/socket.h> +#include <sys/utsname.h> #include <sys/wanboot_impl.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -677,12 +675,17 @@ mkisofs(const char *image_dir, const char *image) /* * This function, when invoked with a file name, optional network and - * client * ID strings, and callback function will walk the directory - * hierarchy between the concatenation of NB_NETBOOT_ROOT, the network - * number, and client ID, invoking the callback function each time it - * finds a file with the specified name until the hierarchy walk - * terminates or the callback function returns a value other than - * WBCGI_FTW_CBCONT. + * client ID strings, and callback function will search for the file + * in the following locations: + * + * NB_NETBOOT_ROOT/<network>/<client id>/<file> + * NB_NETBOOT_ROOT/<client id>/<file> + * NB_NETBOOT_ROOT/<network>/<file> + * NB_NETBOOT_ROOT/<file> + * + * The callback function is invoked each time the file is found until + * we have searched all of the above locations or the callback function + * returns a value other than WBCGI_FTW_CBCONT. * * Arguments: * filename - Name of file to search for. @@ -698,69 +701,41 @@ static int netboot_ftw(const char *filename, const char *net, const char *cid, int (*cb)(const char *, void *arg), void *arg) { - char ckpath[MAXPATHLEN]; - char *ptr; + char ckpath[4][MAXPATHLEN]; int ret; struct stat buf; + int i = 0; - /* - * All searches start at the root. - */ - if (strlcpy(ckpath, NB_NETBOOT_ROOT, - sizeof (ckpath)) >= sizeof (ckpath)) { + if (snprintf(ckpath[i++], MAXPATHLEN, "%s%s", NB_NETBOOT_ROOT, filename) + >= MAXPATHLEN) return (WBCGI_FTW_CBERR); - } - /* - * Remaining part of path depends on 'net' and 'cid'. Note that - * it is not valid to have a NULL 'net', but non-NULL 'cid'. - */ - if (net == NULL && cid != NULL) { + if (net != NULL && snprintf(ckpath[i++], MAXPATHLEN, "%s%s/%s", + NB_NETBOOT_ROOT, net, filename) >= MAXPATHLEN) return (WBCGI_FTW_CBERR); - } - if (net != NULL) { - if (strlcat(ckpath, net, sizeof (ckpath)) >= sizeof (ckpath) || - strlcat(ckpath, "/", sizeof (ckpath)) >= sizeof (ckpath)) { - return (WBCGI_FTW_CBERR); - } - } + if (cid != NULL) { - if (strlcat(ckpath, cid, sizeof (ckpath)) >= sizeof (ckpath) || - strlcat(ckpath, "/", sizeof (ckpath)) >= sizeof (ckpath)) { + if (snprintf(ckpath[i++], MAXPATHLEN, "%s%s/%s", + NB_NETBOOT_ROOT, cid, filename) >= MAXPATHLEN) + return (WBCGI_FTW_CBERR); + + if (net != NULL && snprintf(ckpath[i++], MAXPATHLEN, + "%s%s/%s/%s", NB_NETBOOT_ROOT, net, cid, filename) >= + MAXPATHLEN) return (WBCGI_FTW_CBERR); - } } /* * Loop through hierarchy and check for file existence. */ - for (;;) { - if (strlcat(ckpath, filename, - sizeof (ckpath)) >= sizeof (ckpath)) { - return (WBCGI_FTW_CBERR); - } - if (WBCGI_FILE_EXISTS(ckpath, buf)) { - if ((ret = cb(ckpath, arg)) != WBCGI_FTW_CBCONT) { + while (i > 0) { + --i; + if (WBCGI_FILE_EXISTS(ckpath[i], buf)) { + if ((ret = cb(ckpath[i], arg)) != WBCGI_FTW_CBCONT) return (ret); - } - } - - /* - * Remove last component (which would be the - * filename). If this leaves the root, then - * hierarchy search has been completed. Otherwise, - * remove the trailing directory and go try again. - */ - ptr = strrchr(ckpath, '/'); - *++ptr = '\0'; - if (strcmp(NB_NETBOOT_ROOT, ckpath) == 0) { - return (WBCGI_FTW_DONE); - } else { - *--ptr = '\0'; - ptr = strrchr(ckpath, '/'); - *++ptr = '\0'; } } + return (WBCGI_FTW_DONE); } /*ARGSUSED*/ @@ -1001,19 +976,46 @@ resolve_hostname(const char *hostname, nvlist_t *nvl, boolean_t may_be_crap) { struct sockaddr_in sin; struct hostent *hp; + struct utsname un; + static char myname[SYS_NMLN] = { '\0' }; + char *cp = NULL; + char msg[WBCGI_MAXBUF]; - if (((hp = gethostbyname(hostname)) == NULL) || - (hp->h_addrtype != AF_INET) || - (hp->h_length != sizeof (struct in_addr))) { - if (!may_be_crap) { - print_status(500, "(error resolving hostname)"); + /* + * Initialize cached nodename + */ + if (strlen(myname) == 0) { + if (uname(&un) == -1) { + (void) snprintf(msg, sizeof (msg), + "(unable to retrieve uname, errno %d)", errno); + print_status(500, msg); + return (B_FALSE); } - return (may_be_crap); + (void) strcpy(myname, un.nodename); } - (void) memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); - if (nvlist_add_string(nvl, - (char *)hostname, inet_ntoa(sin.sin_addr)) != 0) { + /* + * If hostname is local node name, return the address this + * request came in on, which is supplied as SERVER_ADDR in the + * cgi environment. This ensures we don't send back a possible + * alternate address that may be unreachable from the client's + * network. Otherwise, just resolve with nameservice. + */ + if ((strcmp(hostname, myname) != 0) || + ((cp = getenv("SERVER_ADDR")) == NULL)) { + if (((hp = gethostbyname(hostname)) == NULL) || + (hp->h_addrtype != AF_INET) || + (hp->h_length != sizeof (struct in_addr))) { + if (!may_be_crap) { + print_status(500, "(error resolving hostname)"); + } + return (may_be_crap); + } + (void) memcpy(&sin.sin_addr, hp->h_addr, hp->h_length); + cp = inet_ntoa(sin.sin_addr); + } + + if (nvlist_add_string(nvl, (char *)hostname, cp) != 0) { print_status(500, "(error adding hostname to nvlist)"); return (B_FALSE); } @@ -1360,7 +1362,7 @@ wanbootfs_payload(const char *net, const char *cid, const char *nonce, print_status(500, "(truststore not found)"); } if (netboot_ftw(NB_CA_CERT, net, cid, - build_trustfile, truststorepath) == WBCGI_FTW_CBERR) { + build_trustfile, truststorepath) == WBCGI_FTW_CBERR) { goto cleanup; } @@ -1747,9 +1749,8 @@ main(int argc, char **argv) print_status(500, "(hmac utility not found)"); goto cleanup; } - if (keyfile == NULL && - netboot_ftw(NB_CLIENT_KEY, net, cid, - set_pathname, &keyfile) != WBCGI_FTW_CBOK) { + if (keyfile == NULL && netboot_ftw(NB_CLIENT_KEY, net, cid, + set_pathname, &keyfile) != WBCGI_FTW_CBOK) { print_status(500, "(keystore not found)"); goto cleanup; } @@ -1768,9 +1769,8 @@ main(int argc, char **argv) print_status(500, "(encr utility not found)"); goto cleanup; } - if (keyfile == NULL && - netboot_ftw(NB_CLIENT_KEY, net, cid, - set_pathname, &keyfile) != WBCGI_FTW_CBOK) { + if (keyfile == NULL && netboot_ftw(NB_CLIENT_KEY, net, cid, + set_pathname, &keyfile) != WBCGI_FTW_CBOK) { print_status(500, "(keystore not found)"); goto cleanup; } |