//placeholder for global cleanup operations void cleanup() { free_configurations(); }
int main(int argc, char **argv) { LOGFILE = stdout; int my_username = 0; // clean up any junk from previous run system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT); if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) { exit(1); } if (write_config_file(TEST_ROOT "/test.cfg") != 0) { exit(1); } read_config(TEST_ROOT "/test.cfg"); create_tt_roots(); if (getuid() == 0 && argc == 2) { username = argv[1]; } else { username = strdup(getpwuid(getuid())->pw_name); my_username = 1; } set_tasktracker_uid(geteuid(), getegid()); if (set_user(username)) { exit(1); } printf("\nStarting tests\n"); printf("\nTesting get_user_directory()\n"); test_get_user_directory(); printf("\nTesting get_job_directory()\n"); test_get_job_directory(); printf("\nTesting get_attempt_directory()\n"); test_get_attempt_directory(); printf("\nTesting get_task_launcher_file()\n"); test_get_task_launcher_file(); printf("\nTesting get_job_log_dir()\n"); test_get_job_log_dir(); test_check_configuration_permissions(); printf("\nTesting delete_task()\n"); test_delete_task(); printf("\nTesting delete_job()\n"); test_delete_job(); test_delete_user(); test_check_user(); // the tests that change user need to be run in a subshell, so that // when they change user they don't give up our privs run_test_in_child("test_signal_task", test_signal_task); run_test_in_child("test_signal_task_group", test_signal_task_group); // init job and run task can't be run if you aren't testing as root if (getuid() == 0) { // these tests do internal forks so that the change_owner and execs // don't mess up our process. test_init_job(); test_run_task(); } seteuid(0); run("rm -fr " TEST_ROOT); printf("\nFinished tests\n"); if (my_username) { free(username); } free_configurations(); return 0; }
// This test is expected to be executed either by a regular // user or by root. If executed by a regular user it doesn't // test all the functions that would depend on changing the // effective user id. If executed by a super-user everything // gets tested. Here are different ways of execing the test binary: // 1. regular user assuming user == yarn user // $ test-container-executor // 2. regular user with a given yarn user // $ test-container-executor yarn_user // 3. super user with a given user and assuming user == yarn user // # test-container-executor user // 4. super user with a given user and a given yarn user // # test-container-executor user yarn_user int main(int argc, char **argv) { LOGFILE = stdout; ERRORFILE = stderr; // clean up any junk from previous run if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) { exit(1); } if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) { exit(1); } if (write_config_file(TEST_ROOT "/test.cfg", 1) != 0) { exit(1); } read_config(TEST_ROOT "/test.cfg"); local_dirs = extract_values(strdup(NM_LOCAL_DIRS)); log_dirs = extract_values(strdup(NM_LOG_DIRS)); create_nm_roots(local_dirs); // See the description above of various ways this test // can be executed in order to understand the following logic char* current_username = strdup(getpwuid(getuid())->pw_name); if (getuid() == 0 && (argc == 2 || argc == 3)) { username = argv[1]; yarn_username = (argc == 3) ? argv[2] : argv[1]; } else { username = current_username; yarn_username = (argc == 2) ? argv[1] : current_username; } set_nm_uid(geteuid(), getegid()); if (set_user(username)) { exit(1); } printf("\nStarting tests\n"); printf("\nTesting resolve_config_path()\n"); test_resolve_config_path(); printf("\nTesting get_user_directory()\n"); test_get_user_directory(); printf("\nTesting get_app_directory()\n"); test_get_app_directory(); printf("\nTesting get_container_directory()\n"); test_get_container_directory(); printf("\nTesting get_container_launcher_file()\n"); test_get_container_launcher_file(); printf("\nTesting get_app_log_dir()\n"); test_get_app_log_dir(); test_check_configuration_permissions(); printf("\nTesting delete_container()\n"); test_delete_container(); printf("\nTesting delete_app()\n"); test_delete_app(); test_check_user(0); // the tests that change user need to be run in a subshell, so that // when they change user they don't give up our privs run_test_in_child("test_signal_container", test_signal_container); run_test_in_child("test_signal_container_group", test_signal_container_group); // init app and run container can't be run if you aren't testing as root if (getuid() == 0) { // these tests do internal forks so that the change_owner and execs // don't mess up our process. test_init_app(); test_run_container(); } seteuid(0); // test_delete_user must run as root since that's how we use the delete_as_user test_delete_user(); free_configurations(); printf("\nTrying banned default user()\n"); if (write_config_file(TEST_ROOT "/test.cfg", 0) != 0) { exit(1); } read_config(TEST_ROOT "/test.cfg"); username = "******"; test_check_user(1); username = "******"; test_check_user(1); run("rm -fr " TEST_ROOT); printf("\nFinished tests\n"); free(current_username); free_configurations(); return 0; }
//function used to load the configurations present in the secure config void get_configs() { FILE *conf_file; char *line; char *equaltok; char *temp_equaltok; size_t linesize = 1000; int size_read = 0; int str_len = 0; char *file_name = NULL; #ifndef HADOOP_CONF_DIR str_len = strlen(CONF_FILE_PATTERN) + strlen(hadoop_conf_dir); file_name = (char *) malloc(sizeof(char) * (str_len + 1)); #else str_len = strlen(CONF_FILE_PATTERN) + strlen(HADOOP_CONF_DIR); file_name = (char *) malloc(sizeof(char) * (str_len + 1)); #endif if (file_name == NULL) { fprintf(LOGFILE, "Malloc failed :Out of memory \n"); return; } memset(file_name,'\0',str_len +1); #ifndef HADOOP_CONF_DIR snprintf(file_name,str_len, CONF_FILE_PATTERN, hadoop_conf_dir); #else snprintf(file_name, str_len, CONF_FILE_PATTERN, HADOOP_CONF_DIR); #endif #ifdef DEBUG fprintf(LOGFILE,"get_configs :Conf file name is : %s \n", file_name); #endif //allocate space for ten configuration items. config.confdetails = (struct confentry **) malloc(sizeof(struct confentry *) * MAX_SIZE); config.size = 0; conf_file = fopen(file_name, "r"); if (conf_file == NULL) { fprintf(LOGFILE, "Invalid conf file provided : %s \n", file_name); free(file_name); return; } while(!feof(conf_file)) { line = (char *) malloc(linesize); if(line == NULL) { fprintf(LOGFILE,"malloc failed while reading configuration file.\n"); goto cleanup; } size_read = getline(&line,&linesize,conf_file); //feof returns true only after we read past EOF. //so a file with no new line, at last can reach this place //if size_read returns negative check for eof condition if (size_read == -1) { if(!feof(conf_file)){ fprintf(LOGFILE, "getline returned error.\n"); goto cleanup; }else { break; } } //trim the ending new line line[strlen(line)-1] = '\0'; //comment line if(line[0] == '#') { free(line); continue; } //tokenize first to get key and list of values. //if no equals is found ignore this line, can be an empty line also equaltok = strtok_r(line, "=", &temp_equaltok); if(equaltok == NULL) { free(line); continue; } config.confdetails[config.size] = (struct confentry *) malloc( sizeof(struct confentry)); if(config.confdetails[config.size] == NULL) { fprintf(LOGFILE, "Failed allocating memory for single configuration item\n"); goto cleanup; } #ifdef DEBUG fprintf(LOGFILE,"get_configs : Adding conf key : %s \n", equaltok); #endif memset(config.confdetails[config.size], 0, sizeof(struct confentry)); config.confdetails[config.size]->key = (char *) malloc( sizeof(char) * (strlen(equaltok)+1)); strcpy((char *)config.confdetails[config.size]->key, equaltok); equaltok = strtok_r(NULL, "=", &temp_equaltok); if (equaltok == NULL) { fprintf(LOGFILE, "configuration tokenization failed \n"); goto cleanup; } //means value is commented so don't store the key if(equaltok[0] == '#') { free(line); free((void *)config.confdetails[config.size]->key); free(config.confdetails[config.size]); continue; } #ifdef DEBUG fprintf(LOGFILE,"get_configs : Adding conf value : %s \n", equaltok); #endif config.confdetails[config.size]->value = (char *) malloc( sizeof(char) * (strlen(equaltok)+1)); strcpy((char *)config.confdetails[config.size]->value, equaltok); if((config.size + 1) % MAX_SIZE == 0) { config.confdetails = (struct confentry **) realloc(config.confdetails, sizeof(struct confentry **) * (MAX_SIZE + config.size)); if (config.confdetails == NULL) { fprintf(LOGFILE, "Failed re-allocating memory for configuration items\n"); goto cleanup; } } if(config.confdetails[config.size] ) config.size++; free(line); } //close the file fclose(conf_file); //clean up allocated file name free(file_name); return; //free spaces alloced. cleanup: if (line != NULL) { free(line); } fclose(conf_file); free(file_name); free_configurations(); return; }
void read_config(const char* file_name, struct configuration *cfg) { FILE *conf_file; char *line; char *equaltok; char *temp_equaltok; size_t linesize = 1000; int size_read = 0; if (file_name == NULL) { fprintf(ERRORFILE, "Null configuration filename passed in\n"); exit(INVALID_CONFIG_FILE); } #ifdef DEBUG fprintf(LOGFILE, "read_config :Conf file name is : %s \n", file_name); #endif //allocate space for ten configuration items. cfg->confdetails = (struct confentry **) malloc(sizeof(struct confentry *) * MAX_SIZE); cfg->size = 0; conf_file = fopen(file_name, "r"); if (conf_file == NULL) { fprintf(ERRORFILE, "Invalid conf file provided : %s \n", file_name); exit(INVALID_CONFIG_FILE); } while(!feof(conf_file)) { line = (char *) malloc(linesize); if(line == NULL) { fprintf(ERRORFILE, "malloc failed while reading configuration file.\n"); exit(OUT_OF_MEMORY); } size_read = getline(&line,&linesize,conf_file); //feof returns true only after we read past EOF. //so a file with no new line, at last can reach this place //if size_read returns negative check for eof condition if (size_read == -1) { free(line); if(!feof(conf_file)){ exit(INVALID_CONFIG_FILE); } else { break; } } int eol = strlen(line) - 1; if(line[eol] == '\n') { //trim the ending new line line[eol] = '\0'; } //comment line if(line[0] == '#') { free(line); continue; } //tokenize first to get key and list of values. //if no equals is found ignore this line, can be an empty line also equaltok = strtok_r(line, "=", &temp_equaltok); if(equaltok == NULL) { free(line); continue; } cfg->confdetails[cfg->size] = (struct confentry *) malloc( sizeof(struct confentry)); if(cfg->confdetails[cfg->size] == NULL) { fprintf(LOGFILE, "Failed allocating memory for single configuration item\n"); goto cleanup; } #ifdef DEBUG fprintf(LOGFILE, "read_config : Adding conf key : %s \n", equaltok); #endif memset(cfg->confdetails[cfg->size], 0, sizeof(struct confentry)); cfg->confdetails[cfg->size]->key = (char *) malloc( sizeof(char) * (strlen(equaltok)+1)); strcpy((char *)cfg->confdetails[cfg->size]->key, equaltok); equaltok = strtok_r(NULL, "=", &temp_equaltok); if (equaltok == NULL) { fprintf(LOGFILE, "configuration tokenization failed \n"); goto cleanup; } //means value is commented so don't store the key if(equaltok[0] == '#') { free(line); free((void *)cfg->confdetails[cfg->size]->key); free(cfg->confdetails[cfg->size]); continue; } #ifdef DEBUG fprintf(LOGFILE, "read_config : Adding conf value : %s \n", equaltok); #endif cfg->confdetails[cfg->size]->value = (char *) malloc( sizeof(char) * (strlen(equaltok)+1)); strcpy((char *)cfg->confdetails[cfg->size]->value, equaltok); if((cfg->size + 1) % MAX_SIZE == 0) { cfg->confdetails = (struct confentry **) realloc(cfg->confdetails, sizeof(struct confentry **) * (MAX_SIZE + cfg->size)); if (cfg->confdetails == NULL) { fprintf(LOGFILE, "Failed re-allocating memory for configuration items\n"); goto cleanup; } } if(cfg->confdetails[cfg->size]) { cfg->size++; } free(line); } //close the file fclose(conf_file); if (cfg->size == 0) { fprintf(ERRORFILE, "Invalid configuration provided in %s\n", file_name); exit(INVALID_CONFIG_FILE); } //clean up allocated file name return; //free spaces alloced. cleanup: if (line != NULL) { free(line); } fclose(conf_file); free_configurations(cfg); return; }
int main(int argc, char **argv) { LOGFILE = stdout; ERRORFILE = stderr; int my_username = 0; // clean up any junk from previous run system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT); if (mkdirs(TEST_ROOT "/logs/userlogs", 0755) != 0) { exit(1); } if (write_config_file(TEST_ROOT "/test.cfg") != 0) { exit(1); } read_config(TEST_ROOT "/test.cfg"); local_dirs = (char *) malloc (sizeof(char) * ARRAY_SIZE); strcpy(local_dirs, NM_LOCAL_DIRS); log_dirs = (char *) malloc (sizeof(char) * ARRAY_SIZE); strcpy(log_dirs, NM_LOG_DIRS); create_nm_roots(extract_values(local_dirs)); if (getuid() == 0 && argc == 2) { username = argv[1]; } else { username = strdup(getpwuid(getuid())->pw_name); my_username = 1; } set_nm_uid(geteuid(), getegid()); if (set_user(username)) { exit(1); } printf("\nStarting tests\n"); printf("\nTesting get_user_directory()\n"); test_get_user_directory(); printf("\nTesting get_app_directory()\n"); test_get_app_directory(); printf("\nTesting get_container_directory()\n"); test_get_container_directory(); printf("\nTesting get_container_launcher_file()\n"); test_get_container_launcher_file(); printf("\nTesting get_app_log_dir()\n"); test_get_app_log_dir(); test_check_configuration_permissions(); printf("\nTesting delete_container()\n"); test_delete_container(); printf("\nTesting delete_app()\n"); test_delete_app(); test_delete_user(); test_check_user(); // the tests that change user need to be run in a subshell, so that // when they change user they don't give up our privs run_test_in_child("test_signal_container", test_signal_container); run_test_in_child("test_signal_container_group", test_signal_container_group); // init app and run container can't be run if you aren't testing as root if (getuid() == 0) { // these tests do internal forks so that the change_owner and execs // don't mess up our process. test_init_app(); test_run_container(); } seteuid(0); run("rm -fr " TEST_ROOT); printf("\nFinished tests\n"); if (my_username) { free(username); } free_configurations(); return 0; }