/* manages the /etc/security/console.perms file */ #include #include #include #include "pamconf.h" #include "pamconf.m" #include "pamconf_tools.h" #include "fviews.h" /* removes the < > which embraces the classnames */ void remove_ltgt(SSTRING &given_string) { if(given_string.getlen()>2){ SSTRING temp_str; given_string.truncate(given_string.getlen()-1); given_string.copy(temp_str); given_string.setfrom(temp_str.get()+1); } } /* adds the typical < > which embraces the classnames */ void surround_with_ltgt(SSTRING &given_string) { SSTRING temp_str; given_string.copy(temp_str); given_string.setfromf("<%s>", temp_str.get()); } /* fills combo with all defined class names */ void fill_combo_cp_with(VIEWITEMS &given_vitems, FIELD_COMBO *given_combo) { SSTRING *current_line; int total_groups; int my_counter=0; SSTRING classname; total_groups=given_vitems.getnb(); while(total_groups--){ current_line=&(given_vitems.getitem(my_counter++)->line); if(strchr(current_line->get(), '=')){ gimme_word_from_string_bchar(current_line->get(), classname, 0, '='); given_combo->addopt(classname.get()); } } } /* translate the number returned after selected an item to a real line number in VIEWITEMS. if is_class_atribution!=0 then only lines having '=' will be considered, otherwise only the ones which haven't '='. */ int return_coords_consperms(int reported_entry, int is_class_atribution, VIEWITEMS &given_sstrings) { SSTRING *current_line; int total_groups; int linenumber_to_report=0; int my_counter=0; int valid_lines_counter=0; total_groups=given_sstrings.getnb(); while(total_groups--){ current_line=&(given_sstrings.getitem(my_counter++)->line); if(is_class_atribution){ // must have '=' if(strchr(current_line->get(), '=')){ if(reported_entry==valid_lines_counter) linenumber_to_report=my_counter-1; valid_lines_counter++; } }else{ if(!strchr(current_line->get(), '=')){ if(reported_entry==valid_lines_counter) linenumber_to_report=my_counter-1; valid_lines_counter++; } } } return(linenumber_to_report); } void consperms_entries_props(int which_line, VIEWITEMS &given_vitems, int pseudo_line_number) { DIALOG my_dialog; MENU_STATUS my_button=MENU_NULL; int my_selection=0; SSTRING title_text; SSTRING *current_line; SSTRING console, perm1, devh, perm2, rootsomething; FIELD_COMBO *fc_console, *fc_devh; int spaces_present; /* !=0 if there are space characters in some entry */ current_line=&(given_vitems.getitem(which_line)->line); title_text.setfromf(MSG_U(T_CPCONSPERMENTRYN, "Console perm entry #%d"), pseudo_line_number+1); /* load vars */ gimme_word_from_string(current_line->get(), console, 0); gimme_word_from_string(current_line->get(), perm1, 1); gimme_word_from_string(current_line->get(), devh, 2); gimme_word_from_string(current_line->get(), perm2, 3); gimme_word_from_string(current_line->get(), rootsomething, 4); /* builds gui */ fc_console=my_dialog.newf_combo(MSG_U(F_CPCONSOLE, "Console:"), console); fill_combo_cp_with(given_vitems, fc_console); my_dialog.newf_str(MSG_U(F_CPPERMISSION, "Permission:"), perm1); fc_devh=my_dialog.newf_combo(MSG_U(F_CPDEVICE, "Device:"), devh); fill_combo_cp_with(given_vitems, fc_devh); my_dialog.newf_str(MSG_U(F_CPREVERTMODE, "Revert mode:"), perm2); my_dialog.newf_str(MSG_U(F_CPREVERTUSRDOTGROUP, "Revert user.group:"), rootsomething); while(1){ spaces_present=0; /* opens dialog.. */ my_selection=0; my_button=my_dialog.editmenu(title_text.get(), MSG_U(I_CPCONSPERMENTRYN, "In some fields you may use classes (aliases)\nor enter directly the desired value."), hf_pam_console, my_selection, MENUBUT_QUIT|MENUBUT_DEL|MENUBUT_ACCEPT); switch(my_button){ case MENU_QUIT: case MENU_ESCAPE: return; case MENU_DEL: if(confirm_yesno_window(MSG_U(T_CPENTRYREMOVAL, "Entry removal"), MSG_U(I_CPENTRYREMOVAL, "Do you really want\nto remove this definition?"))){ given_vitems.remove_del(which_line); given_vitems.write(cf_consperms, NULL); return; } break; case MENU_ACCEPT: /* check for spaces in fields which don't tolerate spaces */ SPA(console); SPA(perm1); SPA(devh); SPA(perm2); SPA(rootsomething); if(spaces_present){ spaces_not_allowed(); }else{ current_line->setfromf("%s %s %s %s %s", console.get(), perm1.get(), devh.get(), perm2.get(), rootsomething.get()); /* writes to file */ given_vitems.write(cf_consperms, NULL); return; } break; default: break; } } } void consperms_entries_window(void) { DIALOG_RECORDS my_dialog; MENU_STATUS my_button=MENU_NULL; int my_selection=0; VIEWITEMS_PARSER pre_my_vitems; int real_line_position; while(1){ VIEWITEMS my_vitems(pre_my_vitems); my_vitems.read(cf_consperms); // load file data my_dialog.remove_all(); // cleans window my_dialog.newf_head("", MSG_U(F_CPCPDRRUG, "console\tperm\tdevice\trevert\trevert user.group")); dump_viewitems_to_list(my_dialog, my_vitems, 5, ' ', '='); /* opens dialog.. */ my_selection=0; my_button=my_dialog.editmenu(MSG_U(T_CPENTRIESFORCP, "Entries for console perms"), "", hf_list_edit, my_selection, MENUBUT_QUIT|MENUBUT_ADD); switch(my_button){ case MENU_QUIT: case MENU_ESCAPE: return; case MENU_ADD: my_vitems.add(new VIEWITEM(MSG_U(X_CP_SAMPLE, "whatever 0660 /dev/something 0660 root_or_anything"))); real_line_position=return_coords_consperms(my_selection, 0, my_vitems); consperms_entries_props(my_vitems.getnb()-1, my_vitems, -1); break; default: real_line_position=return_coords_consperms(my_selection, 0, my_vitems); consperms_entries_props(real_line_position, my_vitems, my_selection); break; } } } void consperms_classes_props(int which_line, VIEWITEMS &given_vitems, int pseudo_line_number) { DIALOG my_dialog; MENU_STATUS my_button=MENU_NULL; int my_selection=0; SSTRING title_text; SSTRING *current_line; SSTRING classname, classdata; int spaces_present; /* !=0 if there are space characters in some entry */ current_line=&(given_vitems.getitem(which_line)->line); if(pseudo_line_number<0){ title_text.setfromf(MSG_U(T_CPNEWCLASSENTRY, "New class entry")); }else{ title_text.setfromf(MSG_U(T_CPCONSCLASSENTRYN, "Console class entry #%d"), pseudo_line_number+1); } /* load vars */ gimme_word_from_string_bchar(current_line->get(), classname, 0, '='); gimme_word_from_string_bchar(current_line->get(), classdata, 1, '='); convert_to_textarea(classdata); remove_ltgt(classname); /* removes those <> */ /* builds gui */ if(pseudo_line_number<0){ my_dialog.newf_str(MSG_U(F_CPNAME4NEWCLASS, "Name for new class:"), classname); }else{ my_dialog.newf_info(MSG_U(F_CPCLASSNAME, "Class name:"), classname.get()); } my_dialog.newf_textarea(MSG_U(F_CPMEANSTHESAMEAS, "Means the same as:"), classdata, 30, 4); while(1){ spaces_present=0; /* opens dialog.. */ my_selection=0; my_button=my_dialog.editmenu(title_text.get(), "", help_nil, my_selection, MENUBUT_QUIT|MENUBUT_DEL|MENUBUT_ACCEPT); switch(my_button){ case MENU_QUIT: case MENU_ESCAPE: return; case MENU_DEL: if(confirm_yesno_window(MSG_U(T_CPENTRYREMOVAL2, "Entry removal"), MSG_U(I_CPENTRYREMOVAL2, "Do you really want\nto remove this definition?"))){ surround_with_ltgt(classname); /* surrounds with <> */ given_vitems.remove_del(which_line); given_vitems.write(cf_consperms, NULL); return; } break; case MENU_ACCEPT: /* check for spaces in fields which don't tolerate spaces */ SPA(classname); if(spaces_present){ spaces_not_allowed(); }else{ surround_with_ltgt(classname); /* surrounds with <> */ convert_from_textarea(classdata); current_line->setfromf("%s=%s", classname.get(), classdata.get()); /* writes to file */ given_vitems.write(cf_consperms, NULL); return; } break; default: break; } } } void consperms_classes_window(void) { DIALOG_RECORDS my_dialog; MENU_STATUS my_button=MENU_NULL; int my_selection=0; VIEWITEMS_PARSER pre_my_vitems; int real_line_position; while(1){ VIEWITEMS my_vitems(pre_my_vitems); my_vitems.read(cf_consperms); // load file data my_dialog.remove_all(); // cleans window my_dialog.newf_head("", MSG_U(F_CPCND, "class name\tdefinition")); dump_viewitems_to_list(my_dialog, my_vitems, 2, '=', 0, '='); /* opens dialog.. */ my_selection=0; my_button=my_dialog.editmenu(MSG_U(T_CPCLASS4CONSPERMS, "Classes for console perms"), MSG_U(I_CPCLASS4CONSPERMS, "These classes are like aliases for data\nand can be used in some fields."), hf_list_edit, my_selection, MENUBUT_QUIT|MENUBUT_ADD); switch(my_button){ case MENU_QUIT: case MENU_ESCAPE: return; case MENU_ADD: my_vitems.add(new VIEWITEM(MSG_U(X_CP_SAMPLE_CNSOMETHING, "=/dev/something"))); real_line_position=return_coords_consperms(my_selection, 1, my_vitems); consperms_classes_props(my_vitems.getnb()-1, my_vitems, -1); break; default: real_line_position=return_coords_consperms(my_selection, 1, my_vitems); consperms_classes_props(real_line_position, my_vitems, my_selection); break; } } } void consperms_window(void) { MENU_STATUS my_button=MENU_NULL; int my_selection=0; DIALOG_MENU dia_mymenu; my_selection=0; dia_mymenu.new_menuitem("", MSG_U(M_CPCLASSDEFS, "Classes definitions")); dia_mymenu.new_menuitem("", MSG_U(M_CPENTRIES, "Entries")); while(1){ my_button=dia_mymenu.editmenu(MSG_U(T_CPCONSPERMS, "Console perms (pam_console.so)"), MSG_U(I_CPCONSPERMS, "These settings may grant access to the user for some devices\nusually restricted to the root user."), help_nil, my_selection, MENUBUT_QUIT); if((my_button==MENU_QUIT)||(my_button==MENU_ESCAPE)) return; switch(my_selection){ case 0: consperms_classes_window(); break; case 1: consperms_entries_window(); break; } } }