/** * Function to prepare the job directories for the task JVM. */ int initialize_job(const char *user, const char *jobid, const char* credentials, const char* job_xml, char* const* args) { if (jobid == NULL || user == NULL) { fprintf(LOGFILE, "Either jobid is null or the user passed is null.\n"); return INVALID_ARGUMENT_NUMBER; } // create the user directory int result = initialize_user(user); if (result != 0) { return result; } // create the log directory for the job char *job_log_dir = get_job_log_directory(jobid); if (job_log_dir == NULL) { return -1; } result = create_directory_for_user(job_log_dir); free(job_log_dir); if (result != 0) { return -1; } // open up the credentials file int cred_file = open_file_as_task_tracker(credentials); if (cred_file == -1) { return -1; } int job_file = open_file_as_task_tracker(job_xml); if (job_file == -1) { return -1; } // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { return -1; } // 750 mode_t permissions = S_IRWXU | S_IRGRP | S_IXGRP; char **tt_roots = get_values(TT_SYS_DIR_KEY); if (tt_roots == NULL) { return INVALID_CONFIG_FILE; } char **tt_root; char *primary_job_dir = NULL; for(tt_root=tt_roots; *tt_root != NULL; ++tt_root) { char *job_dir = get_job_directory(*tt_root, user, jobid); if (job_dir == NULL) { // try the next one } else if (mkdirs(job_dir, permissions) != 0) { free(job_dir); } else if (primary_job_dir == NULL) { primary_job_dir = job_dir; } else { free(job_dir); } } free_values(tt_roots); if (primary_job_dir == NULL) { fprintf(LOGFILE, "Did not create any job directories\n"); return -1; } char *cred_file_name = concatenate("%s/%s", "cred file", 2, primary_job_dir, CREDENTIALS_FILENAME); if (cred_file_name == NULL) { return -1; } if (copy_file(cred_file, credentials, cred_file_name, S_IRUSR|S_IWUSR) != 0){ return -1; } char *job_file_name = concatenate("%s/%s", "job file", 2, primary_job_dir, JOB_FILENAME); if (job_file_name == NULL) { return -1; } if (copy_file(job_file, job_xml, job_file_name, S_IRUSR|S_IWUSR|S_IRGRP) != 0) { return -1; } fclose(stdin); fflush(LOGFILE); if (LOGFILE != stdout) { fclose(stdout); } fclose(stderr); if (chdir(primary_job_dir)) { fprintf(LOGFILE, "Failure to chdir to job dir - %s\n", strerror(errno)); return -1; } execvp(args[0], args); fprintf(LOGFILE, "Failure to exec job initialization process - %s\n", strerror(errno)); return -1; }
/** * Function to prepare the application directories for the container. */ int initialize_app(const char *user, const char *app_id, const char* nmPrivate_credentials_file, char* const* local_dirs, char* const* log_roots, char* const* args) { if (app_id == NULL || user == NULL) { fprintf(LOGFILE, "Either app_id is null or the user passed is null.\n"); return INVALID_ARGUMENT_NUMBER; } // create the user directory on all disks int result = initialize_user(user, local_dirs); if (result != 0) { return result; } ////////////// create the log directories for the app on all disks char* const* log_root; char *any_one_app_log_dir = NULL; for(log_root=log_roots; *log_root != NULL; ++log_root) { char *app_log_dir = get_app_log_directory(*log_root, app_id); if (app_log_dir == NULL) { // try the next one } else if (create_directory_for_user(app_log_dir) != 0) { free(app_log_dir); return -1; } else if (any_one_app_log_dir == NULL) { any_one_app_log_dir = app_log_dir; } else { free(app_log_dir); } } if (any_one_app_log_dir == NULL) { fprintf(LOGFILE, "Did not create any app-log directories\n"); return -1; } free(any_one_app_log_dir); ////////////// End of creating the log directories for the app on all disks // open up the credentials file int cred_file = open_file_as_nm(nmPrivate_credentials_file); if (cred_file == -1) { return -1; } // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { return -1; } // 750 mode_t permissions = S_IRWXU | S_IRGRP | S_IXGRP; char* const* nm_root; char *primary_app_dir = NULL; for(nm_root=local_dirs; *nm_root != NULL; ++nm_root) { char *app_dir = get_app_directory(*nm_root, user, app_id); if (app_dir == NULL) { // try the next one } else if (mkdirs(app_dir, permissions) != 0) { free(app_dir); } else if (primary_app_dir == NULL) { primary_app_dir = app_dir; } else { free(app_dir); } } if (primary_app_dir == NULL) { fprintf(LOGFILE, "Did not create any app directories\n"); return -1; } char *nmPrivate_credentials_file_copy = strdup(nmPrivate_credentials_file); // TODO: FIXME. The user's copy of creds should go to a path selected by // localDirAllocatoir char *cred_file_name = concatenate("%s/%s", "cred file", 2, primary_app_dir, basename(nmPrivate_credentials_file_copy)); if (cred_file_name == NULL) { free(nmPrivate_credentials_file_copy); return -1; } if (copy_file(cred_file, nmPrivate_credentials_file, cred_file_name, S_IRUSR|S_IWUSR) != 0){ free(nmPrivate_credentials_file_copy); return -1; } free(nmPrivate_credentials_file_copy); fclose(stdin); fflush(LOGFILE); if (LOGFILE != stdout) { fclose(stdout); } if (ERRORFILE != stderr) { fclose(stderr); } if (chdir(primary_app_dir) != 0) { fprintf(LOGFILE, "Failed to chdir to app dir - %s\n", strerror(errno)); return -1; } execvp(args[0], args); fprintf(ERRORFILE, "Failure to exec app initialization process - %s\n", strerror(errno)); return -1; }
void test_delete_task() { if (initialize_user(username)) { printf("FAIL: failed to initialize user %s\n", username); exit(1); } char* job_dir = get_job_directory(TEST_ROOT "/local-2", username, "job_1"); char* dont_touch = get_job_directory(TEST_ROOT "/local-2", username, DONT_TOUCH_FILE); char* task_dir = get_attempt_work_directory(TEST_ROOT "/local-2", username, "job_1", "task_1"); char buffer[100000]; sprintf(buffer, "mkdir -p %s/who/let/the/dogs/out/who/who", task_dir); run(buffer); sprintf(buffer, "touch %s", dont_touch); run(buffer); // soft link to the canary file from the task directory sprintf(buffer, "ln -s %s %s/who/softlink", dont_touch, task_dir); run(buffer); // hard link to the canary file from the task directory sprintf(buffer, "ln %s %s/who/hardlink", dont_touch, task_dir); run(buffer); // create a dot file in the task directory sprintf(buffer, "touch %s/who/let/.dotfile", task_dir); run(buffer); // create a no permission file sprintf(buffer, "touch %s/who/let/protect", task_dir); run(buffer); sprintf(buffer, "chmod 000 %s/who/let/protect", task_dir); run(buffer); // create a no permission directory sprintf(buffer, "chmod 000 %s/who/let", task_dir); run(buffer); // delete task directory char * dirs[] = {job_dir, 0}; int ret = delete_as_user(username, "task_1" , dirs); if (ret != 0) { printf("FAIL: return code from delete_as_user is %d\n", ret); exit(1); } // check to make sure the task directory is gone if (access(task_dir, R_OK) == 0) { printf("FAIL: failed to delete the directory - %s\n", task_dir); exit(1); } // check to make sure the job directory is not gone if (access(job_dir, R_OK) != 0) { printf("FAIL: accidently deleted the directory - %s\n", job_dir); exit(1); } // but that the canary is not gone if (access(dont_touch, R_OK) != 0) { printf("FAIL: accidently deleted file %s\n", dont_touch); exit(1); } sprintf(buffer, "chmod -R 700 %s", job_dir); run(buffer); sprintf(buffer, "rm -fr %s", job_dir); run(buffer); free(job_dir); free(task_dir); free(dont_touch); }
int launch_container_as_user(const char *user, const char *app_id, const char *container_id, const char *work_dir, const char *script_name, const char *cred_file, const char* pid_file, char* const* local_dirs, char* const* log_dirs, const char *resources_key, char* const* resources_values) { int exit_code = -1; char *script_file_dest = NULL; char *cred_file_dest = NULL; script_file_dest = get_container_launcher_file(work_dir); if (script_file_dest == NULL) { exit_code = OUT_OF_MEMORY; goto cleanup; } cred_file_dest = get_container_credentials_file(work_dir); if (NULL == cred_file_dest) { exit_code = OUT_OF_MEMORY; goto cleanup; } // open launch script int container_file_source = open_file_as_nm(script_name); if (container_file_source == -1) { goto cleanup; } // open credentials int cred_file_source = open_file_as_nm(cred_file); if (cred_file_source == -1) { goto cleanup; } // setsid pid_t pid = setsid(); if (pid == -1) { exit_code = SETSID_OPER_FAILED; goto cleanup; } // write pid to pidfile if (pid_file == NULL || write_pid_to_file_as_nm(pid_file, pid) != 0) { exit_code = WRITE_PIDFILE_FAILED; goto cleanup; } // cgroups-based resource enforcement if (resources_key != NULL && ! strcmp(resources_key, "cgroups")) { // write pid to cgroups char* const* cgroup_ptr; for (cgroup_ptr = resources_values; cgroup_ptr != NULL && *cgroup_ptr != NULL; ++cgroup_ptr) { if (strcmp(*cgroup_ptr, "none") != 0 && write_pid_to_cgroup_as_root(*cgroup_ptr, pid) != 0) { exit_code = WRITE_CGROUP_FAILED; goto cleanup; } } } // create the user directory on all disks int result = initialize_user(user, local_dirs); if (result != 0) { return result; } // initializing log dirs int log_create_result = create_log_dirs(app_id, log_dirs); if (log_create_result != 0) { return log_create_result; } // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { exit_code = SETUID_OPER_FAILED; goto cleanup; } // Create container specific directories as user. If there are no resources // to localize for this container, app-directories and log-directories are // also created automatically as part of this call. if (create_container_directories(user, app_id, container_id, local_dirs, log_dirs, work_dir) != 0) { fprintf(LOGFILE, "Could not create container dirs"); goto cleanup; } // 700 if (copy_file(container_file_source, script_name, script_file_dest,S_IRWXU) != 0) { goto cleanup; } // 600 if (copy_file(cred_file_source, cred_file, cred_file_dest, S_IRUSR | S_IWUSR) != 0) { goto cleanup; } fcloseall(); umask(0027); if (chdir(work_dir) != 0) { fprintf(LOGFILE, "Can't change directory to %s -%s\n", work_dir, strerror(errno)); goto cleanup; } if (execlp(script_file_dest, script_file_dest, NULL) != 0) { fprintf(LOGFILE, "Couldn't execute the container launch file %s - %s", script_file_dest, strerror(errno)); exit_code = UNABLE_TO_EXECUTE_CONTAINER_SCRIPT; goto cleanup; } exit_code = 0; cleanup: free(script_file_dest); free(cred_file_dest); return exit_code; }