void test_get_container_launcher_file() { char *expected_file = ("/tmp/usercache/user/appcache/app_200906101234_0001" "/launch_container.sh"); char *app_dir = get_app_directory("/tmp", "user", "app_200906101234_0001"); char *container_file = get_container_launcher_file(app_dir); if (strcmp(container_file, expected_file) != 0) { printf("failure to match expected container file %s vs %s\n", container_file, expected_file); exit(1); } free(app_dir); free(container_file); }
int fork_as_user(const char * working_dir, const char * script_file) { char *script_file_dest = NULL; script_file_dest = get_container_launcher_file(working_dir); if (script_file_dest == NULL) { return OUT_OF_MEMORY; } // open launch script int script_file_source = open_file_as_wl(script_file); if (script_file_source == -1) { return -1; } setsid(); // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { return SETUID_OPER_FAILED; } if (copy_file(script_file_source, script_file, script_file_dest, S_IRWXU) != 0) { return -1; } fcloseall(); umask(0027); if (chdir(working_dir) != 0) { fprintf(LOGFILE, "Can't change directory to %s -%s\n", working_dir, strerror(errno)); return -1; } int pid = fork(); if (pid == 0 && 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)); return UNABLE_TO_EXECUTE_CONTAINER_SCRIPT; } else { fprintf(LOGFILE, "Launched the process from the container launch file %s - with pid %d", script_file_dest, pid); return 0; } //Unreachable return -1; }
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; } } } // give up root privs if (change_user(user_detail->pw_uid, user_detail->pw_gid) != 0) { exit_code = SETUID_OPER_FAILED; goto cleanup; } 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; }
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; char *exit_code_file = 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; } exit_code_file = get_exit_code_file(pid_file); if (NULL == exit_code_file) { 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; } pid_t child_pid = fork(); if (child_pid != 0) { // parent exit_code = wait_and_write_exit_code(child_pid, exit_code_file); 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; } #if HAVE_FCLOSEALL fcloseall(); #else // only those fds are opened assuming no bug fclose(LOGFILE); fclose(ERRORFILE); fclose(stdin); fclose(stdout); fclose(stderr); #endif 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(exit_code_file); free(script_file_dest); free(cred_file_dest); return exit_code; }