Ejemplo n.º 1
0
char * container_basedir(char *containerdir, char *dir) {
    char * testdir = strdup(dir);
    char * prevdir = NULL;
    if ( containerdir == NULL || dir == NULL ) {
        return(NULL);
    }

    while ( testdir != NULL && ( strcmp(testdir, "/") != 0 ) ) {
        if ( is_dir(joinpath(containerdir, testdir)) == 0 ) {
            return(testdir);
        }
        prevdir = strdup(testdir);
        testdir = dirname(strdup(testdir));
    }
    return(prevdir);
}
Ejemplo n.º 2
0
static void
calculate_exec_prefix(const _PyCoreConfig *core_config,
                      PyCalculatePath *calculate, wchar_t *exec_prefix)
{
    calculate->exec_prefix_found = search_for_exec_prefix(core_config,
                                                          calculate,
                                                          exec_prefix);
    if (!calculate->exec_prefix_found) {
        if (!core_config->_frozen) {
            fprintf(stderr,
                "Could not find platform dependent libraries <exec_prefix>\n");
        }
        wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
        joinpath(exec_prefix, L"lib/lib-dynload");
    }
    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
}
Ejemplo n.º 3
0
static void
calculate_prefix(const _PyCoreConfig *core_config,
                 PyCalculatePath *calculate, wchar_t *prefix)
{
    calculate->prefix_found = search_for_prefix(core_config, calculate, prefix);
    if (!calculate->prefix_found) {
        if (!core_config->_frozen) {
            fprintf(stderr,
                "Could not find platform independent libraries <prefix>\n");
        }
        wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
        joinpath(prefix, calculate->lib_python);
    }
    else {
        reduce(prefix);
    }
}
Ejemplo n.º 4
0
int check_mounted(char *mountpoint) {
    int retval = -1;
    FILE *mounts;
    char *line = (char *)malloc(MAX_LINE_LEN);
    char *rootfs_dir = singularity_runtime_rootfs(NULL);
    unsigned int mountpoint_len = strlength(mountpoint, PATH_MAX);

    singularity_message(DEBUG, "Opening /proc/mounts\n");
    if ( ( mounts = fopen("/proc/mounts", "r") ) == NULL ) { // Flawfinder: ignore
        singularity_message(ERROR, "Could not open /proc/mounts: %s\n", strerror(errno));
        ABORT(255);
    }

    if ( mountpoint[mountpoint_len-1] == '/' ) {
        singularity_message(DEBUG, "Removing trailing slash from string: %s\n", mountpoint);
        mountpoint[mountpoint_len-1] = '\0';
    }

    singularity_message(DEBUG, "Iterating through /proc/mounts\n");
    while ( fgets(line, MAX_LINE_LEN, mounts) != NULL ) {
        (void) strtok(strdup(line), " ");
        char *mount = strtok(NULL, " ");

        // Check to see if path is in container root
        if ( strncmp(rootfs_dir, mount, strlength(rootfs_dir, 1024)) != 0 ) {
            continue;
        }

        // Check to see if path is ot the container root
        if ( strcmp(mount, rootfs_dir) == 0 ) {
            continue;
        }

        // Check to see if mountpoint is already mounted
        if ( strcmp(joinpath(rootfs_dir, mountpoint), mount) == 0 ) {
            singularity_message(DEBUG, "Mountpoint is already mounted: %s\n", mountpoint);
            retval = 1;
            break;
        }
    }

    fclose(mounts);
    free(line);

    return(retval);
}
Ejemplo n.º 5
0
/* search_for_exec_prefix requires that argv0_path be no more than
   MAXPATHLEN bytes long.
*/
static int
search_for_exec_prefix(char *argv0_path, char *home)
{
    size_t n;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        char *delim;
        delim = strchr(home, DELIM);
        if (delim)
            strncpy(exec_prefix, delim+1, MAXPATHLEN);
        else
            strncpy(exec_prefix, home, MAXPATHLEN);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        return 1;
    }

    /* Check to see if argv[0] is in the build directory */
    strcpy(exec_prefix, argv0_path);
    joinpath(exec_prefix, "Modules/Setup");
    if (isfile(exec_prefix)) {
        reduce(exec_prefix);
        return -1;
    }

    /* Search from argv0_path, until root is found */
    copy_absolute(exec_prefix, argv0_path);
    do {
        n = strlen(exec_prefix);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        if (isdir(exec_prefix))
            return 1;
        exec_prefix[n] = '\0';
        reduce(exec_prefix);
    } while (exec_prefix[0]);

    /* Look at configure's EXEC_PREFIX */
    strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
    joinpath(exec_prefix, lib_python);
    joinpath(exec_prefix, "lib-dynload");
    if (isdir(exec_prefix))
        return 1;

    /* Fail */
    return 0;
}
Ejemplo n.º 6
0
/* copy_absolute requires that path be allocated at least
   MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
static void
copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen)
{
    if (p[0] == SEP) {
        wcscpy(path, p);
    }
    else {
        if (!_Py_wgetcwd(path, pathlen)) {
            /* unable to get the current directory */
            wcscpy(path, p);
            return;
        }
        if (p[0] == '.' && p[1] == SEP) {
            p += 2;
        }
        joinpath(path, p);
    }
}
Ejemplo n.º 7
0
static void
calculate_zip_path(PyCalculatePath *calculate, const wchar_t *prefix)
{
    wcsncpy(calculate->zip_path, prefix, MAXPATHLEN);
    calculate->zip_path[MAXPATHLEN] = L'\0';

    if (calculate->prefix_found > 0) {
        /* Use the reduced prefix returned by Py_GetPrefix() */
        reduce(calculate->zip_path);
        reduce(calculate->zip_path);
    }
    else {
        wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
    }
    joinpath(calculate->zip_path, L"lib/python00.zip");

    /* Replace "00" with version */
    size_t bufsz = wcslen(calculate->zip_path);
    calculate->zip_path[bufsz - 6] = VERSION[0];
    calculate->zip_path[bufsz - 5] = VERSION[2];
}
Ejemplo n.º 8
0
int container_daemon_stop(char *sessiondir) {
    FILE *comm;
    FILE *test_daemon_fp;
    int daemon_fd;

    message(DEBUG, "Called container_daemon_stop(%s)\n", sessiondir);

    message(VERBOSE, "Checking if daemon is currently running for this container\n");
    if ( is_file(joinpath(sessiondir, "daemon.pid")) < 0 ) {
        message(ERROR, "Daemon process is not running\n");
        return(0);
    }

    message(DEBUG, "Opening daemon.pid for reading\n");
    if ( ( test_daemon_fp = fopen(joinpath(sessiondir, "daemon.pid"), "r") ) == NULL ) { // Flawfinder: ignore
        message(ERROR, "Could not open daemon pid file %s: %s\n", joinpath(sessiondir, "daemon.pid"), strerror(errno));
        ABORT(255);
    }

    message(DEBUG, "Testing to see if daemon process is still active\n");
    daemon_fd = fileno(test_daemon_fp);
    if ( flock(daemon_fd, LOCK_SH | LOCK_NB) == 0 ) {
        message(INFO, "No active container daemon active\n");
        return(0);
    }

    message(DEBUG, "Connecting to daemon.comm FIFO\n");
    if ( is_fifo(joinpath(sessiondir, "daemon.comm")) < 0 ) {
        message(ERROR, "Container daemon COMM not available\n");
        ABORT(255);
    }

    message(VERBOSE, "Opening daemon.comm for writing\n");
    if ( ( comm = fopen(joinpath(sessiondir, "daemon.comm"), "w") ) == NULL ) { //Flawfinder: ignore
        message(ERROR, "Could not open fifo for writing %s: %s\n", joinpath(sessiondir, "daemon.comm"), strerror(errno));
        ABORT(255);
    }

    message(VERBOSE, "Sending stop command to daemon process\n");
    fputs("stop", comm);

    fclose(comm);

    message(DEBUG, "Return container_daemon_stop(%s) = 0\n", sessiondir);
    return(0);
}
Ejemplo n.º 9
0
int git2_mkdir_2file(const char *file_path)
{
	const int mode = 0755; /* or 0777 ? */
	int error = GIT_OK;
	char target_folder_path[GIT_PATH_MAX];
	
	error = dirname_r(target_folder_path, sizeof(target_folder_path), file_path);
	
	if (error < GIT_OK)
		return GIT_ERROR;
	
	/* Does the containing folder exist? */
	if (git2_isdir(target_folder_path)) {
		joinpath(target_folder_path, target_folder_path, ""); /* Ensure there's a trailing slash */
		
		/* Let's create the tree structure */
		error = git2_mkdir_recurs(target_folder_path, mode);
		if (error < GIT_OK)
			return error;	/* The callee already takes care of setting the correct error message. */
	}
	
	return GIT_OK;
}
Ejemplo n.º 10
0
int _singularity_runtime_mount_binds(void) {
    char *tmp_config_string;
    char *container_dir = singularity_runtime_rootfs(NULL);

    if ( singularity_registry_get("CONTAIN") != NULL ) {
        singularity_message(DEBUG, "Skipping bind mounts as contain was requested\n");
        return(0);
    }

    singularity_message(DEBUG, "Checking configuration file for 'bind path'\n");
    const char **tmp_config_string_list = singularity_config_get_value_multi(BIND_PATH);
    if ( strlength(*tmp_config_string_list, 1) == 0 ) {
        return(0);
    }
    while ( *tmp_config_string_list != NULL ) {
        tmp_config_string = strdup(*tmp_config_string_list);
        tmp_config_string_list++;
        char *source = strtok(tmp_config_string, ":");
        char *dest = strtok(NULL, ":");
        chomp(source);
        if ( dest == NULL ) {
            dest = strdup(source);
        } else {
            chomp(dest);
        }

        singularity_message(VERBOSE2, "Found 'bind path' = %s, %s\n", source, dest);

        if ( ( is_file(source) < 0 ) && ( is_dir(source) < 0 ) ) {
            singularity_message(WARNING, "Non existent 'bind path' source: '%s'\n", source);
            continue;
        }

        singularity_message(DEBUG, "Checking if bind point is already mounted: %s\n", dest);
        if ( check_mounted(dest) >= 0 ) {
            singularity_message(VERBOSE, "Not mounting bind point (already mounted): %s\n", dest);
            continue;
        }

        if ( ( is_file(source) == 0 ) && ( is_file(joinpath(container_dir, dest)) < 0 ) ) {
            if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) {
                char *basedir = dirname(joinpath(container_dir, dest));

                singularity_message(DEBUG, "Checking base directory for file %s ('%s')\n", dest, basedir);
                if ( is_dir(basedir) != 0 ) {
                    singularity_message(DEBUG, "Creating base directory for file bind\n");
                    singularity_priv_escalate();
                    if ( s_mkpath(basedir, 0755) != 0 ) {
                        singularity_message(ERROR, "Failed creating base directory to bind file: %s\n", dest);
                        ABORT(255);
                    }
                    singularity_priv_drop();
                }

                free(basedir);

                singularity_priv_escalate();
                singularity_message(VERBOSE3, "Creating bind file on overlay file system: %s\n", dest);
                FILE *tmp = fopen(joinpath(container_dir, dest), "w+"); // Flawfinder: ignore
                singularity_priv_drop();
                if ( tmp == NULL ) {
                    singularity_message(WARNING, "Could not create bind point file in container %s: %s\n", dest, strerror(errno));
                    continue;
                }
                if ( fclose(tmp) != 0 ) {
                    singularity_message(WARNING, "Could not close bind point file descriptor %s: %s\n", dest, strerror(errno));
                    continue;
                }
                singularity_message(DEBUG, "Created bind file: %s\n", dest);
            } else {
                singularity_message(WARNING, "Non existent bind point (file) in container: '%s'\n", dest);
                continue;
            }
        } else if ( ( is_dir(source) == 0 ) && ( is_dir(joinpath(container_dir, dest)) < 0 ) ) {
            if ( singularity_registry_get("OVERLAYFS_ENABLED") != NULL ) {
                singularity_priv_escalate();
                singularity_message(VERBOSE3, "Creating bind directory on overlay file system: %s\n", dest);
                if ( s_mkpath(joinpath(container_dir, dest), 0755) < 0 ) {
                    singularity_priv_drop();
                    singularity_message(WARNING, "Could not create bind point directory in container %s: %s\n", dest, strerror(errno));
                    continue;
                }
                singularity_priv_drop();
            } else {
                singularity_message(WARNING, "Non existent bind point (directory) in container: '%s'\n", dest);
                continue;
            }
        }

        singularity_priv_escalate();
        singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", source, container_dir, dest);
        if ( mount(source, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
            singularity_message(ERROR, "There was an error binding the path %s: %s\n", source, strerror(errno));
            ABORT(255);
        }
        if ( singularity_priv_userns_enabled() != 1 ) {
            if ( mount(NULL, joinpath(container_dir, dest), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) {
                singularity_message(ERROR, "There was an error remounting the path %s: %s\n", source, strerror(errno));
                ABORT(255);
            }
        }
        singularity_priv_drop();
    }

    return(0);
}
Ejemplo n.º 11
0
int main(int argc, char **argv) {
    char *image;

    // Before we do anything, check privileges and drop permission
    singularity_priv_init();
    singularity_priv_drop();

#ifdef SINGULARITY_SUID
    singularity_message(VERBOSE2, "Running SUID program workflow\n");

    singularity_message(VERBOSE2, "Checking program has appropriate permissions\n");
    if ( ( getuid() != 0 ) && ( ( is_owner("/proc/self/exe", 0) < 0 ) || ( is_suid("/proc/self/exe") < 0 ) ) ) {
        singularity_abort(255, "This program must be SUID root\n");
    }

    singularity_message(VERBOSE2, "Checking configuration file is properly owned by root\n");
    if ( is_owner(joinpath(SYSCONFDIR, "/singularity/singularity.conf"), 0 ) < 0 ) {
        singularity_abort(255, "Running in privileged mode, root must own the Singularity configuration file\n");
    }

    singularity_config_init(joinpath(SYSCONFDIR, "/singularity/singularity.conf"));

    singularity_message(VERBOSE2, "Checking that we are allowed to run as SUID\n");
    if ( singularity_config_get_bool(ALLOW_SETUID) == 0 ) {
        singularity_abort(255, "SUID mode has been disabled by the sysadmin... Aborting\n");
    }

    singularity_message(VERBOSE2, "Checking if we were requested to run as NOSUID by user\n");
    if ( envar_defined("SINGULARITY_NOSUID") == TRUE ) {
        singularity_abort(1, "NOSUID mode has been requested... Aborting\n");
    }

#else
    singularity_message(VERBOSE, "Running NON-SUID program workflow\n");

    singularity_message(DEBUG, "Checking program has appropriate permissions\n");
    if ( is_suid("/proc/self/exe") >= 0 ) {
        singularity_abort(255, "This program must **NOT** be SUID\n");
    }

    singularity_config_init(joinpath(SYSCONFDIR, "/singularity/singularity.conf"));

    if ( singularity_priv_getuid() != 0 ) {
        singularity_message(VERBOSE2, "Checking that we are allowed to run as SUID\n");
        if ( singularity_config_get_bool(ALLOW_SETUID) == 1 ) {
            singularity_message(VERBOSE2, "Checking if we were requested to run as NOSUID by user\n");
            if ( envar_defined("SINGULARITY_NOSUID") == FALSE ) {
                char sexec_suid_path[] = LIBEXECDIR "/singularity/sexec-suid";
		
		singularity_message(VERBOSE, "Checking for sexec-suid at %s\n", sexec_suid_path);

		if ( is_file(sexec_suid_path) == 0 ) {
                    if ( ( is_owner(sexec_suid_path, 0 ) == 0 ) && ( is_suid(sexec_suid_path) == 0 ) ) {
                        singularity_message(VERBOSE, "Invoking SUID sexec: %s\n", sexec_suid_path);

                        execv(sexec_suid_path, argv); // Flawfinder: ignore
                        singularity_abort(255, "Failed to execute sexec binary (%s): %s\n", sexec_suid_path, strerror(errno));
                    } else {
                        singularity_message(VERBOSE, "Not invoking SUID mode: SUID sexec permissions not properly set\n");
                    }
		}
		else {
		    singularity_message(VERBOSE, "Not invoking SUID mode: SUID sexec not installed\n");
		}
            } else {
                singularity_message(VERBOSE, "Not invoking SUID mode: NOSUID mode requested\n");
            }
        } else {
            singularity_message(VERBOSE, "Not invoking SUID mode: disallowed by the system administrator\n");
        }
    } else {
        singularity_message(VERBOSE, "Not invoking SUID mode: running as root\n");
    }

#endif /* SINGULARITY_SUID */

    if ( ( image = envar_path("SINGULARITY_IMAGE") ) == NULL ) {
        singularity_abort(255, "SINGULARITY_IMAGE not defined!\n");
    }

    singularity_action_init();
    singularity_rootfs_init(image);
    singularity_sessiondir_init(image);

    free(image);

    singularity_ns_unshare();

    singularity_rootfs_mount();

    singularity_rootfs_check();

    singularity_file();

    singularity_mount();

    singularity_rootfs_chroot();

    singularity_action_do(argc, argv);

    return(0);

}
Ejemplo n.º 12
0
void singularity_mount_scratch(void) {
    char *container_dir = singularity_rootfs_dir();
    char *scratchdir_path;
    char *tmpdir_path;
    char *sourcedir_path;
    int r;

    singularity_message(DEBUG, "Getting SINGULARITY_SCRATCHDIR from environment\n");
    if ( ( scratchdir_path = envar_path("SINGULARITY_SCRATCHDIR") ) == NULL ) {
        singularity_message(DEBUG, "Not mounting scratch directory: Not requested\n");
        return;
    }

    singularity_message(DEBUG, "Checking configuration file for 'user bind control'\n");
    if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 0 ) {
        singularity_message(VERBOSE, "Not mounting scratch: user bind control is disabled by system administrator\n");
        return;
    }

#ifndef SINGULARITY_NO_NEW_PRIVS
        singularity_message(WARNING, "Not mounting scratch: host does not support PR_SET_NO_NEW_PRIVS\n");
        return;
#endif  

    singularity_message(DEBUG, "Checking if overlay is enabled\n");
    int overlayfs_enabled = singularity_rootfs_overlay_enabled() > 0;
    if ( !overlayfs_enabled ) {
        singularity_message(VERBOSE, "Overlay is not enabled: cannot make directories not preexisting in container scratch.\n");
    }

    singularity_message(DEBUG, "Checking SINGULARITY_WORKDIR from environment\n");
    if ( ( tmpdir_path = envar_path("SINGULARITY_WORKDIR") ) == NULL ) {
        if ( ( tmpdir_path = singularity_sessiondir_get() ) == NULL ) {
            singularity_message(ERROR, "Could not identify a suitable temporary directory for scratch\n");
            return;
        }
    }

    sourcedir_path = joinpath(tmpdir_path, "/scratch");

    free(tmpdir_path);

    char *outside_token = NULL;
    char *current = strtok_r(strdup(scratchdir_path), ",", &outside_token);

    free(scratchdir_path);

    while ( current != NULL ) {

        char *full_sourcedir_path = joinpath(sourcedir_path, basename(strdup(current)));

        if ( s_mkpath(full_sourcedir_path, 0750) < 0 ) {
             singularity_message(ERROR, "Could not create scratch working directory %s: %s\n", full_sourcedir_path, strerror(errno));
             ABORT(255);
         }

        if (overlayfs_enabled) {
            singularity_priv_escalate();
            singularity_message(DEBUG, "Creating scratch directory inside container\n");
            r = s_mkpath(joinpath(container_dir, current), 0755);
            singularity_priv_drop();
            if ( r < 0 ) {
                singularity_message(VERBOSE, "Skipping scratch directory mount, could not create dir inside container %s: %s\n", current, strerror(errno));
                return;
            }
        }

        singularity_priv_escalate();
        singularity_message(VERBOSE, "Binding '%s' to '%s/%s'\n", full_sourcedir_path, container_dir, current);
        r = mount(full_sourcedir_path, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL);
        if ( singularity_priv_userns_enabled() != 1 ) {
            r += mount(NULL, joinpath(container_dir, current), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL);
        }
        singularity_priv_drop();
        if ( r < 0 ) {
            singularity_message(WARNING, "Could not bind scratch directory into container %s: %s\n", full_sourcedir_path, strerror(errno));
            ABORT(255);
        }

        current = strtok_r(NULL, ",", &outside_token);
        // Ignore empty directories.
        while (current && !strlength(current, 1024)) {current = strtok_r(NULL, ",", &outside_token);}
    }
    return;
}
Ejemplo n.º 13
0
char *singularity_rootfs_dir(void) {
    singularity_message(DEBUG, "Returning singularity_rootfs_dir: %s\n", joinpath(mount_point, OVERLAY_FINAL));
    return(joinpath(mount_point, OVERLAY_FINAL));
}
Ejemplo n.º 14
0
int singularity_rootfs_mount(void) {
    char *rootfs_source = joinpath(mount_point, ROOTFS_SOURCE);
    char *overlay_mount = joinpath(mount_point, OVERLAY_MOUNT);
    char *overlay_upper = joinpath(mount_point, OVERLAY_UPPER);
    char *overlay_work  = joinpath(mount_point, OVERLAY_WORK);
    char *overlay_final = joinpath(mount_point, OVERLAY_FINAL);

    singularity_message(DEBUG, "Checking 'container dir' mount location: %s\n", mount_point);
    if ( is_dir(mount_point) < 0 ) {
        singularity_priv_escalate();
        singularity_message(VERBOSE, "Creating container dir: %s\n", mount_point);
        if ( s_mkpath(mount_point, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create directory: %s\n", mount_point);
            ABORT(255);
        }
        singularity_priv_drop();
    }

    singularity_message(DEBUG, "Checking for rootfs_source directory: %s\n", rootfs_source);
    if ( is_dir(rootfs_source) < 0 ) {
        singularity_priv_escalate();
        singularity_message(VERBOSE, "Creating container destination dir: %s\n", rootfs_source);
        if ( s_mkpath(rootfs_source, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create directory: %s\n", rootfs_source);
            ABORT(255);
        }
        singularity_priv_drop();
    }

    singularity_message(DEBUG, "Checking for overlay_mount directory: %s\n", overlay_mount);
    if ( is_dir(overlay_mount) < 0 ) {
        singularity_priv_escalate();
        singularity_message(VERBOSE, "Creating container mount dir: %s\n", overlay_mount);
        if ( s_mkpath(overlay_mount, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create directory: %s\n", overlay_mount);
            ABORT(255);
        }
        singularity_priv_drop();
    }

    singularity_message(DEBUG, "Checking for overlay_final directory: %s\n", overlay_final);
    if ( is_dir(overlay_final) < 0 ) {
        singularity_priv_escalate();
        singularity_message(VERBOSE, "Creating overlay final dir: %s\n", overlay_final);
        if ( s_mkpath(overlay_final, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create directory: %s\n", overlay_final);
            ABORT(255);
        }
        singularity_priv_drop();
    }

    if ( module == ROOTFS_IMAGE ) {
        if ( rootfs_image_mount() < 0 ) {
            singularity_message(ERROR, "Failed mounting image, aborting...\n");
            ABORT(255);
        }
    } else if ( module == ROOTFS_DIR ) {
        if ( rootfs_dir_mount() < 0 ) {
            singularity_message(ERROR, "Failed mounting directory, aborting...\n");
            ABORT(255);
        }
    } else if ( module == ROOTFS_SQUASHFS ) {
        if ( rootfs_squashfs_mount() < 0 ) {
            singularity_message(ERROR, "Failed mounting SquashFS, aborting...\n");
            ABORT(255);
        }
    } else {
        singularity_message(ERROR, "Internal error, no rootfs type defined\n");
        ABORT(255);
    }

    singularity_message(DEBUG, "OverlayFS enabled by host build\n");
    if ( singularity_config_get_bool(ENABLE_OVERLAY) <= 0 ) {
        singularity_message(VERBOSE3, "Not enabling overlayFS via configuration\n");
    } else if ( envar_defined("SINGULARITY_DISABLE_OVERLAYFS") == TRUE ) {
        singularity_message(VERBOSE3, "Not enabling overlayFS via environment\n");
    } else if ( envar_defined("SINGULARITY_WRITABLE") == TRUE ) {
        singularity_message(VERBOSE3, "Not enabling overlayFS, image mounted writablable\n");
    } else {
#ifdef SINGULARITY_OVERLAYFS
        int overlay_options_len = strlength(rootfs_source, PATH_MAX) + strlength(overlay_upper, PATH_MAX) + strlength(overlay_work, PATH_MAX) + 50;
        char *overlay_options = (char *) malloc(overlay_options_len);
        snprintf(overlay_options, overlay_options_len, "lowerdir=%s,upperdir=%s,workdir=%s", rootfs_source, overlay_upper, overlay_work); // Flawfinder: ignore

        singularity_priv_escalate();
        singularity_message(DEBUG, "Mounting overlay tmpfs: %s\n", overlay_mount);
        if ( mount("tmpfs", overlay_mount, "tmpfs", MS_NOSUID, "size=1m") < 0 ){
            singularity_message(ERROR, "Failed to mount overlay tmpfs %s: %s\n", overlay_mount, strerror(errno));
            ABORT(255);
        }

        singularity_message(DEBUG, "Creating upper overlay directory: %s\n", overlay_upper);
        if ( s_mkpath(overlay_upper, 0755) < 0 ) {
            singularity_message(ERROR, "Failed creating upper overlay directory %s: %s\n", overlay_upper, strerror(errno));
            ABORT(255);
        }

        singularity_message(DEBUG, "Creating overlay work directory: %s\n", overlay_work);
        if ( s_mkpath(overlay_work, 0755) < 0 ) {
            singularity_message(ERROR, "Failed creating overlay work directory %s: %s\n", overlay_work, strerror(errno));
            ABORT(255);
        }

        singularity_message(VERBOSE, "Mounting overlay with options: %s\n", overlay_options);
        if ( mount("overlay", overlay_final, "overlay", MS_NOSUID, overlay_options) < 0 ){
            singularity_message(ERROR, "Could not create overlay: %s\n", strerror(errno));
            ABORT(255); 
        }
        free(overlay_options);
        singularity_priv_drop();

        overlay_enabled = 1;
#else /* SINGULARITY_OVERLAYFS */
        singularity_message(WARNING, "OverlayFS not supported by host build\n");
#endif /* SINGULARITY_OVERLAYFS */
    }

    if ( overlay_enabled != 1 ) {
        singularity_priv_escalate();
        singularity_message(VERBOSE3, "Binding the ROOTFS_SOURCE to OVERLAY_FINAL (%s->%s)\n", joinpath(mount_point, ROOTFS_SOURCE), joinpath(mount_point, OVERLAY_FINAL));
        if ( mount(joinpath(mount_point, ROOTFS_SOURCE), joinpath(mount_point, OVERLAY_FINAL), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
            singularity_message(ERROR, "There was an error binding the path %s: %s\n", joinpath(mount_point, ROOTFS_SOURCE), strerror(errno));
            ABORT(255);
        }
        singularity_priv_drop();
    }

    return(0);
}
Ejemplo n.º 15
0
/*
 * rewrite .newsrc and position group at specifed position
 */
t_bool
pos_group_in_newsrc(
	struct t_group *group,
	int pos)
{
	FILE *fp_in = NULL, *fp_out = NULL;
	FILE *fp_sub = NULL, *fp_unsub = NULL;
	char *newsgroup = NULL;
	char *line;
	char buf[HEADER_LEN];
	char sub[HEADER_LEN];
	char unsub[HEADER_LEN];
	int subscribed_pos = 1;
	size_t group_len;
	t_bool found = FALSE;
	t_bool newnewsrc_created = FALSE;
	t_bool option_line = FALSE;
	t_bool repositioned = FALSE;
	t_bool ret_code = FALSE;
	t_bool sub_created = FALSE;
	t_bool unsub_created = FALSE;

	if (no_write)
		goto rewrite_group_done;

	if ((fp_in = fopen(newsrc, "r")) == NULL)
		goto rewrite_group_done;

	if ((fp_out = fopen(newnewsrc, "w" FOPEN_OPTS)) == NULL)
		goto rewrite_group_done;

	newnewsrc_created = TRUE;

#ifndef M_OS2
	if (newsrc_mode)
		fchmod(fileno(fp_out), newsrc_mode);
#endif /* !M_OS2 */

#ifdef VMS
	joinpath(buf, TMPDIR, "subrc");
	sprintf(sub, "%s.%d", buf, (int) process_id);

	joinpath(buf, TMPDIR, "unsubrc");
	sprintf(unsub, "%s.%d", buf, (int) process_id);
#else
	joinpath(buf, TMPDIR, ".subrc");
	sprintf(sub, "%s.%d", buf, (int) process_id);

	joinpath(buf, TMPDIR, ".unsubrc");
	sprintf(unsub, "%s.%d", buf, (int) process_id);
#endif /* !VMS */

	if ((fp_sub = fopen(sub, "w" FOPEN_OPTS)) == NULL)
		goto rewrite_group_done;

	sub_created = TRUE;

	if ((fp_unsub = fopen(unsub, "w" FOPEN_OPTS)) == NULL)
		goto rewrite_group_done;

	unsub_created = TRUE;

	/*
	 * split newsrc into subscribed and unsubscribed to files
	 */
	group_len = strlen(group->name);

	while ((line = tin_fgets(fp_in, FALSE)) != NULL) {
		if (STRNCMPEQ(group->name, line, group_len) && line[group_len] == SUBSCRIBED) {
			newsgroup = my_strdup(line);		/* Take a copy of this line */
			found = TRUE;
			continue;
		} else if (strchr(line, SUBSCRIBED) != NULL) {
			write_newsrc_line(fp_sub, line);
		} else if (strchr(line, UNSUBSCRIBED) != NULL) {
			write_newsrc_line(fp_unsub, line);
		} else {								/* options line at beginning of .newsrc */
			fprintf(fp_sub, "%s\n", line);
			option_line = TRUE;
		}
	}

	if (ferror(fp_sub) || fclose(fp_sub) || ferror(fp_unsub) || fclose(fp_unsub)) {
		error_message(_(txt_filesystem_full), NEWSRC_FILE);
		fp_sub = fp_unsub = NULL;
		goto rewrite_group_done;
	}

	fp_sub = fp_unsub = NULL;
	fclose(fp_in);
	fp_in = NULL;

	/*
	 * The group to be moved cannot be found, so give up now
	 */
	if (!found)
		goto rewrite_group_done;

	/*
	 * write subscribed groups & repositioned group to newnewsrc
	 */
	if ((fp_sub = fopen(sub, "r")) == NULL)
		goto rewrite_group_done;

	while ((line = tin_fgets(fp_sub, FALSE)) != NULL) {
		if (option_line) {
			if (strchr(line, SUBSCRIBED) == NULL && strchr(line, UNSUBSCRIBED) == NULL) {
				fprintf(fp_out, "%s\n", line);
				continue;
			} else
				option_line = FALSE;
		}

		if (pos == subscribed_pos) {
			write_newsrc_line(fp_out, newsgroup);
			repositioned = TRUE;
		}

		fprintf(fp_out, "%s\n", line);

		subscribed_pos++;
	}

	if (!repositioned) {
		write_newsrc_line(fp_out, newsgroup);
		repositioned = TRUE;
	}

	/*
	 * append unsubscribed groups file to newnewsrc
	 */
	if ((fp_unsub = fopen(unsub, "r")) == NULL)
		goto rewrite_group_done;

	while ((line = tin_fgets(fp_unsub, FALSE)) != NULL)
		fprintf(fp_out, "%s\n", line);

	/*
	 * Try and cleanly close out the newnewsrc file
	 */
	if (ferror(fp_out) || fclose(fp_out))
		error_message(_(txt_filesystem_full), NEWSRC_FILE);
	else {
		if (repositioned) {
			rename_file(newnewsrc, newsrc);
			ret_code = TRUE;
		}
	}
	fp_out = NULL;
	newnewsrc_created = FALSE;

rewrite_group_done:
	if (fp_in != NULL)
		fclose(fp_in);

	if (fp_out != NULL)
		fclose(fp_out);

	if (fp_sub != NULL)
		fclose(fp_sub);

	if (fp_unsub != NULL)
		fclose(fp_unsub);

	if (newnewsrc_created)
		unlink(newnewsrc);

	if (sub_created)
		unlink(sub);

	if (unsub_created)
		unlink(unsub);

	FreeIfNeeded(newsgroup);

	return ret_code;
}
Ejemplo n.º 16
0
void
msg_write_signature(
	FILE *fp,
	t_bool include_dot_signature,
	struct t_group *thisgroup)
{
	FILE *fixfp;
	FILE *sigfp;
	char cwd[PATH_LEN];
	char path[PATH_LEN];
	char pathfixed[PATH_LEN];

#ifdef NNTP_INEWS
	if (read_news_via_nntp && 0 == strcasecmp(tinrc.inews_prog, INTERNAL_CMD))
		include_dot_signature = TRUE;
#endif /* NNTP_INEWS */

	if (thisgroup && !thisgroup->bogus) {
		if (!strcmp(thisgroup->attribute->sigfile, "--none"))
			return;

		/* TODO: handle DONT_HAVE_PIPING case */
#ifndef DONT_HAVE_PIPING
		if (thisgroup->attribute->sigfile[0] == '!') {
			FILE *pipe_fp;
			char *sigcmd;
			char cmd[PATH_LEN];
			fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n");
			sigcmd = my_malloc(strlen(thisgroup->attribute->sigfile + 1) + strlen(thisgroup->name) + 4);
			sprintf(sigcmd, "%s \"%s\"", thisgroup->attribute->sigfile + 1, thisgroup->name);

			if ((pipe_fp = popen(sigcmd, "r")) != NULL) {
				while (fgets(cmd, PATH_LEN, pipe_fp))
					fputs(cmd, fp);
				pclose(pipe_fp);
			} /* else issue an error-message? */
			free(sigcmd);

			return;
		}
#endif /* !DONT_HAVE_PIPING */
		get_cwd(cwd);

		if (!strfpath(thisgroup->attribute->sigfile, path, sizeof(path), thisgroup)) {
			if (!strfpath(tinrc.sigfile, path, sizeof(path), thisgroup))
				joinpath(path, homedir, ".Sig");
		}

		/*
		 * Check to see if sigfile is a directory & if it is
		 * generate a random signature from sigs in sigdir. If
		 * the file path/.sigfixed or ~/.sigfixed exists (fixed
		 * part of random sig) then read it in first and append
		 * the random sig part onto the end.
		 */
		if ((sigfp = open_random_sig(path)) != NULL) {
#ifdef DEBUG
			if (debug == 2)
				error_message("USING random sig=[%s]", sigfile);
#endif /* DEBUG */
			fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n");
			joinpath(pathfixed, path, ".sigfixed");
#ifdef DEBUG
			if (debug == 2)
				error_message("TRYING fixed sig=[%s]", pathfixed);
#endif /* DEBUG */
			if ((fixfp = fopen(pathfixed, "r")) != NULL) {
				copy_fp(fixfp, fp);
				fclose(fixfp);
			} else {
				joinpath(pathfixed, homedir, ".sigfixed");
#ifdef DEBUG
				if (debug == 2)
					error_message("TRYING fixed sig=[%s]", pathfixed);
#endif /* DEBUG */
				if ((fixfp = fopen(pathfixed, "r")) != NULL) {
					copy_fp(fixfp, fp);
					fclose(fixfp);
				}
			}
			copy_fp(sigfp, fp);
			fclose(sigfp);
			my_chdir(cwd);
			return;
		}
	}

	if ((sigfp = fopen(path, "r")) != NULL) {
		fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n");
		copy_fp(sigfp, fp);
		fclose(sigfp);
		return;
	}

	/*
	 * Use ~/.signature as a last resort, but only if mailing or
	 * using internal inews (external inews appends it automagically).
	 */
	if ((sigfp = fopen(default_signature, "r")) != NULL) {
		if (include_dot_signature) {
			fprintf(fp, "\n%s", tinrc.sigdashes ? SIGDASHES : "\n");
			copy_fp(sigfp, fp);
		}
		fclose(sigfp);
	}
}
Ejemplo n.º 17
0
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
   bytes long.
*/
static int
search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix)
{
    size_t n;
    wchar_t *vpath;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        wchar_t *delim;
        wcsncpy(prefix, home, MAXPATHLEN);
        prefix[MAXPATHLEN] = L'\0';
        delim = wcschr(prefix, DELIM);
        if (delim)
            *delim = L'\0';
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        return 1;
    }

    /* Check to see if argv[0] is in the build directory */
    wcsncpy(prefix, argv0_path, MAXPATHLEN);
    prefix[MAXPATHLEN] = L'\0';
    joinpath(prefix, L"Modules/Setup");
    if (isfile(prefix)) {
        /* Check VPATH to see if argv0_path is in the build directory. */
        vpath = _Py_char2wchar(VPATH, NULL);
        if (vpath != NULL) {
            wcsncpy(prefix, argv0_path, MAXPATHLEN);
            prefix[MAXPATHLEN] = L'\0';
            joinpath(prefix, vpath);
            PyMem_RawFree(vpath);
            joinpath(prefix, L"Lib");
            joinpath(prefix, LANDMARK);
            if (ismodule(prefix))
                return -1;
        }
    }

    /* Search from argv0_path, until root is found */
    copy_absolute(prefix, argv0_path, MAXPATHLEN+1);
    do {
        n = wcslen(prefix);
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        if (ismodule(prefix))
            return 1;
        prefix[n] = L'\0';
        reduce(prefix);
    } while (prefix[0]);

    /* Look at configure's PREFIX */
    wcsncpy(prefix, _prefix, MAXPATHLEN);
    prefix[MAXPATHLEN] = L'\0';
    joinpath(prefix, lib_python);
    joinpath(prefix, LANDMARK);
    if (ismodule(prefix))
        return 1;

    /* Fail */
    return 0;
}
Ejemplo n.º 18
0
static void
calculate_path(void)
{
    extern char *Py_GetProgramName(void);

    static char delimiter[2] = {DELIM, '\0'};
    static char separator[2] = {SEP, '\0'};
    char *pythonpath = PYTHONPATH;
    char *rtpypath = Py_GETENV("PYTHONPATH");
    char *home = Py_GetPythonHome();
    char *path = getenv("PATH");
    char *prog = Py_GetProgramName();
    char argv0_path[MAXPATHLEN+1];
    char zip_path[MAXPATHLEN+1];
    int pfound, efound; /* 1 if found; -1 if found build directory */
    char *buf;
    size_t bufsz;
    size_t prefixsz;
    char *defpath = pythonpath;
#ifdef WITH_NEXT_FRAMEWORK
    NSModule pythonModule;
#endif

	/* If there is no slash in the argv0 path, then we have to
	 * assume python is on the user's $PATH, since there's no
	 * other way to find a directory to start the search from.  If
	 * $PATH isn't exported, you lose.
	 */
	if (strchr(prog, SEP))
		strncpy(progpath, prog, MAXPATHLEN);
	else if (path) {
		while (1) {
			char *delim = strchr(path, DELIM);

			if (delim) {
				size_t len = delim - path;
				if (len > MAXPATHLEN)
					len = MAXPATHLEN;
				strncpy(progpath, path, len);
				*(progpath + len) = '\0';
			}
			else
				strncpy(progpath, path, MAXPATHLEN);

			joinpath(progpath, prog);
			if (isxfile(progpath))
				break;

			if (!delim) {
				progpath[0] = '\0';
				break;
			}
			path = delim + 1;
		}
	}
	else
		progpath[0] = '\0';
	if (progpath[0] != SEP)
		absolutize(progpath);
	strncpy(argv0_path, progpath, MAXPATHLEN);
	argv0_path[MAXPATHLEN] = '\0';

#ifdef WITH_NEXT_FRAMEWORK
	/* On Mac OS X we have a special case if we're running from a framework.
	** This is because the python home should be set relative to the library,
	** which is in the framework, not relative to the executable, which may
	** be outside of the framework. Except when we're in the build directory...
	*/
    pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
    /* Use dylib functions to find out where the framework was loaded from */
    buf = (char *)NSLibraryNameForModule(pythonModule);
    if (buf != NULL) {
        /* We're in a framework. */
        /* See if we might be in the build directory. The framework in the
        ** build directory is incomplete, it only has the .dylib and a few
        ** needed symlinks, it doesn't have the Lib directories and such.
        ** If we're running with the framework from the build directory we must
        ** be running the interpreter in the build directory, so we use the
        ** build-directory-specific logic to find Lib and such.
        */
        strncpy(argv0_path, buf, MAXPATHLEN);
        reduce(argv0_path);
        joinpath(argv0_path, lib_python);
        joinpath(argv0_path, LANDMARK);
        if (!ismodule(argv0_path)) {
                /* We are in the build directory so use the name of the
                   executable - we know that the absolute path is passed */
                strncpy(argv0_path, prog, MAXPATHLEN);
        }
        else {
                /* Use the location of the library as the progpath */
                strncpy(argv0_path, buf, MAXPATHLEN);
        }
    }
#endif

#if HAVE_READLINK
    {
        char tmpbuffer[MAXPATHLEN+1];
        int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
        while (linklen != -1) {
            /* It's not null terminated! */
            tmpbuffer[linklen] = '\0';
            if (tmpbuffer[0] == SEP)
                /* tmpbuffer should never be longer than MAXPATHLEN,
                   but extra check does not hurt */
                strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
            else {
                /* Interpret relative to progpath */
                reduce(argv0_path);
                joinpath(argv0_path, tmpbuffer);
            }
            linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
        }
    }
#endif /* HAVE_READLINK */

    reduce(argv0_path);
    /* At this point, argv0_path is guaranteed to be less than
       MAXPATHLEN bytes long.
    */

    if (!(pfound = search_for_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                "Could not find platform independent libraries <prefix>\n");
        strncpy(prefix, PREFIX, MAXPATHLEN);
        joinpath(prefix, lib_python);
    }
    else
        reduce(prefix);

    strncpy(zip_path, prefix, MAXPATHLEN);
    zip_path[MAXPATHLEN] = '\0';
    if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
        reduce(zip_path);
        reduce(zip_path);
    }
    else
        strncpy(zip_path, PREFIX, MAXPATHLEN);
    joinpath(zip_path, "lib/python00.zip");
    bufsz = strlen(zip_path);	/* Replace "00" with version */
    zip_path[bufsz - 6] = VERSION[0];
    zip_path[bufsz - 5] = VERSION[2];

    if (!(efound = search_for_exec_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                "Could not find platform dependent libraries <exec_prefix>\n");
        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
        joinpath(exec_prefix, "lib/lib-dynload");
    }
    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */

    if ((!pfound || !efound) && !Py_FrozenFlag)
        fprintf(stderr,
                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");

    /* Calculate size of return buffer.
     */
    bufsz = 0;

    if (rtpypath)
        bufsz += strlen(rtpypath) + 1;

    prefixsz = strlen(prefix) + 1;

    while (1) {
        char *delim = strchr(defpath, DELIM);

        if (defpath[0] != SEP)
            /* Paths are relative to prefix */
            bufsz += prefixsz;

        if (delim)
            bufsz += delim - defpath + 1;
        else {
            bufsz += strlen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += strlen(zip_path) + 1;
    bufsz += strlen(exec_prefix) + 1;

    /* This is the only malloc call in this file */
    buf = PyMem_Malloc(bufsz);

    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
        fprintf(stderr, "Using default static PYTHONPATH.\n");
        module_search_path = PYTHONPATH;
    }
    else {
        /* Run-time value of $PYTHONPATH goes first */
        if (rtpypath) {
            strcpy(buf, rtpypath);
            strcat(buf, delimiter);
        }
        else
            buf[0] = '\0';

        /* Next is the default zip path */
        strcat(buf, zip_path);
        strcat(buf, delimiter);

        /* Next goes merge of compile-time $PYTHONPATH with
         * dynamically located prefix.
         */
        defpath = pythonpath;
        while (1) {
            char *delim = strchr(defpath, DELIM);

            if (defpath[0] != SEP) {
                strcat(buf, prefix);
                strcat(buf, separator);
            }

            if (delim) {
                size_t len = delim - defpath + 1;
                size_t end = strlen(buf) + len;
                strncat(buf, defpath, len);
                *(buf + end) = '\0';
            }
            else {
                strcat(buf, defpath);
                break;
            }
            defpath = delim + 1;
        }
        strcat(buf, delimiter);

        /* Finally, on goes the directory for dynamic-load modules */
        strcat(buf, exec_prefix);

        /* And publish the results */
        module_search_path = buf;
    }

    /* Reduce prefix and exec_prefix to their essence,
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
     * If we're loading relative to the build directory,
     * return the compiled-in defaults instead.
     */
    if (pfound > 0) {
        reduce(prefix);
        reduce(prefix);
    }
    else
        strncpy(prefix, PREFIX, MAXPATHLEN);

    if (efound > 0) {
        reduce(exec_prefix);
        reduce(exec_prefix);
        reduce(exec_prefix);
    }
    else
        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
}
Ejemplo n.º 19
0
static void
calculate_path(void)
{
    extern wchar_t *Py_GetProgramName(void);

    static wchar_t delimiter[2] = {DELIM, '\0'};
    static wchar_t separator[2] = {SEP, '\0'};
    char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */
    wchar_t rtpypath[MAXPATHLEN+1];
    wchar_t *home = Py_GetPythonHome();
    char *_path = getenv("PATH");
    wchar_t *path_buffer = NULL;
    wchar_t *path = NULL;
    wchar_t *prog = Py_GetProgramName();
    wchar_t argv0_path[MAXPATHLEN+1];
    wchar_t zip_path[MAXPATHLEN+1];
    int pfound, efound; /* 1 if found; -1 if found build directory */
    wchar_t *buf;
    size_t bufsz;
    size_t prefixsz;
    wchar_t *defpath;
#ifdef WITH_NEXT_FRAMEWORK
    NSModule pythonModule;
#endif
#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    uint32_t nsexeclength = MAXPATHLEN;
#else
    unsigned long nsexeclength = MAXPATHLEN;
#endif
    char execpath[MAXPATHLEN+1];
#endif
    wchar_t *_pythonpath, *_prefix, *_exec_prefix;

    _pythonpath = _Py_char2wchar(PYTHONPATH, NULL);
    _prefix = _Py_char2wchar(PREFIX, NULL);
    _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL);

    if (!_pythonpath || !_prefix || !_exec_prefix) {
        Py_FatalError(
            "Unable to decode path variables in getpath.c: "
            "memory error");
    }

    if (_path) {
        path_buffer = _Py_char2wchar(_path, NULL);
        path = path_buffer;
    }

    /* If there is no slash in the argv0 path, then we have to
     * assume python is on the user's $PATH, since there's no
     * other way to find a directory to start the search from.  If
     * $PATH isn't exported, you lose.
     */
    if (wcschr(prog, SEP))
        wcsncpy(progpath, prog, MAXPATHLEN);
#ifdef __APPLE__
     /* On Mac OS X, if a script uses an interpreter of the form
      * "#!/opt/python2.3/bin/python", the kernel only passes "python"
      * as argv[0], which falls through to the $PATH search below.
      * If /opt/python2.3/bin isn't in your path, or is near the end,
      * this algorithm may incorrectly find /usr/bin/python. To work
      * around this, we can use _NSGetExecutablePath to get a better
      * hint of what the intended interpreter was, although this
      * will fail if a relative path was used. but in that case,
      * absolutize() should help us out below
      */
    else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) {
        size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1);
        if (r == (size_t)-1 || r > MAXPATHLEN) {
            /* Could not convert execpath, or it's too long. */
            progpath[0] = '\0';
        }
    }
#endif /* __APPLE__ */
    else if (path) {
        while (1) {
            wchar_t *delim = wcschr(path, DELIM);

            if (delim) {
                size_t len = delim - path;
                if (len > MAXPATHLEN)
                    len = MAXPATHLEN;
                wcsncpy(progpath, path, len);
                *(progpath + len) = '\0';
            }
            else
                wcsncpy(progpath, path, MAXPATHLEN);

            joinpath(progpath, prog);
            if (isxfile(progpath))
                break;

            if (!delim) {
                progpath[0] = L'\0';
                break;
            }
            path = delim + 1;
        }
    }
    else
        progpath[0] = '\0';
    if (path_buffer != NULL)
        PyMem_Free(path_buffer);
    if (progpath[0] != SEP && progpath[0] != '\0')
        absolutize(progpath);
    wcsncpy(argv0_path, progpath, MAXPATHLEN);
    argv0_path[MAXPATHLEN] = '\0';

#ifdef WITH_NEXT_FRAMEWORK
    /* On Mac OS X we have a special case if we're running from a framework.
    ** This is because the python home should be set relative to the library,
    ** which is in the framework, not relative to the executable, which may
    ** be outside of the framework. Except when we're in the build directory...
    */
    pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
    /* Use dylib functions to find out where the framework was loaded from */
    buf = (wchar_t *)NSLibraryNameForModule(pythonModule);
    if (buf != NULL) {
        /* We're in a framework. */
        /* See if we might be in the build directory. The framework in the
        ** build directory is incomplete, it only has the .dylib and a few
        ** needed symlinks, it doesn't have the Lib directories and such.
        ** If we're running with the framework from the build directory we must
        ** be running the interpreter in the build directory, so we use the
        ** build-directory-specific logic to find Lib and such.
        */
        wcsncpy(argv0_path, buf, MAXPATHLEN);
        reduce(argv0_path);
        joinpath(argv0_path, lib_python);
        joinpath(argv0_path, LANDMARK);
        if (!ismodule(argv0_path)) {
            /* We are in the build directory so use the name of the
               executable - we know that the absolute path is passed */
            wcsncpy(argv0_path, progpath, MAXPATHLEN);
        }
        else {
            /* Use the location of the library as the progpath */
            wcsncpy(argv0_path, buf, MAXPATHLEN);
        }
    }
#endif

#if HAVE_READLINK
    {
        wchar_t tmpbuffer[MAXPATHLEN+1];
        int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN);
        while (linklen != -1) {
            if (tmpbuffer[0] == SEP)
                /* tmpbuffer should never be longer than MAXPATHLEN,
                   but extra check does not hurt */
                wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN);
            else {
                /* Interpret relative to progpath */
                reduce(argv0_path);
                joinpath(argv0_path, tmpbuffer);
            }
            linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN);
        }
    }
#endif /* HAVE_READLINK */

    reduce(argv0_path);
    /* At this point, argv0_path is guaranteed to be less than
       MAXPATHLEN bytes long.
    */

    if (!(pfound = search_for_prefix(argv0_path, home, _prefix))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                "Could not find platform independent libraries <prefix>\n");
        wcsncpy(prefix, _prefix, MAXPATHLEN);
        joinpath(prefix, lib_python);
    }
    else
        reduce(prefix);

    wcsncpy(zip_path, prefix, MAXPATHLEN);
    zip_path[MAXPATHLEN] = L'\0';
    if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
        reduce(zip_path);
        reduce(zip_path);
    }
    else
        wcsncpy(zip_path, _prefix, MAXPATHLEN);
    joinpath(zip_path, L"lib/python00.zip");
    bufsz = wcslen(zip_path);   /* Replace "00" with version */
    zip_path[bufsz - 6] = VERSION[0];
    zip_path[bufsz - 5] = VERSION[2];

    if (!(efound = search_for_exec_prefix(argv0_path, home, _exec_prefix))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                "Could not find platform dependent libraries <exec_prefix>\n");
        wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
        joinpath(exec_prefix, L"lib/lib-dynload");
    }
    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */

    if ((!pfound || !efound) && !Py_FrozenFlag)
        fprintf(stderr,
                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");

    /* Calculate size of return buffer.
     */
    bufsz = 0;

    if (_rtpypath) {
        size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t));
        if (s == (size_t)-1 || s >=sizeof(rtpypath))
            /* XXX deal with errors more gracefully */
            _rtpypath = NULL;
        if (_rtpypath)
            bufsz += wcslen(rtpypath) + 1;
    }

    defpath = _pythonpath;
    prefixsz = wcslen(prefix) + 1;
    while (1) {
        wchar_t *delim = wcschr(defpath, DELIM);

        if (defpath[0] != SEP)
            /* Paths are relative to prefix */
            bufsz += prefixsz;

        if (delim)
            bufsz += delim - defpath + 1;
        else {
            bufsz += wcslen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += wcslen(zip_path) + 1;
    bufsz += wcslen(exec_prefix) + 1;

    /* This is the only malloc call in this file */
    buf = (wchar_t *)PyMem_Malloc(bufsz*sizeof(wchar_t));

    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
        fprintf(stderr, "Using default static PYTHONPATH.\n");
        module_search_path = L"" PYTHONPATH;
    }
    else {
        /* Run-time value of $PYTHONPATH goes first */
        if (_rtpypath) {
            wcscpy(buf, rtpypath);
            wcscat(buf, delimiter);
        }
        else
            buf[0] = '\0';

        /* Next is the default zip path */
        wcscat(buf, zip_path);
        wcscat(buf, delimiter);

        /* Next goes merge of compile-time $PYTHONPATH with
         * dynamically located prefix.
         */
        defpath = _pythonpath;
        while (1) {
            wchar_t *delim = wcschr(defpath, DELIM);

            if (defpath[0] != SEP) {
                wcscat(buf, prefix);
                wcscat(buf, separator);
            }

            if (delim) {
                size_t len = delim - defpath + 1;
                size_t end = wcslen(buf) + len;
                wcsncat(buf, defpath, len);
                *(buf + end) = '\0';
            }
            else {
                wcscat(buf, defpath);
                break;
            }
            defpath = delim + 1;
        }
        wcscat(buf, delimiter);

        /* Finally, on goes the directory for dynamic-load modules */
        wcscat(buf, exec_prefix);

        /* And publish the results */
        module_search_path = buf;
    }

    /* Reduce prefix and exec_prefix to their essence,
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
     * If we're loading relative to the build directory,
     * return the compiled-in defaults instead.
     */
    if (pfound > 0) {
        reduce(prefix);
        reduce(prefix);
        /* The prefix is the root directory, but reduce() chopped
         * off the "/". */
        if (!prefix[0])
                wcscpy(prefix, separator);
    }
    else
        wcsncpy(prefix, _prefix, MAXPATHLEN);

    if (efound > 0) {
        reduce(exec_prefix);
        reduce(exec_prefix);
        reduce(exec_prefix);
        if (!exec_prefix[0])
                wcscpy(exec_prefix, separator);
    }
    else
        wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);

    PyMem_Free(_pythonpath);
    PyMem_Free(_prefix);
    PyMem_Free(_exec_prefix);
}
Ejemplo n.º 20
0
/*
 * get_newsrcname()
 * get name of newsrc file with given name of nntp server
 * returns TRUE if name was found, FALSE if the search failed
 */
int
get_newsrcname(
	char *newsrc_name,
	const char *nntpserver_name) /* return value is always ignored */
{
	FILE *fp;
	char *line_entry;
	char line[LEN];
	char name_found[PATH_LEN];
	int line_entry_counter;
	int found = 0;
	t_bool do_cpy = FALSE;

	if ((fp = fopen(local_newsrctable_file, "r")) != NULL) {
		while ((fgets(line, (int) sizeof(line), fp) != NULL) && (found != 1)) {
			line_entry_counter = 0;

			if (!strchr("# ;", line[0])) {
				while ((line_entry = strtok(line_entry_counter ? NULL : line, " \t\n")) != NULL) {
					line_entry_counter++;

					if ((line_entry_counter == 1) && (!strcasecmp(line_entry, nntpserver_name))) {
						found = 1;
						do_cpy = TRUE;
					}

					if ((line_entry_counter == 1) && ((!strcasecmp(line_entry, "default")) || (!strcmp(line_entry, "*")))) {
						found = 2;
						do_cpy = TRUE;
					}
					if (do_cpy && (line_entry_counter == 2)) {
						strcpy(name_found, line_entry);
						do_cpy = FALSE;
					}
				}
			}
		}
		fclose(fp);
		if (found) {
			char dir[PATH_LEN];
			char tmp_newsrc[PATH_LEN];
			int error = 0;

			if (!strfpath(name_found, tmp_newsrc, sizeof(tmp_newsrc), NULL)) {
					my_fprintf(stderr, _("couldn't expand %s\n"), name_found);
					error = 1;
			} else {
				if (tmp_newsrc[0] == '/')
					(void) strcpy(newsrc_name, tmp_newsrc);
				else
					joinpath(newsrc_name, homedir, tmp_newsrc);
			}
			(void) strcpy(dir, newsrc_name);
			if (strchr(dir, '/'))
				*strrchr(dir, '/') = (char) 0;

			if (!error) {
			/* FIXME - write a global permssion check routine */
				if (access(dir, X_OK)) {
					my_fprintf(stderr, _(txt_error_no_enter_permission), dir);
					error = 1;
				} else if (access(newsrc_name, F_OK)) {
					my_fprintf(stderr, _(txt_error_no_such_file), newsrc_name);
					error = 2;
				} else if (access(dir, R_OK)) {
					my_fprintf(stderr, _(txt_error_no_read_permission), dir);
					error = 1;
				} else if (access(newsrc_name, R_OK)) {
					my_fprintf(stderr, _(txt_error_no_read_permission), newsrc_name);
					error = 1;
				} else if (access(dir, W_OK)) {
					my_fprintf(stderr, _(txt_error_no_write_permission), dir);
					error = 1;
				} else if (access(newsrc_name, W_OK)) {
					my_fprintf(stderr, _(txt_error_no_write_permission), newsrc_name);
					error = 1;
				}
			}
			if (error) {
				char ch;
				char default_ch = map_to_local(iKeyNrctblAlternative, &menukeymap.nrctbl_create);

				do {
					/* very ugly code, but curses is not initialized yet */
					if (error >= 2) {
						default_ch = map_to_local(iKeyNrctblCreate, &menukeymap.nrctbl_create);
						printf("%s%c\b", _(txt_nrctbl_create), default_ch);
					} else
						printf("%s%c\b", _(txt_nrctbl_default), default_ch);

					if ((ch = (char) ReadCh()) == '\r' || ch == '\n')
						ch = default_ch;
				} while (!strchr(menukeymap.nrctbl_create.localkeys, ch));
				printf("%c\n", ch);

				switch (map_to_default(ch, &menukeymap.nrctbl_create)) {
					case iKeyNrctblCreate:
						/* FIXME this doesn't check if we could create the file */
						return TRUE;

					case iKeyNrctblDefault:
						joinpath(newsrc_name, homedir, ".newsrc");
						return TRUE;

					case iKeyNrctblAlternative:
						sprintf(name_found, ".newsrc-%s", nntpserver_name);
						joinpath(newsrc_name, homedir, name_found);
						return TRUE;

					case iKeyNrctblQuit:
						exit(EXIT_SUCCESS);
						/* keep lint quiet: */
						/* FALLTHROUGH */

					case ESC:
					default:
						return TRUE;
				}
			}
			return TRUE;
		}
	} else
		write_newsrctable_file();

	return FALSE;
}
Ejemplo n.º 21
0
static void
calculate_path(void)
{
    extern char *Py_GetProgramName(void);

    static char delimiter[2] = {DELIM, '\0'};
    static char separator[2] = {SEP, '\0'};
    char *pythonpath = PYTHONPATH;
    char *rtpypath = getenv("PYTHONPATH");
    char *home = Py_GetPythonHome();
    char *path = getenv("PATH");
    char *prog = Py_GetProgramName();
    char argv0_path[MAXPATHLEN+1];
    int pfound, efound; /* 1 if found; -1 if found build directory */
    char *buf;
    size_t bufsz;
    size_t prefixsz;
    char *defpath = pythonpath;
#ifdef WITH_NEXT_FRAMEWORK
    NSModule pythonModule;
#endif
	
#ifdef WITH_NEXT_FRAMEWORK
    /* XXX Need to check this code for buffer overflows */
    pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
    /* Use dylib functions to find out where the framework was loaded from */
    buf = NSLibraryNameForModule(pythonModule);
    if (buf != NULL) {
        /* We're in a framework. */
        strcpy(progpath, buf);

        /* Frameworks have support for versioning */
        strcpy(lib_python, "lib");
    }
    else {
        /* If we're not in a framework, fall back to the old way
           (even though NSNameOfModule() probably does the same thing.) */
#endif
	
	/* If there is no slash in the argv0 path, then we have to
	 * assume python is on the user's $PATH, since there's no
	 * other way to find a directory to start the search from.  If
	 * $PATH isn't exported, you lose.
	 */
	if (strchr(prog, SEP))
            strncpy(progpath, prog, MAXPATHLEN);
	else if (path) {
	    int bufspace = MAXPATHLEN;
            while (1) {
                char *delim = strchr(path, DELIM);

                if (delim) {
                    size_t len = delim - path;
		    if (len > bufspace)
			len = bufspace;
                    strncpy(progpath, path, len);
                    *(progpath + len) = '\0';
		    bufspace -= len;
                }
                else
                    strncpy(progpath, path, bufspace);

                joinpath(progpath, prog);
                if (isxfile(progpath))
                    break;

                if (!delim) {
                    progpath[0] = '\0';
                    break;
                }
                path = delim + 1;
            }
	}
	else
            progpath[0] = '\0';
#ifdef WITH_NEXT_FRAMEWORK
    }
#endif

    strncpy(argv0_path, progpath, MAXPATHLEN);
	
#if HAVE_READLINK
    {
        char tmpbuffer[MAXPATHLEN+1];
        int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
        while (linklen != -1) {
            /* It's not null terminated! */
            tmpbuffer[linklen] = '\0';
            if (tmpbuffer[0] == SEP)
		/* tmpbuffer should never be longer than MAXPATHLEN,
		   but extra check does not hurt */
                strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
            else {
                /* Interpret relative to progpath */
                reduce(argv0_path);
                joinpath(argv0_path, tmpbuffer);
            }
            linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
        }
    }
#endif /* HAVE_READLINK */

    reduce(argv0_path);
    /* At this point, argv0_path is guaranteed to be less than
       MAXPATHLEN bytes long.
    */

    if (!(pfound = search_for_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                    "Could not find platform independent libraries <prefix>\n");
        strncpy(prefix, PREFIX, MAXPATHLEN);
        joinpath(prefix, lib_python);
    }
    else
        reduce(prefix);
	
    if (!(efound = search_for_exec_prefix(argv0_path, home))) {
        if (!Py_FrozenFlag)
            fprintf(stderr,
                    "Could not find platform dependent libraries <exec_prefix>\n");
        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
        joinpath(exec_prefix, "lib/lib-dynload");
    }
    /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */

    if ((!pfound || !efound) && !Py_FrozenFlag)
        fprintf(stderr,
                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");

    /* Calculate size of return buffer.
     */
    bufsz = 0;

    if (rtpypath)
        bufsz += strlen(rtpypath) + 1;

    prefixsz = strlen(prefix) + 1;

    while (1) {
        char *delim = strchr(defpath, DELIM);

        if (defpath[0] != SEP)
            /* Paths are relative to prefix */
            bufsz += prefixsz;

        if (delim)
            bufsz += delim - defpath + 1;
        else {
            bufsz += strlen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += strlen(exec_prefix) + 1;

    /* This is the only malloc call in this file */
    buf = PyMem_Malloc(bufsz);

    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
        fprintf(stderr, "Using default static PYTHONPATH.\n");
        module_search_path = PYTHONPATH;
    }
    else {
        /* Run-time value of $PYTHONPATH goes first */
        if (rtpypath) {
            strcpy(buf, rtpypath);
            strcat(buf, delimiter);
        }
        else
            buf[0] = '\0';

        /* Next goes merge of compile-time $PYTHONPATH with
         * dynamically located prefix.
         */
        defpath = pythonpath;
        while (1) {
            char *delim = strchr(defpath, DELIM);

            if (defpath[0] != SEP) {
                strcat(buf, prefix);
                strcat(buf, separator);
            }

            if (delim) {
                size_t len = delim - defpath + 1;
                size_t end = strlen(buf) + len;
                strncat(buf, defpath, len);
                *(buf + end) = '\0';
            }
            else {
                strcat(buf, defpath);
                break;
            }
            defpath = delim + 1;
        }
        strcat(buf, delimiter);

        /* Finally, on goes the directory for dynamic-load modules */
        strcat(buf, exec_prefix);

        /* And publish the results */
        module_search_path = buf;
    }

    /* Reduce prefix and exec_prefix to their essence,
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
     * If we're loading relative to the build directory,
     * return the compiled-in defaults instead.
     */
    if (pfound > 0) {
        reduce(prefix);
        reduce(prefix);
    }
    else
        strncpy(prefix, PREFIX, MAXPATHLEN);

    if (efound > 0) {
        reduce(exec_prefix);
        reduce(exec_prefix);
        reduce(exec_prefix);
    }
    else
        strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
}
Ejemplo n.º 22
0
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN 
   bytes long.
*/
static int
search_for_prefix(char *argv0_path, char *home)
{
    size_t n;
    char *vpath;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        char *delim;
        strncpy(prefix, home, MAXPATHLEN);
        delim = strchr(prefix, DELIM);
        if (delim)
            *delim = '\0';
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        return 1;
    }

    /* Check to see if argv[0] is in the build directory */
    strcpy(prefix, argv0_path);
    joinpath(prefix, "Modules/Setup");
    if (isfile(prefix)) {
        /* Check VPATH to see if argv0_path is in the build directory.
         * Complication: the VPATH passed in is relative to the
         * Modules build directory and points to the Modules source
         * directory; we need it relative to the build tree and
         * pointing to the source tree.  Solution: chop off a leading
         * ".." (but only if it's there -- it could be an absolute
         * path) and chop off the final component (assuming it's
         * "Modules").
         */
        vpath = VPATH;
        if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/')
            vpath += 3;
        strcpy(prefix, argv0_path);
        joinpath(prefix, vpath);
        reduce(prefix);
        joinpath(prefix, "Lib");
        joinpath(prefix, LANDMARK);
        if (ismodule(prefix))
            return -1;
    }

    /* Search from argv0_path, until root is found */
    init_path_from_argv0(prefix, argv0_path);
    do {
        n = strlen(prefix);
        joinpath(prefix, lib_python);
        joinpath(prefix, LANDMARK);
        if (ismodule(prefix))
            return 1;
        prefix[n] = '\0';
        reduce(prefix);
    } while (prefix[0]);

    /* Look at configure's PREFIX */
    strncpy(prefix, PREFIX, MAXPATHLEN);
    joinpath(prefix, lib_python);
    joinpath(prefix, LANDMARK);
    if (ismodule(prefix))
        return 1;

    /* Fail */
    return 0;
}
Ejemplo n.º 23
0
int main(int argc, char ** argv) {
    FILE *containerimage_fp;
    FILE *loop_fp;
    FILE *config_fp;
    char *containerimage;
    char *containername;
    char *containerpath;
    char *username;
    char *command;
    char *tmpdir;
    char *loop_dev_lock;
    char *loop_dev_cache;
    char *loop_dev = 0;
    char *config_path;
    char *tmp_config_string;
    char cwd[PATH_MAX];
    int cwd_fd;
    int tmpdirlock_fd;
    int containerimage_fd;
    int loop_dev_lock_fd;
    int gid_list_count;
    int retval = 0;
    uid_t uid;
    gid_t gid;
    gid_t *gid_list;
    pid_t namespace_fork_pid = 0;
    struct passwd *pw;


//****************************************************************************//
// Init
//****************************************************************************//

    signal(SIGINT, sighandler);
    signal(SIGKILL, sighandler);
    signal(SIGQUIT, sighandler);

    openlog("Singularity", LOG_CONS | LOG_NDELAY, LOG_LOCAL0);

    // Get all user/group info
    uid = getuid();
    gid = getgid();
    gid_list_count = getgroups(0, NULL);
    gid_list = (gid_t *) malloc(sizeof(gid_t) * gid_list_count);
    if ( getgroups(gid_list_count, gid_list) < 0 ) {
        fprintf(stderr, "ABORT: Could not obtain current supplementary group list: %s\n", strerror(errno));
        return(255);
    }
    pw = getpwuid(uid);

    // Check to make sure we are installed correctly
    if ( seteuid(0) < 0 ) {
        fprintf(stderr, "ABORT: Check installation, must be performed by root.\n");
        return(255);
    }

    // Lets start off as the calling UID
    if ( seteuid(uid) < 0 ) {
        fprintf(stderr, "ABORT: Could not set effective uid to %d: %s\n", uid, strerror(errno));
        return(255);
    }
    if ( setegid(gid) < 0 ) {
        fprintf(stderr, "ABORT: Could not set effective gid to %d: %s\n", gid, strerror(errno));
        return(255);
    }

    username = pw->pw_name;
    containerimage = getenv("SINGULARITY_IMAGE");
    command = getenv("SINGULARITY_COMMAND");

    unsetenv("SINGULARITY_COMMAND");
    unsetenv("SINGULARITY_EXEC");

    config_path = (char *) malloc(strlen(SYSCONFDIR) + 30);
    snprintf(config_path, strlen(SYSCONFDIR) + 30, "%s/singularity/singularity.conf", SYSCONFDIR);

    // Figure out where we start
    if ( (cwd_fd = open(".", O_RDONLY)) < 0 ) {
        fprintf(stderr, "ABORT: Could not open cwd fd (%s)!\n", strerror(errno));
        return(1);
    }
    if ( getcwd(cwd, PATH_MAX) == NULL ) {
        fprintf(stderr, "Could not obtain current directory path: %s\n", strerror(errno));
        return(1);
    }

    if ( containerimage == NULL ) {
        fprintf(stderr, "ABORT: SINGULARITY_IMAGE undefined!\n");
        return(1);
    }

    if ( is_file(containerimage) != 0 ) {
        fprintf(stderr, "ABORT: Container image path is invalid: %s\n", containerimage);
        return(1);
    }

    if ( is_file(config_path) != 0 ) {
        fprintf(stderr, "ABORT: Configuration file not found: %s\n", config_path);
        return(255);
    }

    if ( is_owner(config_path, 0) != 0 ) {
        fprintf(stderr, "ABORT: Configuration file is not owned by root: %s\n", config_path);
        return(255);
    }

    // TODO: Offer option to only run containers owned by root (so root can approve
    // containers)
    if ( uid == 0 && is_owner(containerimage, 0) < 0 ) {
        fprintf(stderr, "ABORT: Root should only run containers that root owns!\n");
        return(1);
    }

    containername = basename(strdup(containerimage));

    tmpdir = strjoin("/tmp/.singularity-", file_id(containerimage));
    loop_dev_lock = joinpath(tmpdir, "loop_dev.lock");
    loop_dev_cache = joinpath(tmpdir, "loop_dev");

    containerpath = (char *) malloc(strlen(tmpdir) + 5);
    snprintf(containerpath, strlen(tmpdir) + 5, "%s/mnt", tmpdir);

    syslog(LOG_NOTICE, "User=%s[%d], Command=%s, Container=%s, CWD=%s, Arg1=%s", username, uid, command, containerimage, cwd, argv[1]);


//****************************************************************************//
// Setup
//****************************************************************************//


    if ( ( config_fp = fopen(config_path, "r") ) == NULL ) {
        fprintf(stderr, "ERROR: Could not open config file %s: %s\n", config_path, strerror(errno));
        return(255);
    }

    if ( getenv("SINGULARITY_WRITABLE") == NULL ) {
        if ( ( containerimage_fp = fopen(containerimage, "r") ) == NULL ) {
            fprintf(stderr, "ERROR: Could not open image read only %s: %s\n", containerimage, strerror(errno));
            return(255);
        }
        containerimage_fd = fileno(containerimage_fp);
        if ( flock(containerimage_fd, LOCK_SH | LOCK_NB) < 0 ) {
            fprintf(stderr, "ABORT: Image is locked by another process\n");
            return(5);
        }
    } else {
        if ( ( containerimage_fp = fopen(containerimage, "r+") ) == NULL ) {
            fprintf(stderr, "ERROR: Could not open image read/write %s: %s\n", containerimage, strerror(errno));
            return(255);
        }
        containerimage_fd = fileno(containerimage_fp);
        if ( flock(containerimage_fd, LOCK_EX | LOCK_NB) < 0 ) {
            fprintf(stderr, "ABORT: Image is locked by another process\n");
            return(5);
        }
    }


//****************************************************************************//
// We are now running with escalated privileges until we exec
//****************************************************************************//

    if ( seteuid(0) < 0 ) {
        fprintf(stderr, "ABORT: Could not escalate effective user privileges %s\n", strerror(errno));
        return(255);
    }
    if ( setegid(0) < 0 ) {
        fprintf(stderr, "ABORT: Could not escalate effective group privileges: %s\n", strerror(errno));
        return(255);
    }

    if ( s_mkpath(tmpdir, 0755) < 0 ) {
        fprintf(stderr, "ABORT: Could not create temporary directory %s: %s\n", tmpdir, strerror(errno));
        return(255);
    }

    if ( is_owner(tmpdir, 0) < 0 ) {
        fprintf(stderr, "ABORT: Container working directory has wrong ownership: %s\n", tmpdir);
        syslog(LOG_ERR, "Container working directory has wrong ownership: %s", tmpdir);
        return(255);
    }

    tmpdirlock_fd = open(tmpdir, O_RDONLY);
    if ( tmpdirlock_fd < 0 ) {
        fprintf(stderr, "ERROR: Could not obtain file descriptor on %s: %s\n", tmpdir, strerror(errno));
        return(255);
    }

    if ( flock(tmpdirlock_fd, LOCK_SH | LOCK_NB) < 0 ) {
        fprintf(stderr, "ERROR: Could not obtain shared lock on %s: %s\n", tmpdir, strerror(errno));
        return(255);
    }

    if ( ( loop_dev_lock_fd = open(loop_dev_lock, O_CREAT | O_RDWR, 0644) ) < 0 ) {
        fprintf(stderr, "ERROR: Could not open loop_dev_lock %s: %s\n", loop_dev_lock, strerror(errno));
        return(255);
    }

    if ( s_mkpath(containerpath, 0755) < 0 ) {
        fprintf(stderr, "ABORT: Could not create directory %s: %s\n", containerpath, strerror(errno));
        return(255);
    }

    if ( is_owner(containerpath, 0) < 0 ) {
        fprintf(stderr, "ABORT: Container directory is not root owned: %s\n", containerpath);
        syslog(LOG_ERR, "Container directory has wrong ownership: %s", tmpdir);
        return(255);
    }

    if ( flock(loop_dev_lock_fd, LOCK_EX | LOCK_NB) == 0 ) {
        loop_dev = obtain_loop_dev();

        if ( ( loop_fp = fopen(loop_dev, "r+") ) < 0 ) {
            fprintf(stderr, "ERROR: Failed to open loop device %s: %s\n", loop_dev, strerror(errno));
            syslog(LOG_ERR, "Failed to open loop device %s: %s", loop_dev, strerror(errno));
            return(255);
        }

        if ( associate_loop(containerimage_fp, loop_fp, 1) < 0 ) {
            fprintf(stderr, "ERROR: Could not associate %s to loop device %s\n", containerimage, loop_dev);
            syslog(LOG_ERR, "Failed to associate %s to loop device %s", containerimage, loop_dev);
            return(255);
        }

        if ( fileput(loop_dev_cache, loop_dev) < 0 ) {
            fprintf(stderr, "ERROR: Could not write to loop_dev_cache %s: %s\n", loop_dev_cache, strerror(errno));
            return(255);
        }

        flock(loop_dev_lock_fd, LOCK_SH | LOCK_NB);

    } else {
        flock(loop_dev_lock_fd, LOCK_SH);
        if ( ( loop_dev = filecat(loop_dev_cache) ) == NULL ) {
            fprintf(stderr, "ERROR: Could not retrieve loop_dev_cache from %s\n", loop_dev_cache);
            return(255);
        }

        if ( ( loop_fp = fopen(loop_dev, "r") ) < 0 ) {
            fprintf(stderr, "ERROR: Failed to open loop device %s: %s\n", loop_dev, strerror(errno));
            return(255);
        }
    }



//****************************************************************************//
// Management fork
//****************************************************************************//

    namespace_fork_pid = fork();
    if ( namespace_fork_pid == 0 ) {

//****************************************************************************//
// Setup namespaces
//****************************************************************************//

        if ( unshare(CLONE_NEWNS) < 0 ) {
            fprintf(stderr, "ABORT: Could not virtualize mount namespace: %s\n", strerror(errno));
            return(255);
        }

        // Privatize the mount namespaces (thank you for the pointer Doug Jacobsen!)
        if ( mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0 ) {
            // I am not sure if this error needs to be caught, maybe it will fail
            // on older kernels? If so, we can fix then.
            fprintf(stderr, "ABORT: Could not make mountspaces private: %s\n", strerror(errno));
            return(255);
        }

#ifdef NS_CLONE_NEWPID
        if ( getenv("SINGULARITY_NO_NAMESPACE_PID") == NULL ) {
            unsetenv("SINGULARITY_NO_NAMESPACE_PID");
            if ( unshare(CLONE_NEWPID) < 0 ) {
                fprintf(stderr, "ABORT: Could not virtualize PID namespace: %s\n", strerror(errno));
                return(255);
            }
        }
#else
#ifdef NS_CLONE_PID
        // This is for older legacy CLONE_PID
        if ( getenv("SINGULARITY_NO_NAMESPACE_PID") == NULL ) {
            unsetenv("SINGULARITY_NO_NAMESPACE_PID");
            if ( unshare(CLONE_PID) < 0 ) {
                fprintf(stderr, "ABORT: Could not virtualize PID namespace: %s\n", strerror(errno));
                return(255);
            }
        }
#endif
#endif
#ifdef NS_CLONE_FS
        if ( getenv("SINGULARITY_NO_NAMESPACE_FS") == NULL ) {
            unsetenv("SINGULARITY_NO_NAMESPACE_FS");
            if ( unshare(CLONE_FS) < 0 ) {
                fprintf(stderr, "ABORT: Could not virtualize file system namespace: %s\n", strerror(errno));
                return(255);
            }
        }
#endif
#ifdef NS_CLONE_FILES
        if ( getenv("SINGULARITY_NO_NAMESPACE_FILES") == NULL ) {
            unsetenv("SINGULARITY_NO_NAMESPACE_FILES");
            if ( unshare(CLONE_FILES) < 0 ) {
                fprintf(stderr, "ABORT: Could not virtualize file descriptor namespace: %s\n", strerror(errno));
                return(255);
            }
        }
#endif


//****************************************************************************//
// Mount image
//****************************************************************************//

        if ( getenv("SINGULARITY_WRITABLE") == NULL ) {
            unsetenv("SINGULARITY_WRITABLE");
            if ( mount_image(loop_dev, containerpath, 0) < 0 ) {
                fprintf(stderr, "ABORT: exiting...\n");
                return(255);
            }
        } else {
            if ( mount_image(loop_dev, containerpath, 1) < 0 ) {
                fprintf(stderr, "ABORT: exiting...\n");
                return(255);
            }
        }


//****************************************************************************//
// Check image
//****************************************************************************//

        if ( is_exec(joinpath(containerpath, "/bin/sh")) < 0 ) {
            fprintf(stderr, "ERROR: Container image does not have a valid /bin/sh\n");
            return(1);
        }


//****************************************************************************//
// Bind mounts
//****************************************************************************//

        if ( getenv("SINGULARITY_CONTAIN") == NULL ) {
            unsetenv("SINGULARITY_CONTAIN");
    
            rewind(config_fp);
            while ( ( tmp_config_string = config_get_key_value(config_fp, "bind path") ) != NULL ) {
                if ( ( is_file(tmp_config_string) != 0 ) && ( is_dir(tmp_config_string) != 0 ) ) {
                    fprintf(stderr, "ERROR: Non existant bind source path: '%s'\n", tmp_config_string);
                    continue;
                }
                if ( ( is_file(joinpath(containerpath, tmp_config_string)) != 0 ) && ( is_dir(joinpath(containerpath, tmp_config_string)) != 0 ) ) {
                    fprintf(stderr, "WARNING: Non existant bind container destination path: '%s'\n", tmp_config_string);
                    continue;
                }
                if ( mount_bind(tmp_config_string, joinpath(containerpath, tmp_config_string), 0) < 0 ) {
                    fprintf(stderr, "ABORTING!\n");
                    return(255);
                }
            }


            if (is_file(joinpath(containerpath, "/etc/nsswitch.conf")) == 0 ) {
                if ( is_file(joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf")) == 0 ) {
                    if ( mount_bind(joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf"), joinpath(containerpath, "/etc/nsswitch.conf"), 0) != 0 ) {
                        fprintf(stderr, "ABORT: Could not bind /etc/nsswitch.conf\n");
                        return(255);
                    }
                } else {
                    fprintf(stderr, "WARNING: Template /etc/nsswitch.conf does not exist: %s\n", joinpath(SYSCONFDIR, "/singularity/default-nsswitch.conf"));
                }
            }

            if ( uid != 0 ) { // If we are root, no need to mess with passwd or group
                if (is_file(joinpath(containerpath, "/etc/passwd")) == 0 ) {
                    if ( is_file(joinpath(tmpdir, "/passwd")) < 0 ) {
                        if ( build_passwd(joinpath(containerpath, "/etc/passwd"), joinpath(tmpdir, "/passwd")) < 0 ) {
                            fprintf(stderr, "ABORT: Failed creating template password file\n");
                            return(255);
                        }
                    }
                    if ( mount_bind(joinpath(tmpdir, "/passwd"), joinpath(containerpath, "/etc/passwd"), 0) < 0 ) {
                        fprintf(stderr, "ABORT: Could not bind /etc/passwd\n");
                        return(255);
                    }
                }
    
                if (is_file(joinpath(containerpath, "/etc/group")) == 0 ) {
                    if ( is_file(joinpath(tmpdir, "/group")) < 0 ) {
                        if ( build_group(joinpath(containerpath, "/etc/group"), joinpath(tmpdir, "/group")) < 0 ) {
                            fprintf(stderr, "ABORT: Failed creating template group file\n");
                            return(255);
                        }
                    }
                    if ( mount_bind(joinpath(tmpdir, "/group"), joinpath(containerpath, "/etc/group"), 0) < 0 ) {
                        fprintf(stderr, "ABORT: Could not bind /etc/group\n");
                        return(255);
                    }
                }
            }
        }

//****************************************************************************//
// Fork child in new namespaces
//****************************************************************************//

        exec_fork_pid = fork();

        if ( exec_fork_pid == 0 ) {


//****************************************************************************//
// Enter the file system
//****************************************************************************//

            if ( chroot(containerpath) < 0 ) {
                fprintf(stderr, "ABORT: failed enter CONTAINERIMAGE: %s\n", containerpath);
                return(255);
            }
            if ( chdir("/") < 0 ) {
                fprintf(stderr, "ABORT: Could not chdir after chroot to /: %s\n", strerror(errno));
                return(1);
            }


//****************************************************************************//
// Setup real mounts within the container
//****************************************************************************//

            rewind(config_fp);
            if ( config_get_key_bool(config_fp, "mount proc", 1) > 0 ) {
                if ( is_dir("/proc") == 0 ) {
                    if ( mount("proc", "/proc", "proc", 0, NULL) < 0 ) {
                        fprintf(stderr, "ABORT: Could not mount /proc: %s\n", strerror(errno));
                        return(255);
                    }
                }
            }

            rewind(config_fp);
            if ( config_get_key_bool(config_fp, "mount sys", 1) > 0 ) {
                if ( is_dir("/sys") == 0 ) {
                    if ( mount("sysfs", "/sys", "sysfs", 0, NULL) < 0 ) {
                        fprintf(stderr, "ABORT: Could not mount /sys: %s\n", strerror(errno));
                        return(255);
                    }
                }
            }


//****************************************************************************//
// Drop all privileges for good
//****************************************************************************//

            if ( setgroups(gid_list_count, gid_list) < 0 ) {
                fprintf(stderr, "ABOFT: Could not reset supplementary group list: %s\n", strerror(errno));
                return(255);
            }
            if ( setregid(gid, gid) < 0 ) {
                fprintf(stderr, "ABORT: Could not dump real and effective group privileges: %s\n", strerror(errno));
                return(255);
            }
            if ( setreuid(uid, uid) < 0 ) {
                fprintf(stderr, "ABORT: Could not dump real and effective user privileges: %s\n", strerror(errno));
                return(255);
            }


//****************************************************************************//
// Setup final environment
//****************************************************************************//

            // After this, we exist only within the container... Let's make it known!
            if ( setenv("SINGULARITY_CONTAINER", "true", 0) != 0 ) {
                fprintf(stderr, "ABORT: Could not set SINGULARITY_CONTAINER to 'true'\n");
                return(1);
            }

            if ( is_dir(cwd) == 0 ) {
               if ( chdir(cwd) < 0 ) {
                    fprintf(stderr, "ABORT: Could not chdir to: %s: %s\n", cwd, strerror(errno));
                    return(1);
                }
            } else {
                if ( fchdir(cwd_fd) < 0 ) {
                    fprintf(stderr, "ABORT: Could not fchdir to cwd: %s\n", strerror(errno));
                    return(1);
                }
            }


//****************************************************************************//
// Execv to container process
//****************************************************************************//

            if ( command == NULL ) {
                fprintf(stderr, "No command specified, launching 'shell'\n");
                command = strdup("shell");
            }

            if ( strcmp(command, "run") == 0 ) {
                if ( is_exec("/singularity") == 0 ) {
                    argv[0] = strdup("/singularity");
                    if ( execv("/singularity", argv) != 0 ) {
                        fprintf(stderr, "ABORT: exec of /bin/sh failed: %s\n", strerror(errno));
                    }
                } else {
                    fprintf(stderr, "No Singularity runscript found, launching 'shell'\n");
                    command = strdup("shell");
                }
            }
            
            if ( strcmp(command, "exec") == 0 ) {
                if ( argc <= 1 ) {
                    fprintf(stderr, "ABORT: Exec requires a command to run\n");
                    return(1);
                }
                if ( execvp(argv[1], &argv[1]) != 0 ) {
                    fprintf(stderr, "ABORT: execvp of '%s' failed: %s\n", argv[1], strerror(errno));
                    return(1);
                }
            }
            
            if ( strcmp(command, "shell") == 0 ) {
                char *prompt;

                prompt = (char *) malloc(strlen(containername) + 16);
                snprintf(prompt, strlen(containerimage) + 16, "Singularity/%s> ", containername);
                setenv("PS1", prompt, 1);

                if ( is_exec("/bin/bash") == 0 ) {
                    char *args[argc+2];
                    int i;

                    args[0] = strdup("/bin/bash");
                    args[1] = strdup("--norc");
                    args[2] = strdup("--noprofile");
                    for(i=1; i<=argc; i++) {
                        args[i+2] = argv[i];
                    }

                    if ( execv("/bin/bash", args) != 0 ) {
                        fprintf(stderr, "ABORT: exec of /bin/bash failed: %s\n", strerror(errno));
                    }
                } else {
                    argv[0] = strdup("/bin/sh");
                    if ( execv("/bin/sh", argv) != 0 ) {
                        fprintf(stderr, "ABORT: exec of /bin/sh failed: %s\n", strerror(errno));
                    }
                }
            }

            // If we get here... we fail on bad command
            fprintf(stderr, "ABORT: Unrecognized Singularity command: %s\n", command);
            return(1);


//****************************************************************************//
// Outer child waits for inner child
//****************************************************************************//

        } else if ( exec_fork_pid > 0 ) {
            int tmpstatus;

            strncpy(argv[0], "Singularity: exec", strlen(argv[0]));

            if ( seteuid(uid) < 0 ) {
                fprintf(stderr, "ABORT: Could not set effective user privileges to %d: %s\n", uid, strerror(errno));
                return(255);
            }

            waitpid(exec_fork_pid, &tmpstatus, 0);
            retval = WEXITSTATUS(tmpstatus);
        } else {
            fprintf(stderr, "ABORT: Could not fork namespace process: %s\n", strerror(errno));
            return(255);
        }
        return(retval);

    } else if ( namespace_fork_pid > 0 ) {
        int tmpstatus;

        strncpy(argv[0], "Singularity: namespace", strlen(argv[0]));

        if ( seteuid(uid) < 0 ) {
            fprintf(stderr, "ABORT: Could not set effective user privileges to %d: %s\n", uid, strerror(errno));
            return(255);
        }

        waitpid(namespace_fork_pid, &tmpstatus, 0);
        retval = WEXITSTATUS(tmpstatus);
    } else {
        fprintf(stderr, "ABORT: Could not fork management process: %s\n", strerror(errno));
        return(255);
    }


//****************************************************************************//
// Final wrap up before exiting
//****************************************************************************//


    if ( close(cwd_fd) < 0 ) {
        fprintf(stderr, "ERROR: Could not close cwd_fd: %s\n", strerror(errno));
        retval++;
    }

    if ( flock(tmpdirlock_fd, LOCK_EX | LOCK_NB) == 0 ) {
        close(tmpdirlock_fd);
        if ( seteuid(0) < 0 ) {
            fprintf(stderr, "ABORT: Could not re-escalate effective user privileges: %s\n", strerror(errno));
            return(255);
        }

        if ( s_rmdir(tmpdir) < 0 ) {
            fprintf(stderr, "WARNING: Could not remove all files in %s: %s\n", tmpdir, strerror(errno));
        }
    
        // Dissociate loops from here Just in case autoflush didn't work.
        (void)disassociate_loop(loop_fp);

        if ( seteuid(uid) < 0 ) {
            fprintf(stderr, "ABORT: Could not drop effective user privileges: %s\n", strerror(errno));
            return(255);
        }

    } else {
//        printf("Not removing tmpdir, lock still\n");
    }

    close(containerimage_fd);
    close(tmpdirlock_fd);

    free(loop_dev_lock);
    free(containerpath);
    free(tmpdir);
    closelog();

    return(retval);
}
Ejemplo n.º 24
0
/*
 * Read the ${TIN_HOMEDIR:-"$HOME"}/.newsauth file and put authentication
 * username and password for the specified server in the given strings.
 * Returns TRUE if at least a password was found, FALSE if there was
 * no .newsauth file or no matching server.
 */
static t_bool
read_newsauth_file(
	char *server,
	char *authuser,
	char *authpass)
{
	FILE *fp;
	char *_authpass;
	char *ptr;
	char filename[PATH_LEN];
	char line[PATH_LEN];
	int found = 0;
	int fd;
	struct stat statbuf;

	joinpath(filename, sizeof(filename), homedir, ".newsauth");

	if ((fp = fopen(filename, "r"))) {
		if ((fd = fileno(fp)) == -1) {
			fclose(fp);
			return FALSE;
		}
		if (fstat(fd, &statbuf) == -1) {
			fclose(fp);
			return FALSE;
		}

#	ifndef FILE_MODE_BROKEN
		if (S_ISREG(statbuf.st_mode) && (statbuf.st_mode|S_IRUSR|S_IWUSR) != (S_IRUSR|S_IWUSR|S_IFREG)) {
			error_message(4, _(txt_error_insecure_permissions), filename, statbuf.st_mode);
			/*
			 * TODO: fix permssions?
			 * fchmod(fd, S_IRUSR|S_IWUSR);
			 */
		}
#	endif /* !FILE_MODE_BROKEN */

		/*
		 * Search through authorization file for correct NNTP server
		 * File has format: 'nntp-server' 'password' ['username']
		 */
		while (fgets(line, sizeof(line), fp) != NULL) {
			/* strip trailing newline character */
			ptr = strchr(line, '\n');
			if (ptr != NULL)
				*ptr = '\0';

			/* Get server from 1st part of the line */
			ptr = strpbrk(line, " \t");

			if (ptr == NULL)		/* no passwd, no auth, skip */
				continue;

			*ptr++ = '\0';		/* cut off server part */

			if ((strcasecmp(line, server)))
				continue;		/* wrong server, keep on */

			/* Get password from 2nd part of the line */
			while (*ptr == ' ' || *ptr == '\t')
				ptr++;	/* skip any blanks */

			_authpass = ptr;

			if (*_authpass == '"') {	/* skip "embedded" password string */
				ptr = strrchr(_authpass, '"');
				if ((ptr != NULL) && (ptr > _authpass)) {
					_authpass++;
					*ptr++ = '\0';	/* cut off trailing " */
				} else	/* no matching ", proceede as normal */
					ptr = _authpass;
			}

			/* Get user from 3rd part of the line */
			ptr = strpbrk(ptr, " \t");	/* find next separating blank */

			if (ptr != NULL) {	/* a 3rd argument follows */
				while (*ptr == ' ' || *ptr == '\t')	/* skip any blanks */
					*ptr++ = '\0';
				if (*ptr != '\0')	/* if its not just empty */
					strcpy(authuser, ptr);	/* so will replace default user */
			}
			strcpy(authpass, _authpass);
			found++;
			break;	/* if we end up here, everything seems OK */
		}
		fclose(fp);
		return (found > 0);
	}
	return FALSE;
}
Ejemplo n.º 25
0
/* search_for_exec_prefix requires that argv0_path be no more than
   MAXPATHLEN bytes long.
*/
static int
search_for_exec_prefix(char *argv0_path, char *home)
{
    size_t n;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        char *delim;
        delim = strchr(home, DELIM);
        if (delim)
            strncpy(exec_prefix, delim+1, MAXPATHLEN);
        else
            strncpy(exec_prefix, home, MAXPATHLEN);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        return 1;
    }

    /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
       is written by setup.py and contains the relative path to the location
       of shared library modules. */
    strcpy(exec_prefix, argv0_path);
    joinpath(exec_prefix, "pybuilddir.txt");
    if (isfile(exec_prefix)) {
      FILE *f = fopen(exec_prefix, "r");
      if (f == NULL)
	errno = 0;
      else {
	char rel_builddir_path[MAXPATHLEN+1];
	size_t n;
	n = fread(rel_builddir_path, 1, MAXPATHLEN, f);
	rel_builddir_path[n] = '\0';
	fclose(f);
	if (n >= 0) {
	  strcpy(exec_prefix, argv0_path);
	  joinpath(exec_prefix, rel_builddir_path);
	  return -1;
	}
      }
    }

    /* Search from argv0_path, until root is found */
    copy_absolute(exec_prefix, argv0_path);
    do {
        n = strlen(exec_prefix);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, "lib-dynload");
        if (isdir(exec_prefix))
            return 1;
        exec_prefix[n] = '\0';
        reduce(exec_prefix);
    } while (exec_prefix[0]);

    /* Look at configure's EXEC_PREFIX */
    strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
    joinpath(exec_prefix, lib_python);
    joinpath(exec_prefix, "lib-dynload");
    if (isdir(exec_prefix))
        return 1;

    /* Fail */
    return 0;
}
Ejemplo n.º 26
0
int _singularity_runtime_mount_tmp(void) {
    char *container_dir = singularity_runtime_rootfs(NULL);
    char *tmp_source;
    char *vartmp_source;

    if ( singularity_config_get_bool(MOUNT_TMP) <= 0 ) {
        singularity_message(VERBOSE, "Skipping tmp dir mounting (per config)\n");
        return(0);
    }

    if ( singularity_registry_get("CONTAIN") == NULL ) {
        tmp_source = strdup("/tmp");
        vartmp_source = strdup("/var/tmp");
    } else {
        char *tmpdirpath;
        if ( ( tmpdirpath = singularity_registry_get("WORKDIR") ) != NULL ) {
            if ( singularity_config_get_bool(USER_BIND_CONTROL) <= 0 ) {
                singularity_message(ERROR, "User bind control is disabled by system administrator\n");
                ABORT(5);
            }
            tmp_source = joinpath(tmpdirpath, "/tmp");
            vartmp_source = joinpath(tmpdirpath, "/var_tmp");
        } else {
            char *sessiondir = singularity_registry_get("SESSIONDIR");
            tmp_source = joinpath(sessiondir, "/tmp");
            vartmp_source = joinpath(sessiondir, "/var_tmp");
        }
        free(tmpdirpath);
    }

    if ( check_mounted("/tmp") < 0 ) {
        if ( s_mkpath(tmp_source, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create source /tmp directory %s: %s\n", tmp_source, strerror(errno));
            ABORT(255);
        }
        if ( is_dir(tmp_source) == 0 ) {
            if ( is_dir(joinpath(container_dir, "/tmp")) == 0 ) {
                singularity_priv_escalate();
                singularity_message(VERBOSE, "Mounting directory: /tmp\n");
                if ( mount(tmp_source, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                    singularity_message(ERROR, "Failed to mount %s -> /tmp: %s\n", tmp_source, strerror(errno));
                    ABORT(255);
                }
                if ( singularity_priv_userns_enabled() != 1 ) {
                    if ( mount(NULL, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) {
                        singularity_message(ERROR, "Failed to remount /tmp: %s\n", strerror(errno));
                        ABORT(255);
                    }
                }
                singularity_priv_drop();
            } else {
                singularity_message(VERBOSE, "Could not mount container's /tmp directory: does not exist\n");
            }
        } else {
            singularity_message(VERBOSE, "Could not mount host's /tmp directory (%s): does not exist\n", tmp_source);
        }
    } else {
        singularity_message(VERBOSE, "Not mounting '/tmp', already mounted\n");
    }

    if ( check_mounted("/var/tmp") < 0 ) {
        if ( s_mkpath(vartmp_source, 0755) < 0 ) {
            singularity_message(ERROR, "Could not create source /var/tmp directory %s: %s\n", vartmp_source, strerror(errno));
            ABORT(255);
        }
        if ( is_dir(vartmp_source) == 0 ) {
            if ( is_dir(joinpath(container_dir, "/var/tmp")) == 0 ) {
                singularity_priv_escalate();
                singularity_message(VERBOSE, "Mounting directory: /var/tmp\n");
                if ( mount(vartmp_source, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                    singularity_message(ERROR, "Failed to mount %s -> /var/tmp: %s\n", vartmp_source, strerror(errno));
                    ABORT(255);
                }
                if ( singularity_priv_userns_enabled() != 1 ) {
                    if ( mount(NULL, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC|MS_REMOUNT, NULL) < 0 ) {
                        singularity_message(ERROR, "Failed to remount /var/tmp: %s\n", strerror(errno));
                        ABORT(255);
                    }
                }
                singularity_priv_drop();
            } else {
                singularity_message(VERBOSE, "Could not mount container's /var/tmp directory: does not exist\n");
            }
        } else {
            singularity_message(VERBOSE, "Could not mount host's /var/tmp directory (%s): does not exist\n", vartmp_source);
        }
    } else {
        singularity_message(VERBOSE, "Not mounting '/var/tmp', already mounted\n");
    }

    free(tmp_source);
    free(vartmp_source);

    return(0);
}
Ejemplo n.º 27
0
/* search_for_exec_prefix requires that argv0_path be no more than
   MAXPATHLEN bytes long.
*/
static int
search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix)
{
    size_t n;

    /* If PYTHONHOME is set, we believe it unconditionally */
    if (home) {
        wchar_t *delim;
        delim = wcschr(home, DELIM);
        if (delim)
            wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
        else
            wcsncpy(exec_prefix, home, MAXPATHLEN);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, L"lib-dynload");
        return 1;
    }

    /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
       is written by setup.py and contains the relative path to the location
       of shared library modules. */
    wcscpy(exec_prefix, argv0_path);
    joinpath(exec_prefix, L"pybuilddir.txt");
    if (isfile(exec_prefix)) {
        FILE *f = _Py_wfopen(exec_prefix, L"rb");
        if (f == NULL)
            errno = 0;
        else {
            char buf[MAXPATHLEN+1];
            PyObject *decoded;
            wchar_t rel_builddir_path[MAXPATHLEN+1];
            n = fread(buf, 1, MAXPATHLEN, f);
            buf[n] = '\0';
            fclose(f);
            decoded = PyUnicode_DecodeUTF8(buf, n, "surrogateescape");
            if (decoded != NULL) {
                Py_ssize_t k;
                k = PyUnicode_AsWideChar(decoded,
                                         rel_builddir_path, MAXPATHLEN);
                Py_DECREF(decoded);
                if (k >= 0) {
                    rel_builddir_path[k] = L'\0';
                    wcscpy(exec_prefix, argv0_path);
                    joinpath(exec_prefix, rel_builddir_path);
                    return -1;
                }
            }
        }
    }

    /* Search from argv0_path, until root is found */
    copy_absolute(exec_prefix, argv0_path, MAXPATHLEN+1);
    do {
        n = wcslen(exec_prefix);
        joinpath(exec_prefix, lib_python);
        joinpath(exec_prefix, L"lib-dynload");
        if (isdir(exec_prefix))
            return 1;
        exec_prefix[n] = L'\0';
        reduce(exec_prefix);
    } while (exec_prefix[0]);

    /* Look at configure's EXEC_PREFIX */
    wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN);
    joinpath(exec_prefix, lib_python);
    joinpath(exec_prefix, L"lib-dynload");
    if (isdir(exec_prefix))
        return 1;

    /* Fail */
    return 0;
}
Ejemplo n.º 28
0
int _singularity_runtime_files_passwd(void) {
    FILE *file_fp;
    char *source_file;
    char *tmp_file;
    char *homedir = singularity_priv_home();
    uid_t uid = singularity_priv_getuid();
    struct passwd *pwent = getpwuid(uid);
    char *containerdir = CONTAINER_FINALDIR;
    char *tmpdir = singularity_registry_get("SESSIONDIR");

    singularity_message(DEBUG, "Called singularity_file_passwd_create()\n");

    if ( uid == 0 ) {
        singularity_message(VERBOSE, "Not updating passwd file, running as root!\n");
        return(0);
    }

    if ( containerdir == NULL ) {
        singularity_message(ERROR, "Failed to obtain container directory\n");
        ABORT(255);
    }

    if ( tmpdir == NULL ) {
        singularity_message(ERROR, "Failed to obtain session directory\n");
        ABORT(255);
    }

    singularity_message(DEBUG, "Checking configuration option: 'config passwd'\n");
    if ( singularity_config_get_bool(CONFIG_PASSWD) <= 0 ) {
        singularity_message(VERBOSE, "Skipping bind of the host's /etc/passwd\n");
        return(0);
    }

    source_file = joinpath(containerdir, "/etc/passwd");
    tmp_file = joinpath(tmpdir, "/passwd");

    singularity_message(VERBOSE2, "Checking for template passwd file: %s\n", source_file);
    if ( is_file(source_file) < 0 ) {
        singularity_message(VERBOSE, "Passwd file does not exist in container, not updating\n");
        return(0);
    }

    singularity_message(VERBOSE2, "Creating template of /etc/passwd\n");
    if ( ( copy_file(source_file, tmp_file) ) < 0 ) {
        singularity_message(ERROR, "Failed copying template passwd file to tmpdir: %s\n", strerror(errno));
        ABORT(255);
    }

    singularity_message(VERBOSE, "Creating template passwd file and appending user data: %s\n", tmp_file);
    if ( ( file_fp = fopen(tmp_file, "a") ) == NULL ) { // Flawfinder: ignore
        singularity_message(ERROR, "Could not open template passwd file %s: %s\n", tmp_file, strerror(errno));
        ABORT(255);
    }

    fprintf(file_fp, "%s:x:%d:%d:%s:%s:%s\n", pwent->pw_name, pwent->pw_uid, pwent->pw_gid, pwent->pw_gecos, homedir, pwent->pw_shell);
    fclose(file_fp);


    container_file_bind(tmp_file, "/etc/passwd");

    // set HOME to the homedir, because it might be different than outside
    envar_set("HOME", homedir, 1);

    return(0);
}
Ejemplo n.º 29
0
/** Determine paths.

    Two directories must be found, the platform independent directory
    (prefix), containing the common .py and .pyc files, and the platform
    dependent directory (exec_prefix), containing the shared library
    modules.  Note that prefix and exec_prefix are the same directory
    for UEFI installations.

    Separate searches are carried out for prefix and exec_prefix.
    Each search tries a number of different locations until a ``landmark''
    file or directory is found.  If no prefix or exec_prefix is found, a
    warning message is issued and the preprocessor defined PREFIX and
    EXEC_PREFIX are used (even though they may not work); python carries on
    as best as is possible, but some imports may fail.

    Before any searches are done, the location of the executable is
    determined.  If argv[0] has one or more slashes in it, it is used
    unchanged.  Otherwise, it must have been invoked from the shell's path,
    so we search %PATH% for the named executable and use that.  If the
    executable was not found on %PATH% (or there was no %PATH% environment
    variable), the original argv[0] string is used.

    Finally, argv0_path is set to the directory containing the executable
    (i.e. the last component is stripped).

    With argv0_path in hand, we perform a number of steps.  The same steps
    are performed for prefix and for exec_prefix, but with a different
    landmark.

    The prefix landmark will always be lib/python.VERSION/os.py and the
    exec_prefix will always be lib/python.VERSION/dynaload, where VERSION
    is Python's version number as defined at the beginning of this file.

    First. See if the %PYTHONHOME% environment variable points to the
    installed location of the Python libraries.  If %PYTHONHOME% is set, then
    it points to prefix and exec_prefix.  %PYTHONHOME% can be a single
    directory, which is used for both, or the prefix and exec_prefix
    directories separated by the DELIM character.

    Next. Search the directories pointed to by the preprocessor variables
    PREFIX and EXEC_PREFIX.  These paths are prefixed with the volume name
    extracted from argv0_path.  The volume names correspond to the UEFI
    shell "map" names.

    That's it!

    Well, almost.  Once we have determined prefix and exec_prefix, the
    preprocessor variable PYTHONPATH is used to construct a path.  Each
    relative path on PYTHONPATH is prefixed with prefix.  Then the directory
    containing the shared library modules is appended.  The environment
    variable $PYTHONPATH is inserted in front of it all.  Finally, the
    prefix and exec_prefix globals are tweaked so they reflect the values
    expected by other code, by stripping the "lib/python$VERSION/..." stuff
    off.  This seems to make more sense given that currently the only
    known use of sys.prefix and sys.exec_prefix is for the ILU installation
    process to find the installed Python tree.

    The final, fully resolved, paths should look something like:
      fs0:/Efi/Tools/python.efi
      fs0:/Efi/StdLib/lib/python27
      fs0:/Efi/StdLib/lib/python27/dynaload

**/
static void
calculate_path(void)
{
    extern char *Py_GetProgramName(void);

    static char delimiter[2] = {DELIM, '\0'};
    static char separator[2] = {SEP, '\0'};
    char *pythonpath = PYTHONPATH;
    char *rtpypath = Py_GETENV("PYTHONPATH");
    //char *home = Py_GetPythonHome();
    char *path = getenv("path");
    char *prog = Py_GetProgramName();
    char argv0_path[MAXPATHLEN+1];
    char zip_path[MAXPATHLEN+1];
    char *buf;
    size_t bufsz;
    size_t prefixsz;
    char *defpath;


/* ###########################################################################
      Determine path to the Python.efi binary.
      Produces progpath, argv0_path, and volume_name.
########################################################################### */

    /* If there is no slash in the argv0 path, then we have to
     * assume python is on the user's $PATH, since there's no
     * other way to find a directory to start the search from.  If
     * $PATH isn't exported, you lose.
     */
    if (strchr(prog, SEP))
            strncpy(progpath, prog, MAXPATHLEN);
    else if (path) {
      while (1) {
        char *delim = strchr(path, DELIM);

        if (delim) {
                size_t len = delim - path;
                if (len > MAXPATHLEN)
                        len = MAXPATHLEN;
                strncpy(progpath, path, len);
                *(progpath + len) = '\0';
        }
        else
                strncpy(progpath, path, MAXPATHLEN);

        joinpath(progpath, prog);
        if (isxfile(progpath))
                break;

        if (!delim) {
                progpath[0] = '\0';
                break;
        }
        path = delim + 1;
      }
    }
    else
            progpath[0] = '\0';
    if ( (!is_absolute(progpath)) && (progpath[0] != '\0') )
            absolutize(progpath);
    strncpy(argv0_path, progpath, MAXPATHLEN);
    argv0_path[MAXPATHLEN] = '\0';
    set_volume(volume_name, argv0_path);

    reduce(argv0_path);
    /* At this point, argv0_path is guaranteed to be less than
       MAXPATHLEN bytes long.
    */

/* ###########################################################################
      Build the FULL prefix string, including volume name.
      This is the full path to the platform independent libraries.
########################################################################### */

    strncpy(prefix, volume_name, MAXPATHLEN);
    joinpath(prefix, PREFIX);
    joinpath(prefix, lib_python);

/* ###########################################################################
      Build the FULL path to the zipped-up Python library.
########################################################################### */

    strncpy(zip_path, prefix, MAXPATHLEN);
    zip_path[MAXPATHLEN] = '\0';
    reduce(zip_path);
    joinpath(zip_path, "python00.zip");
    bufsz = strlen(zip_path);   /* Replace "00" with version */
    zip_path[bufsz - 6] = VERSION[0];
    zip_path[bufsz - 5] = VERSION[1];

/* ###########################################################################
      Build the FULL path to dynamically loadable libraries.
########################################################################### */

    strncpy(exec_prefix, volume_name, MAXPATHLEN);    // "fs0:"
    joinpath(exec_prefix, EXEC_PREFIX);               // "fs0:/Efi/StdLib"
    joinpath(exec_prefix, lib_python);                // "fs0:/Efi/StdLib/lib/python.27"
    joinpath(exec_prefix, "lib-dynload");             // "fs0:/Efi/StdLib/lib/python.27/lib-dynload"

/* ###########################################################################
      Build the module search path.
########################################################################### */

    /* Reduce prefix and exec_prefix to their essence,
     * e.g. /usr/local/lib/python1.5 is reduced to /usr/local.
     * If we're loading relative to the build directory,
     * return the compiled-in defaults instead.
     */
    reduce(prefix);
    reduce(prefix);
    /* The prefix is the root directory, but reduce() chopped
     * off the "/". */
    if (!prefix[0]) {
      strcpy(prefix, volume_name);
    }
    bufsz = strlen(prefix);
    if(prefix[bufsz-1] == ':') {    // if prefix consists solely of a volume_name
      prefix[bufsz] = SEP;          //    then append SEP indicating the root directory
      prefix[bufsz+1] = 0;          //    and ensure the new string is terminated
    }

    /* Calculate size of return buffer.
     */
    defpath = pythonpath;
    bufsz = 0;

    if (rtpypath)
        bufsz += strlen(rtpypath) + 1;

    prefixsz = strlen(prefix) + 1;

    while (1) {
        char *delim = strchr(defpath, DELIM);

        if (is_absolute(defpath) == 0)
            /* Paths are relative to prefix */
            bufsz += prefixsz;

        if (delim)
            bufsz += delim - defpath + 1;
        else {
            bufsz += strlen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += strlen(zip_path) + 1;
    bufsz += strlen(exec_prefix) + 1;

    /* This is the only malloc call in this file */
    buf = (char *)PyMem_Malloc(bufsz);

    if (buf == NULL) {
        /* We can't exit, so print a warning and limp along */
        fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
        fprintf(stderr, "Using default static PYTHONPATH.\n");
        module_search_path = PYTHONPATH;
    }
    else {
        /* Run-time value of $PYTHONPATH goes first */
        if (rtpypath) {
            strcpy(buf, rtpypath);
            strcat(buf, delimiter);
        }
        else
            buf[0] = '\0';

        /* Next is the default zip path */
        strcat(buf, zip_path);
        strcat(buf, delimiter);

        /* Next goes merge of compile-time $PYTHONPATH with
         * dynamically located prefix.
         */
        defpath = pythonpath;
        while (1) {
            char *delim = strchr(defpath, DELIM);

            if (is_absolute(defpath) != 1) {
                strcat(buf, prefix);
                strcat(buf, separator);
            }

            if (delim) {
                size_t len = delim - defpath + 1;
                size_t end = strlen(buf) + len;
                strncat(buf, defpath, len);
                *(buf + end) = '\0';
            }
            else {
                strcat(buf, defpath);
                break;
            }
            defpath = delim + 1;
        }
        strcat(buf, delimiter);

        /* Finally, on goes the directory for dynamic-load modules */
        strcat(buf, exec_prefix);

        /* And publish the results */
        module_search_path = buf;
    }
        /*  At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib.
            We want to get back to the root value, so we have to remove the final three
            segments to get VOL:/Efi/StdLib.  Because we don't know what VOL is, and
            EXEC_PREFIX is also indeterminate, we just remove the three final segments.
        */
        reduce(exec_prefix);
        reduce(exec_prefix);
        reduce(exec_prefix);
        if (!exec_prefix[0]) {
          strcpy(exec_prefix, volume_name);
        }
        bufsz = strlen(exec_prefix);
        if(exec_prefix[bufsz-1] == ':') {
          exec_prefix[bufsz] = SEP;
          exec_prefix[bufsz+1] = 0;
        }
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path);
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix             = \"%s\"\n", __func__, __LINE__, prefix);
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix        = \"%s\"\n", __func__, __LINE__, exec_prefix);
    if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath           = \"%s\"\n", __func__, __LINE__, progpath);
}
Ejemplo n.º 30
0
int singularity_mount_tmp(void) {
    char *container_dir = singularity_rootfs_dir();
    char *tmp_source;
    char *vartmp_source;
    char *tmpdirpath;

    singularity_config_rewind();
    if ( singularity_config_get_bool("mount tmp", 1) <= 0 ) {
        singularity_message(VERBOSE, "Skipping tmp dir mounting (per config)\n");
        return(0);
    }

    if ( ( tmpdirpath = getenv("SINGULARITY_WORKDIR") ) != NULL ) { // Flawfinder: ignore
        singularity_config_rewind();
        if ( singularity_config_get_bool("user bind control", 1) <= 0 ) {
            singularity_message(ERROR, "User bind control is disabled by system administrator\n");
            ABORT(5);
        }
        tmp_source = joinpath(tmpdirpath, "/tmp");
        vartmp_source = joinpath(tmpdirpath, "/var_tmp");
    } else if ( getenv("SINGULARITY_CONTAIN") != NULL ) { // Flawfinder: ignore
        char *sessiondir = singularity_sessiondir_get();
        tmp_source = joinpath(sessiondir, "/tmp");
        vartmp_source = joinpath(sessiondir, "/var_tmp");
    } else {
        tmp_source = strdup("/tmp");
        vartmp_source = strdup("/var/tmp");
    }

    if ( s_mkpath(tmp_source, 0755) < 0 ) {
        singularity_message(ERROR, "Could not create tmp directory %s: %s\n", tmp_source, strerror(errno));
        ABORT(255);
    }
    if ( s_mkpath(vartmp_source, 0755) < 0 ) {
        singularity_message(ERROR, "Could not create vartmp directory %s: %s\n", vartmp_source, strerror(errno));
        ABORT(255);
    }

    if ( is_dir(tmp_source) == 0 ) {
        if ( is_dir(joinpath(container_dir, "/tmp")) == 0 ) {
            singularity_priv_escalate();
            singularity_message(VERBOSE, "Mounting directory: /tmp\n");
            if ( mount(tmp_source, joinpath(container_dir, "/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                singularity_message(ERROR, "Failed to mount %s -> /tmp: %s\n", tmp_source, strerror(errno));
                ABORT(255);
            }
            singularity_priv_drop();
        } else {
            singularity_message(VERBOSE, "Could not mount container's /tmp directory: does not exist\n");
        }
    } else {
        singularity_message(VERBOSE, "Could not mount host's /tmp directory (%s): does not exist\n", tmp_source);
    }

    if ( is_dir(vartmp_source) == 0 ) {
        if ( is_dir(joinpath(container_dir, "/var/tmp")) == 0 ) {
            singularity_priv_escalate();
            singularity_message(VERBOSE, "Mounting directory: /var/tmp\n");
            if ( mount(vartmp_source, joinpath(container_dir, "/var/tmp"), NULL, MS_BIND|MS_NOSUID|MS_REC, NULL) < 0 ) {
                singularity_message(ERROR, "Failed to mount %s -> /var/tmp: %s\n", vartmp_source, strerror(errno));
                ABORT(255);
            }
            singularity_priv_drop();
        } else {
            singularity_message(VERBOSE, "Could not mount container's /var/tmp directory: does not exist\n");
        }
    } else {
        singularity_message(VERBOSE, "Could not mount host's /var/tmp directory (%s): does not exist\n", vartmp_source);
    }

    free(tmp_source);
    free(vartmp_source);

    return(0);
}