Пример #1
0
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
    char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
    char * chk = NULL, *ip = NULL;
    int failed = 0;
    iface_t iface;

    if (kickstartNetworkUp(loaderData, &iface)) {
        logMessage(ERROR, "unable to bring up network");
        return 1;
    }

    /* if they just did 'linux ks', they want us to figure it out from
     * the dhcp/bootp information
     */
/* XXX: fixme NetworkManager integration */
/*
    if (url == NULL) {
        char ret[47];
        ip_addr_t *tip;

        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) {
            logMessage(ERROR, "no bootserver was found");
            return 1;
        }

        tip = &(netCfg.dev.nextServer);
        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));

            if (asprintf(&url, "%s:%s", ret, "/kickstart/") == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }

            logMessage(ERROR, "bootp: no bootfile received");
        } else {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));

            if (asprintf(&url, "%s:%s", ret, netCfg.dev.bootFile) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }

            logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile);
        }
    }
*/

    /* get the IP of the target system */
    if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) {
        logMessage(ERROR, "nl_ip2str returned NULL");
        return 1;
    }

    logMessage(INFO, "url is %s", url);
    getHostandPath(url, &host, &path, ip);

    opts = strchr(host, ':');
    if (opts && (strlen(opts) > 1)) {
        char * c = opts;
        opts = host;
        host = c + 1;
        *c = '\0';
    } else {
        opts = NULL;
    }

    /* nfs has to be a little bit different... split off the last part as
     * the file and then concatenate host + dir path */
    file = strrchr(path, '/');
    if (!file) {
        file = path;
    } else {
        *file++ ='\0';
        chk = host + strlen(host)-1;

        if (*chk == '/' || *path == '/') {
            if (asprintf(&host, "%s%s", host, path) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }
        } else {
            if (asprintf(&host, "%s/%s", host, path) == -1) {
                logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                abort();
            }
        }
    }

    logMessage(INFO, "file location: nfs:%s/%s", host, file);

    if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) {
        char * buf;

        if (asprintf(&buf, "/tmp/mnt/%s", file) == -1) {
            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
            abort();
        }

        if (copyFile(buf, dest)) {
            logMessage(ERROR, "failed to copy file to %s", dest);
            failed = 1;
        }

        free(buf);
    } else {
        logMessage(ERROR, "failed to mount nfs source");
        failed = 1;
    }

    free(host);
    free(path);
    if (ip) free(ip);

    umount("/tmp/mnt");
    unlink("/tmp/mnt");

    return failed;
}
Пример #2
0
void getKickstartFile(struct loaderData_s *loaderData) {
    char *c;
    int rc = 1;

    /* Chop off the parameter name, if given. */
    if (!strncmp(loaderData->ksFile, "ks=", 3))
        c = loaderData->ksFile+3;
    else
        c = loaderData->ksFile;

    while (rc != 0) {
        if (!strncmp(c, "ks", 2)) {
#ifdef  STACKI
            /*
             * make the default kickstart method the URL method
             */
            rc = kickstartFromUrl("", loaderData);
            if (rc) {
                return;
            }
#else
            rc = kickstartFromNfs(NULL, loaderData);
#endif
            loaderData->ksFile = strdup("/tmp/ks.cfg");
        } else if (!strncmp(c, "http", 4) || !strncmp(c, "ftp://", 6)) {
            rc = kickstartFromUrl(c, loaderData);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
        } else if (!strncmp(c, "nfs:", 4)) {
            rc = kickstartFromNfs(c+4, loaderData);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
        } else if (!strncmp(c, "floppy", 6)) {
            rc = kickstartFromRemovable(c);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
        } else if (!strncmp(c, "hd:", 3)) {
            rc = kickstartFromHD(c);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
#ifdef  STACKI
        {
            /*
             * bring the network up, even if it a hard disk based install
             */
            iface_t iface;

            iface_init_iface_t(&iface);
            kickstartNetworkUp(loaderData, &iface);
	}
#endif
        } else if (!strncmp(c, "bd:", 3)) {
            rc = kickstartFromBD(c);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
        } else if (!strncmp(c, "cdrom", 5)) {
            rc = kickstartFromCD(c);
            loaderData->ksFile = strdup("/tmp/ks.cfg");
#ifdef  STACKI
        {
            /*
             * bring the network up, even if it a CD-based install
             */
            iface_t iface;

            iface_init_iface_t(&iface);
            kickstartNetworkUp(loaderData, &iface);
	}
#endif
        } else if (!strncmp(c, "file:", 5)) {
            loaderData->ksFile = c+5;
            break;
        }

        if (rc != 0) {
            char *newLocation;

            if (!strcmp(c, "ks"))
                newLocation = newKickstartLocation("");
            else
                newLocation = newKickstartLocation(c);

            if (loaderData->ksFile != NULL)
                free(loaderData->ksFile);

            if (newLocation != NULL) {
               loaderData->ksFile = strdup(newLocation);
               free(newLocation);
               return getKickstartFile(loaderData);
            }
            else
               return;
        }
    }

#ifdef  STACKI
    /*
     * if we get a kickstart file, try to write the '/tmp/interfaces' file
     */
    writeInterfacesFile(loaderData);
#endif

    flags |= LOADER_FLAGS_KICKSTART;
    return;
}
Пример #3
0
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
    char ret[47];
    char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
    int failed = 0;
    struct networkDeviceConfig netCfg;
    ip_addr_t *tip, *u;

    if (kickstartNetworkUp(loaderData, &netCfg)) {
        logMessage(ERROR, "unable to bring up network");
        return 1;
    }

    /* if they just did 'linux ks', they want us to figure it out from
     * the dhcp/bootp information
     */
    if (url == NULL) {
        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) {
            logMessage(ERROR, "no bootserver was found");
            return 1;
        }

        tip = &(netCfg.dev.nextServer);
        if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
            url = sdupprintf("%s:%s", ret, "/kickstart/");
            logMessage(ERROR, "bootp: no bootfile received");
        } else {
            inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
            url = sdupprintf("%s:%s", ret, netCfg.dev.bootFile);
            logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile);
        }
    } 

    /* get the IP of the target system */
    if (FL_HAVE_CMSCONF(flags)) {
        if (loaderData->ip == NULL) {
            logMessage(ERROR, "getFileFromNfs: no client IP information");
            return 1;
        } else {
            sprintf(ret, "%s", loaderData->ip);
        }
    } else {
        tip = &(netCfg.dev.ipv4);
        u = &(netCfg.dev.ip);
        if ((inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)) == NULL) && (inet_ntop(u->sa_family, IP_ADDR(u), ret, IP_STRLEN(u)) == NULL)) {
            logMessage(ERROR, "getFileFromNfs: no client IP information");
            return 1;
        }
    }

    logMessage(INFO, "url is %s", url);
    getHostandPath(url, &host, &path, ret);

    opts = strchr(host, ':');
    if (opts && (strlen(opts) > 1)) {
        char * c = opts;
        opts = host;
        host = c + 1;
        *c = '\0';
    } else {
        opts = NULL;
    }

    /* nfs has to be a little bit different... split off the last part as
     * the file and then concatenate host + dir path */
    file = strrchr(path, '/');
    if (!file) {
        file = path;
    } else {
        *file++ ='\0';
        host = sdupprintf("%s/%s", host, path);
    }

    logMessage(INFO, "file location: nfs://%s/%s", host, file);

    if (!doPwMount(host, "/tmp/mnt", "nfs", IMOUNT_RDONLY, opts)) {
        char * buf;

        buf = alloca(strlen(file) + 10);
        sprintf(buf, "/tmp/mnt/%s", file);
        if (copyFile(buf, dest)) {
            logMessage(ERROR, "failed to copy file to %s", dest);
            failed = 1;
        }
    } else {
        logMessage(ERROR, "failed to mount nfs source");
        failed = 1;
    }

    umount("/tmp/mnt");
    unlink("/tmp/mnt");

    return failed;
}
Пример #4
0
int getFileFromUrl(char * url, char * dest, 
                   struct loaderData_s * loaderData) {
    int retval = 0;
    struct iurlinfo ui;
    enum urlprotocol_t proto = 
        !strncmp(url, "ftp://", 6) ? URL_METHOD_FTP : URL_METHOD_HTTP;
    char * host = NULL, * file = NULL, * chptr = NULL, *login = NULL, *password = NULL;
    int fd, rc;
    iface_t iface;
    char *ehdrs = NULL, *ip = NULL;
    long long size;
    struct progressCBdata *data = NULL;

    iface_init_iface_t(&iface);

    if (kickstartNetworkUp(loaderData, &iface)) {
        logMessage(ERROR, "unable to bring up network");
        return 1;
    }

    memset(&ui, 0, sizeof(ui));
    ui.protocol = proto;

    getHostPathandLogin((proto == URL_METHOD_FTP ? url + 6 : url + 7),
                   &host, &file, &login, &password, ip);

    logMessage(INFO, "file location: %s://%s%s", 
               (proto == URL_METHOD_FTP ? "ftp" : "http"), host, file);

    chptr = strchr(host, '/');
    if (chptr == NULL) {
        ui.address = strdup(host);
        ui.prefix = strdup("/");
    } else {
        *chptr = '\0';
        ui.address = strdup(host);
        host = chptr;
        *host = '/';
        ui.prefix = strdup(host);
    }

    if (password[0] != '\0')
        ui.password = strdup (password);
    if (login[0] != '\0')
        ui.login = strdup (login);

    if (proto == URL_METHOD_HTTP) {
        char *arch = getProductArch();
        char *name = getProductName();

        if (asprintf(&ehdrs, "User-Agent: anaconda/%s\r\n"
                             "X-Anaconda-Architecture: %s\r\n"
                             "X-Anaconda-System-Release: %s\r\n",
                     VERSION, arch, name) == -1) {
            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
            abort();
        }
    }

    if (proto == URL_METHOD_HTTP && FL_KICKSTART_SEND_MAC(flags)) {
        /* find all ethernet devices and make a header entry for each one */
        int i;
        char *dev, *mac, *tmpstr;
        struct device **devices;

        devices = getDevices(DEVICE_NETWORK);
        for (i = 0; devices && devices[i]; i++) {
            dev = devices[i]->device;
            mac = iface_mac2str(dev);

            if (mac) {
                if (asprintf(&tmpstr, "X-RHN-Provisioning-MAC-%d: %s %s\r\n",
                             i, dev, mac) == -1) {
                    logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
                    abort();
                }

                if (!ehdrs) {
                    ehdrs = strdup(tmpstr);
                } else {
                    ehdrs = (char *) realloc(ehdrs, strlen(ehdrs)+strlen(tmpstr)+1);
                    strcat(ehdrs, tmpstr);
                }

                free(mac);
                free(tmpstr);
            }
        }
    }

    fd = urlinstStartTransfer(&ui, file, ehdrs, &data, &size);
    if (fd < 0) {
        logMessage(ERROR, "failed to retrieve http://%s/%s%s", ui.address, ui.prefix, file);
        retval = 1;
        goto err;
    }

    rc = copyFileFd(fd, dest, progressCallback, data, size);
    if (rc) {
        unlink (dest);
        logMessage(ERROR, "failed to copy file to %s", dest);
        retval = 1;
        goto err;
    }

    urlinstFinishTransfer(&ui, fd, &data);

err:
    if (file) free(file);
    if (ehdrs) free(ehdrs);
    if (host) free(host);
    if (login) free(login);
    if (password) free(password);

    return retval;
}
Пример #5
0
int getFileFromUrl(char * url, char * dest, 
                   struct loaderData_s * loaderData) {
    char ret[47];
    struct iurlinfo ui;
    enum urlprotocol_t proto = 
        !strncmp(url, "ftp://", 6) ? URL_METHOD_FTP : URL_METHOD_HTTP;
    char * host = NULL, * file = NULL, * chptr = NULL;
    char * user = NULL, * password = NULL;
    int fd, rc;
    struct networkDeviceConfig netCfg;
    char * ehdrs = NULL;
    ip_addr_t *tip;

#ifdef  ROCKS
    char *drivername;
#endif

#ifdef  ROCKS
     /*
      * Call non-interactive, exhaustive NetworkUp() if we are
      * a cluster appliance.
      */
    if (!strlen(url)) {
	    logMessage(INFO, "ROCKS:getFileFromUrl:calling rocksNetworkUp");
            rc = rocksNetworkUp(loaderData, &netCfg);
    } else {
	    logMessage(INFO, "ROCKS:getFileFromUrl:calling kickstartNetworkUp");
            rc = kickstartNetworkUp(loaderData, &netCfg);
    }

    if (rc) return 1;
    fd = 0;

    /*
     * this will be used when starting up mini_httpd()
     *
     * Get the nextServer from PUMP if we DHCP, otherwise it
     * better be on the command line.
     */

    if ( netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE ) {
    	tip = &(netCfg.dev.nextServer);
    	inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));

    	if (strlen(ret) > 0) {
		loaderData->nextServer = strdup(ret);
	} else {
        	loaderData->nextServer = NULL;
	}
    }

    /*
     * If no nextServer use the gateway.
     */
    if ( !loaderData->nextServer ) {
    	loaderData->nextServer = strdup(loaderData->gateway);
    }

    logMessage(INFO, "%s: nextServer %s",
		"ROCKS:getFileFromUrl", loaderData->nextServer);
#else
    if (kickstartNetworkUp(loaderData, &netCfg)) {
        logMessage(ERROR, "unable to bring up network");
        return 1;
    }
#endif /* ROCKS */

    memset(&ui, 0, sizeof(ui));
    ui.protocol = proto;

#ifdef	ROCKS
{
	struct sockaddr_in	*sin;
	int			string_size;
	int			ncpus;
	char			np[16];
	char			*arch;
	char			*base;

#if defined(__i386__)
	arch = "i386";
#elif defined(__ia64__)
	arch = "ia64";
#elif defined(__x86_64__)
	arch = "x86_64";
#endif

	if (!strlen(url)) {
		base = strdup("install/sbin/kickstart.cgi");
		host = strdup(loaderData->nextServer);
	}
	else {
		char	*p, *q;

		base = NULL;
		host = NULL;

		p = strstr(url, "//");
		if (p != NULL) {
			p += 2;

			/*
			 * 'base' is the file name
			 */
			base = strchr(p, '/');
			if (base != NULL) {
				base += 1;
			}

			/*
		 	 * now get the host portion of the URL
			 */
			q = strchr(p, '/');
			if (q != NULL) {
				*q = '\0';
				host = strdup(p);
			}
		}
		
		if (!base || !host) {
			logMessage(ERROR,
				"kickstartFromUrl:url (%s) not well formed.\n",
				url);
			return(1);
		}
	}

	/* We always retrieve our kickstart file via HTTPS, 
	 * however the official install method (for *.img and rpms)
	 * is still HTTP.
	 */
	ui.protocol = URL_METHOD_HTTPS;

	winStatus(40, 3, _("Secure Kickstart"), 
	        _("Looking for Kickstart keys..."));

	getCert(loaderData);

	newtPopWindow();

	/* seed random number generator with our IP: unique for our purposes.
	 * Used for nack backoff.
	 */
	tip = &(netCfg.dev.nextServer);
	sin = (struct sockaddr_in *)IP_ADDR(tip);
	if (sin == NULL) {
		srand(time(NULL));
	} else {
		srand((unsigned int)sin->sin_addr.s_addr);
	}

	ncpus = num_cpus();
	sprintf(np, "%d", ncpus);

	string_size = strlen(base) + strlen("?arch=") + strlen(arch) +
		strlen("&np=") + strlen(np) + 1;

	if ((file = alloca(string_size)) == NULL) {
		logMessage(ERROR, "kickstartFromUrl:alloca failed\n");
		return(1);
	}
	memset(file, 0, string_size);

	sprintf(file, "/%s?arch=%s&np=%s", base, arch, np);
}

	logMessage(INFO, "ks location: https://%s%s", host, file);

#else
    tip = &(netCfg.dev.ip);
    inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip));
    getHostPathandLogin((proto == URL_METHOD_FTP ? url + 6 : url + 7),
                   &host, &file, &user, &password, ret);

    logMessage(INFO, "file location: %s://%s/%s",
               (proto == URL_METHOD_FTP ? "ftp" : "http"), host, file);

#endif /* ROCKS */
    chptr = strchr(host, '/');
    if (chptr == NULL) {
        ui.address = strdup(host);
        ui.prefix = strdup("/");
    } else {
        *chptr = '\0';
        ui.address = strdup(host);
        host = chptr;
        *host = '/';
        ui.prefix = strdup(host);
    }

    if (user && strlen(user)) {
        ui.login = strdup(user);
        if (password && strlen(password)) ui.password = strdup(password);
    }

    if (proto == URL_METHOD_HTTP) {
        ehdrs = (char *) malloc(24+strlen(VERSION));
        sprintf(ehdrs, "User-Agent: anaconda/%s\r\n", VERSION);
    }

    if (proto == URL_METHOD_HTTP && FL_KICKSTART_SEND_MAC(flags)) {
        /* find all ethernet devices and make a header entry for each one */
        int i;
        unsigned int hdrlen;
        char *dev, *mac, tmpstr[128];
        struct device ** devices;

        hdrlen = 0;
        devices = probeDevices(CLASS_NETWORK, BUS_UNSPEC, PROBE_LOADED);
        for (i = 0; devices && devices[i]; i++) {
            dev = devices[i]->device;
            mac = nl_mac2str(dev);
#ifdef  ROCKS
            drivername = get_driver_name(dev);
#endif
            if (mac) {
#ifdef  ROCKS
                /* A hint as to our primary interface. */
                if (!strcmp(dev, loaderData->netDev)) {
                        snprintf(tmpstr, sizeof(tmpstr),
                                "X-RHN-Provisioning-MAC-%d: %s %s %s ks\r\n",
                                i, dev, mac, drivername);
                } else {
                        snprintf(tmpstr, sizeof(tmpstr),
                                "X-RHN-Provisioning-MAC-%d: %s %s %s\r\n",
                                i, dev, mac, drivername);
                }
#else
                snprintf(tmpstr, sizeof(tmpstr),
                         "X-RHN-Provisioning-MAC-%d: %s %s\r\n", i, dev, mac);

#endif /* ROCKS */

#ifdef  ROCKS
                free(drivername);
#endif
                free(mac);

                if (!ehdrs) {
                    hdrlen = 128;
                    ehdrs = (char *) malloc(hdrlen);
                    *ehdrs = '\0';
                } else if ( strlen(tmpstr) + strlen(ehdrs) + 2 > hdrlen) {
                    hdrlen += 128;
                    ehdrs = (char *) realloc(ehdrs, hdrlen);
                }

                strcat(ehdrs, tmpstr);
            }
        }
    }
	
#ifdef ROCKS
{
        /* Retrieve the kickstart file via HTTPS */

        BIO *sbio;

        sbio = urlinstStartSSLTransfer(&ui, file, ehdrs, 1, flags,
		loaderData->nextServer);
        if (!sbio) {
                logMessage(ERROR, "failed to retrieve https://%s/%s",
                        ui.address, file);
                return 1;
        }

        rc = copyFileSSL(sbio, dest);
        if (rc) {
                unlink (dest);
                logMessage(ERROR, "failed to copy file to %s", dest);
                return 1;
        }

        urlinstFinishSSLTransfer(sbio);
        if (haveCertificate())
                umount("/mnt/rocks-disk");
}
#else
    fd = urlinstStartTransfer(&ui, file, ehdrs);
    if (fd < 0) {
        logMessage(ERROR, "failed to retrieve http://%s/%s/%s", ui.address, ui.prefix, file);
        if (ehdrs) free(ehdrs);
        return 1;
    }
           
    rc = copyFileFd(fd, dest);
    if (rc) {
        unlink (dest);
        logMessage(ERROR, "failed to copy file to %s", dest);
        if (ehdrs) free(ehdrs);
        return 1;
    }

    urlinstFinishTransfer(&ui, fd);
#endif /* ROCKS */

    if (ehdrs) free(ehdrs);

    return 0;
}