#include #include #include #include #include #include /* for isdigit(), etc. */ #include #include "../global.h" #include "../custom.h" #include "shared_util.h" #include "shared_lock.h" #include "shared_authenticate.h" #include "shared_file_util.h" #include "shared_super_util.h" /* for type definitions */ #include "shared_strtrm.h" #include "shared_server_string.h" #include "shared_cs_util.h" void list_server_commands(ADMIN_CONFIG_STRUCT *conf); void list_course_commands(ADMIN_CONFIG_STRUCT *conf); void list_people_commands(ADMIN_CONFIG_STRUCT *conf); void read_param (char *key) { cs_get_required_parameter ("id", key, MAX_KEY); } static int admin_config_value(char *name) { char tmp[20]; cs_get_optional_parameter(name, tmp, 19); if(strlen(tmp)) return (atoi(tmp)); else return 0; } void get_cgi_admin_config_values(ADMIN_CONFIG_STRUCT *conf) { cs_get_optional_parameter("page_title", conf->page_title, MAX_ADMIN_PAGE_TITLE); strtrm(conf->page_title); conf->is_super_user = 0; conf->create_new_course = admin_config_value("create_new_course"); conf->delete_courses = admin_config_value("delete_courses"); conf->config_courses = admin_config_value("config_courses"); conf->change_course_access = admin_config_value("change_courses"); conf->archive_courses = admin_config_value("archive_courses"); conf->course_disk_usage = admin_config_value("course_disk_usage"); conf->purge_postoffice_message = admin_config_value("purge_postoffice_message"); conf->admin_surveys = admin_config_value("admin_survey"); conf->add_admin = admin_config_value("add_admin"); conf->del_admin = admin_config_value("del_admin"); conf->grant_admin = admin_config_value("grant_admin"); conf->search_profiles = admin_config_value("search_profile"); conf->whos_on = admin_config_value("whos_on"); conf->statistics = admin_config_value("statistics"); conf->disk_space = admin_config_value("disk_space"); conf->chat_server = admin_config_value("chat_server"); conf->lock_server = admin_config_value("lock_server"); conf->clean_up = admin_config_value("clean_up"); } void check_str(char *str, const char * msg) { char *ptr; for(ptr = str; (*ptr); ptr++) { if(!(*ptr == '_') && !isdigit(*ptr) && !isalpha(*ptr)) cs_critical_error(msg, ""); } } void write_to_index(const char *username, const char *realname) { FILE *fp; char fname[MAX_PATH +1]; snprintf(fname, MAX_PATH +1, "../%s/%s/%s", USERS_DIR, ADMIN_DIR, USER_INDEX_FNAME); fp = fopen(fname, "a+"); if(!fp) cs_critical_error( ERR_FOPEN_WRITE_FAILED, ""); get_exclusive_lock(fileno(fp), 1); fprintf(fp, "%s:%s\n", username, realname); release_lock(fileno(fp)); fclose(fp); } void get_admin_user_passwd(const char *username, char *passwd) { FILE *fp; char fname[MAX_PATH +1]; snprintf(fname, MAX_PATH +1, "../%s/%s/%c/%s/%s", USERS_DIR, ADMIN_DIR, sub_dir_name(username), username, PASSWD_FNAME); fp = fopen(fname, "r"); if(!fp) cs_critical_error(ERR_FOPEN_READ_FAILED, ""); if(!fgets(passwd, MAX_ENCRYPTED_PASSWORD + 1, fp) ) { fclose(fp); cs_critical_error(ERR_FREAD_FAILED, ""); } strtrm(passwd); /* shared_strtrm.c */ fclose(fp); } void set_one_oper_value(const char *prefix, int num, char *value) { #define MAX_TMP_NAME 40 char name[MAX_NAME]; snprintf(name, MAX_NAME, "%s.%d", prefix, num); cs_set_value(name, value); #undef MAX_TMP_NAME } void super_conf_info_table(ADMIN_CONFIG_STRUCT *conf, char *username, char *realname) { char server_string[MAX_PATH +1]; char url[MAX_PATH +1]; int i = 0; cs_set_current_time(); cs_set_server_name(); cs_set_value("username", username); cs_set_value("realname", realname); if(conf->create_new_course) { set_one_oper_value("conf_course", i, "create_course"); i++; } if(conf->delete_courses) { set_one_oper_value("conf_course", i, "delete_course"); i++; } if(conf->config_courses) { set_one_oper_value("conf_course", i, "configure_course"); i++; } if(conf->change_course_access) { set_one_oper_value("conf_course", i, "change_course_access"); i++; } if(conf->archive_courses) { set_one_oper_value("conf_course", i, "archive_courses"); i++; } if(conf->admin_surveys) set_one_oper_value("conf_course", i, "surveys"); i =0; if(conf->search_profiles) { set_one_oper_value("conf_people", i, "profile"); i++; } if(conf->whos_on) { set_one_oper_value("conf_people", i, "who_is_on_manhattan"); i++; } if(conf->statistics) { set_one_oper_value("conf_people", i, "login_logs"); i++; } i =0; if(conf->disk_space) { set_one_oper_value("conf_usageReport", i, "disk_space"); i++; } if(conf->course_disk_usage) { set_one_oper_value("conf_usageReport", i, "course_disk_usage"); i++; } i = 0; if(conf->chat_server) { set_one_oper_value("conf_server", i, "manage_chat"); i++; } if(conf->lock_server) { set_one_oper_value("conf_server", i, "lock_server"); i++; } i = 0; if(conf->clean_up) { set_one_oper_value("conf_cleanup", i, "clean_up"); i++; } if(conf->purge_postoffice_message) { set_one_oper_value("conf_cleanup", i, "purge_postoffice_message"); i++; } get_server_string(server_string, MAX_PATH +1); snprintf(url, MAX_PATH +1, "%s/%s/%s",server_string, SBIN_ALIAS, "super_doorstep"); cs_set_value("url", url); } static DEL_COURSE_NODE * get_node(char *str) { DEL_COURSE_NODE *ptr; char *str_ptr; str_ptr = strchr(str, ':'); if(!str_ptr) cs_critical_error(ERR_PARAM_FORMAT, "course_list"); ptr = (DEL_COURSE_NODE *)malloc(sizeof(DEL_COURSE_NODE)); if(!ptr) cs_critical_error(ERR_MALLOC_FAILED, ""); ptr->next = 0; *str_ptr = '\0'; ptr->del_id = malloc_str(str); *str_ptr = ':'; str_ptr++; ptr->del_info = malloc_str(str_ptr); return ptr; } DEL_COURSE_NODE * build_selected_course_list() { DEL_COURSE_NODE *ptr, *head =0, *current=0; char *str; HDF *obj; str = hdf_get_value(global_cgi->hdf, "Query.course_list.0", 0); if(str) { obj = hdf_get_child(global_cgi->hdf, "Query.course_list"); while(obj) { str = obj->value; if(str) { ptr = get_node(str); if(!head) head = ptr; else current->next = ptr; current = ptr; } obj = obj->next; } } else { str = hdf_get_value(global_cgi->hdf, "Query.course_list", 0); if(!str) cs_critical_error(ERR_PARAM_MISSING, "course_list"); head = get_node(str); } return head; } void free_del_list(DEL_COURSE_NODE *head) { DEL_COURSE_NODE *ptr; while(head) { ptr = head->next; if(head->del_id) free(head->del_id); if(head->del_info) free(head->del_info); free(head); head = ptr; } } /*** does conf contain actions that **** should be placed under 'Courses' **** on the sys admin's menu? ***/ int has_course_progs(ADMIN_CONFIG_STRUCT *conf) { return (conf->create_new_course || conf->delete_courses || conf->config_courses || conf->admin_surveys); } /*** does conf contain actions that **** should be placed under 'People' **** on the sys admin's menu? ***/ int has_people_progs(ADMIN_CONFIG_STRUCT *conf) { return ( conf->search_profiles || conf-> whos_on || conf->statistics); } /*** does conf contain actions that **** should be placed under 'Server' **** on the sys admin's menu? ***/ int has_server_progs(ADMIN_CONFIG_STRUCT *conf) { return (conf->disk_space || conf->chat_server || conf->lock_server || conf->course_disk_usage || conf->purge_postoffice_message || conf->clean_up); } int read_super_configuration_file (const char *username, ADMIN_CONFIG_STRUCT * config) { FILE *fp; int fd; char fullpath[MAX_PATH + 1]; snprintf (fullpath, MAX_PATH + 1, "../%s/%s/%c/%s/%s", USERS_DIR, ADMIN_DIR, sub_dir_name(username),username, CONFIG_FNAME); fp = fopen (fullpath, "r"); if (!fp) return 0; fd = fileno(fp); get_shared_lock(fd, 1); /* shared_lock.c */ if (fread (config, sizeof (ADMIN_CONFIG_STRUCT), 1, fp) != 1) { release_lock(fd); fclose(fp); return 0; } release_lock(fd); /* shared_lock.c */ fclose (fp); return 1; /* success */ } int write_super_configuration_file (const char *username, ADMIN_CONFIG_STRUCT * config) { FILE *fp; char fullpath[MAX_PATH + 1]; snprintf (fullpath, MAX_PATH + 1, "../%s/%s/%c/%s/%s", USERS_DIR, ADMIN_DIR, sub_dir_name(username),username, CONFIG_FNAME); fp = fopen (fullpath, "w"); if (!fp) return 0; if (fwrite(config, sizeof (ADMIN_CONFIG_STRUCT), 1, fp) != 1) { fclose(fp); return 0; } fclose (fp); return 1; /* success */ } /** is username the administrative *** super user? ***/ static int is_super_user(const char *username) { ADMIN_CONFIG_STRUCT conf; if(!read_super_configuration_file(username, &conf) || !conf.is_super_user) return 0; else return 1; } /* does list of users have at least one admin * that is NOT the super user ? */ int has_other_admins(ADMIN_USER *head) { ADMIN_USER *ptr; for(ptr = head; ptr; ptr = ptr->next) if(!ptr->is_super_user) return 1; return 0; } /*** builds a linked list **** of administrative users from the ../users/admin/index.txt file **** **** ADMIN_USER is #defined in shared_super_util.h ***/ ADMIN_USER * build_admin_user_list() { #define MAX_LINE 200 FILE *fp; char fname[MAX_PATH +1]; char line[MAX_LINE +1]; char *chr_ptr; ADMIN_USER *head = 0, *ptr, *current=0; snprintf(fname, MAX_PATH +1, "../%s/%s/%s", USERS_DIR, ADMIN_DIR, USER_INDEX_FNAME); fp = fopen(fname, "r"); if(!fp) cs_critical_error(ERR_FOPEN_READ_FAILED, ""); get_shared_lock(fileno(fp), 1); while(fgets(line, MAX_LINE, fp)) { strtrm(line); /* shared_strtrm.c */ ptr = (ADMIN_USER *)malloc(sizeof(ADMIN_USER)); chr_ptr = strchr(line, ':'); if(!chr_ptr) cs_critical_error( ERR_FILE_FORMAT_ERROR, ""); *chr_ptr = '\0'; strncpy(ptr->username, line, MAX_USERNAME + 1); /* copy username field */ chr_ptr++; strncpy(ptr->realname, chr_ptr, MAX_NAME +1); /* copy realname field */ ptr->is_super_user = is_super_user(ptr->username); ptr->next = 0; if(!head) head = ptr; else current->next = ptr; current = ptr; } release_lock(fileno(fp)); fclose(fp); return head; #undef MAX_LINE } void free_admin_user_list(ADMIN_USER *list) { ADMIN_USER *ptr; while(list) { ptr = list->next; free(list); list = ptr; } } static void set_checkbox(const char *prefix, int num, int selected) { #define MAX_TMP_NAME 30 char name[MAX_TMP_NAME]; snprintf(name, MAX_TMP_NAME, "%s.%d.selected", prefix, num); if(selected) cs_set_int_value(name, 1); else cs_set_int_value(name, 0); #undef MAX_TMP_NAME } void list_course_commands(ADMIN_CONFIG_STRUCT *conf) { int i =0; set_checkbox("conf_course", i, conf->create_new_course); i++; set_checkbox("conf_course", i, conf->delete_courses); i++; set_checkbox("conf_course",i, conf->config_courses); i++; set_checkbox("conf_course",i, conf->change_course_access); i++; set_checkbox("conf_course",i, conf->archive_courses); i++; set_checkbox("conf_course", i, conf->admin_surveys); i++; } void list_people_commands(ADMIN_CONFIG_STRUCT *conf) { /** note the ability to add/delete/modify administrators is NEVER *** given to anyone but the super user **/ int i =0; set_checkbox("conf_people", i,conf->search_profiles); i++; set_checkbox("conf_people", i, conf->whos_on); i++; set_checkbox("conf_people", i, conf->statistics); } void list_server_commands(ADMIN_CONFIG_STRUCT *conf) { int i =0; set_checkbox("conf_server", i, conf->disk_space); i++; set_checkbox("conf_server",i, conf->course_disk_usage); i++; set_checkbox("conf_server", i, conf->chat_server); i++; set_checkbox("conf_server", i, conf->lock_server); i++; set_checkbox("conf_server", i, conf->clean_up); i++; set_checkbox("conf_server",i, conf->purge_postoffice_message); } void set_admin_data( ADMIN_USER *list) { #define MAX_TMP_NAME 30 ADMIN_USER *ptr; char name[MAX_TMP_NAME]; int i =0; for(ptr = list; ptr; ptr = ptr->next) { if(!ptr->is_super_user) /* never show the super user */ { snprintf(name, MAX_TMP_NAME, "user.%d.username",i); cs_set_value(name, ptr->username); snprintf(name, MAX_TMP_NAME, "user.%d.realname",i); cs_set_value(name, ptr->realname); i++; } } #undef MAX_TMP_NAME }