# Copyright (C) 2001-2007 Tresys Technology, LLC # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA namespace eval Apol_TE { variable vals variable widgets variable tabs variable enabled } proc Apol_TE::create {tab_name nb} { variable vals variable widgets _initializeVars set frame [$nb insert end $tab_name -text "TE Rules"] set pw [PanedWindow $frame.pw -side left -weights extra] set topf [$pw add -weight 0] set bottomf [$pw add -weight 1] pack $pw -expand 1 -fill both # Major SubFrames: # rsbox - rule selection # oobox - other search options # obox - holds search options widgets # rbox - holds display window widgets # abox - action buttons set top_leftf [frame $topf.tl] set widgets(search_opts) [NoteBook $topf.nb] set abox [frame $topf.abox] pack $top_leftf -side left -expand 0 -fill y pack $widgets(search_opts) -side left -expand 1 -fill both -padx 10 pack $abox -side right -fill y -padx 5 set rsbox [TitleFrame $top_leftf.rsbox -text "Rule Selection"] set oobox [TitleFrame $top_leftf.oobox -text "Search Options"] set rbox [TitleFrame $bottomf.rbox -text "Type Enforcement Rules Display"] pack $rsbox -side top -expand 0 -fill both pack $oobox -side top -expand 1 -fill both -pady 2 pack $rbox -expand yes -fill both -padx 2 # Rule selection subframe set fm_rules [$rsbox getframe] set allow [checkbutton $fm_rules.allow -text "allow" \ -onvalue $::QPOL_RULE_ALLOW -offvalue 0 \ -variable Apol_TE::vals(rs:avrule_allow)] set neverallow [checkbutton $fm_rules.neverallow -text "neverallow" \ -onvalue $::QPOL_RULE_NEVERALLOW -offvalue 0 \ -variable Apol_TE::vals(rs:avrule_neverallow)] set auditallow [checkbutton $fm_rules.auditallow -text "auditallow" \ -onvalue $::QPOL_RULE_AUDITALLOW -offvalue 0 \ -variable Apol_TE::vals(rs:avrule_auditallow)] set dontaudit [checkbutton $fm_rules.dontaudit -text "dontaudit" \ -onvalue $::QPOL_RULE_DONTAUDIT -offvalue 0 \ -variable Apol_TE::vals(rs:avrule_dontaudit)] set type_transition [checkbutton $fm_rules.type_transition -text "type_trans" \ -onvalue $::QPOL_RULE_TYPE_TRANS -offvalue 0 \ -variable Apol_TE::vals(rs:type_transition)] set type_member [checkbutton $fm_rules.type_member -text "type_member" \ -onvalue $::QPOL_RULE_TYPE_MEMBER -offvalue 0 \ -variable Apol_TE::vals(rs:type_member)] set type_change [checkbutton $fm_rules.type_change -text "type_change" \ -onvalue $::QPOL_RULE_TYPE_CHANGE -offvalue 0 \ -variable Apol_TE::vals(rs:type_change)] grid $allow $type_transition -sticky w -padx 2 grid $auditallow $type_member -sticky w -padx 2 grid $dontaudit $type_change -sticky w -padx 2 grid $neverallow x -sticky w -padx 2 foreach x {allow neverallow auditallow dontaudit type_transition type_member type_change} { trace add variable Apol_TE::vals(rs:$x) write \ [list Apol_TE::_toggle_rule_selection] } # Other search options subframe set fm_options [$oobox getframe] set enabled [checkbutton $fm_options.enabled -text "Search only enabled rules" \ -variable Apol_TE::vals(oo:enabled)] set regexp [checkbutton $fm_options.regex -text "Search using regular expression" \ -variable Apol_TE::vals(oo:regexp)] pack $enabled $regexp -expand 0 -fill none -anchor w _createTypesAttribsTab _createClassesPermsTab # Action buttons set widgets(new) [button $abox.new -text "New Search" -width 12 \ -command [list Apol_TE::_search_terules new]] set widgets(update) [button $abox.update -text "Update Search" -width 12 -state disabled \ -command [list Apol_TE::_search_terules update]] set widgets(reset) [button $abox.reset -text "Reset Criteria" -width 12 \ -command Apol_TE::_reset] pack $widgets(new) $widgets(update) $widgets(reset) \ -side top -pady 5 -padx 5 -anchor ne $widgets(search_opts) compute_size # Popup menu widget set popupTab_Menu [menu .popup_terules -tearoff 0] set tab_menu_callbacks \ [list {"Close Tab" Apol_TE::_delete_results} \ {"Rename Tab" Apol_TE::_display_rename_tab_dialog}] # Notebook creation for results set widgets(results) [NoteBook [$rbox getframe].results] $widgets(results) bindtabs Apol_TE::_switch_to_tab $widgets(results) bindtabs \ [list ApolTop::popup \ %W %x %y $popupTab_Menu $tab_menu_callbacks] set close [button [$rbox getframe].close -text "Close Tab" \ -command Apol_TE::_delete_current_results] pack $widgets(results) -expand 1 -fill both -padx 4 pack $close -expand 0 -fill x -padx 4 -pady 2 _initializeVars return $frame } proc Apol_TE::open {ppath} { _initializeVars _initializeWidgets _initializeTabs variable vals variable enabled set vals(cp:classes) [Apol_Class_Perms::getClasses] set enabled(cp:classes) 1 set enabled(cp:perms) 1 } proc Apol_TE::close {} { _initializeTabs _initializeWidgets _initializeVars set enabled(cp:perms) 1 } proc Apol_TE::getTextWidget {} { variable widgets variable tabs if {[$widgets(results) pages] != {}} { set raisedPage [$widgets(results) raise] if {$raisedPage != {}} { return $tabs($raisedPage).tb } } return {} } proc Apol_TE::save_query_options {file_channel query_file} { variable vals foreach {key value} [array get vals] { if {$key != "cp:classes" && $key != "cp:perms"} { puts $file_channel "$key $value" } } } proc Apol_TE::load_query_options {file_channel} { variable vals variable widgets variable enabled _initializeVars # load as many values as possible set classes_selected {} set perms_selected {} while {[gets $file_channel line] >= 0} { set line [string trim $line] # Skip empty lines and comments if {$line == {} || [string index $line 0] == "#"} { continue } regexp -line -- {^(\S+)( (.+))?} $line -> key --> value if {$key == "cp:classes_selected"} { set classes_selected $value } elseif {$key == "cp:perms_selected"} { set perms_selected $value } else { set vals($key) $value } } # update the display _initializeWidgets set vals(cp:classes) [Apol_Class_Perms::getClasses] set enabled(cp:classes) 1 set enabled(cp:perms) 1 _toggle_perms_toshow -> -> reset # then verify that selected object classes and permissions exist # for this policy set unknowns {} set vals(cp:classes_selected) {} foreach class $classes_selected { if {[set i [lsearch $vals(cp:classes) $class]] >= 0} { $widgets(cp:classes) selection set $i lappend vals(cp:classes_selected) $class } else { lappend unknowns $class } } if {[llength $unknowns] > 0} { tk_messageBox -icon warning -type ok -title "Open Apol Query" \ -message "The following object classes do not exist in the currently loaded policy and were ignored:\n\n[join $unknowns ", "]" \ -parent . } _toggle_perms_toshow {} {} {} set unknowns {} set vals(cp:perms_selected) {} foreach perm $perms_selected { if {[set i [lsearch $vals(cp:perms) $perm]] >= 0} { $widgets(cp:perms) selection set $i lappend vals(cp:perms_selected) $perm } else { lappend unknowns $perm } } if {[llength $unknowns] > 0} { tk_messageBox -icon warning -type ok -title "Open Apol Query" \ -message "The following permissions do not exist in the currently loaded policy and were ignored:\n\n[join $unknowns ", "]" \ -parent $parentDlg } } #### private functions below #### proc Apol_TE::_initializeVars {} { variable vals array set vals [list \ rs:avrule_allow $::QPOL_RULE_ALLOW \ rs:avrule_neverallow 0 \ rs:avrule_auditallow $::QPOL_RULE_AUDITALLOW \ rs:avrule_dontaudit $::QPOL_RULE_DONTAUDIT \ rs:type_transition $::QPOL_RULE_TYPE_TRANS \ rs:type_member $::QPOL_RULE_TYPE_MEMBER \ rs:type_change $::QPOL_RULE_TYPE_CHANGE \ ta:source_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ ta:target_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ ta:default_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ ] array set vals { oo:enabled 0 oo:regexp 0 ta:use_source 0 ta:source_indirect 1 ta:source_which source ta:source_sym,attribs 0 ta:source_sym {} ta:use_target 0 ta:target_indirect 1 ta:target_sym,attribs 0 ta:target_sym {} ta:use_default 0 ta:default_sym,attribs 0 ta:default_sym {} cp:classes {} cp:classes_selected {} cp:perms {} cp:perms_selected {} cp:perms_toshow all cp:perms_matchall 0 } variable enabled array set enabled { ta:use_source 1 ta:use_target 1 ta:use_default 1 cp:classes 0 cp:perms 0 } } proc Apol_TE::_initializeTabs {} { variable widgets variable tabs array set tabs { next_result_id 1 } foreach p [$widgets(results) pages 0 end] { _delete_results $p } } proc Apol_TE::_initializeWidgets {} { variable widgets $widgets(search_opts) raise typeattrib $widgets(cp:classes) selection clear 0 end $widgets(cp:perms) selection clear 0 end } proc Apol_TE::_createTypesAttribsTab {} { variable vals variable widgets variable enabled set ta_tab [$widgets(search_opts) insert end typeattrib -text "Types/Attributes"] set fm_source [frame $ta_tab.source] set fm_target [frame $ta_tab.target] set fm_default [frame $ta_tab.default] grid $fm_source $fm_target $fm_default -padx 4 -sticky ewns foreach i {0 1 2} { grid columnconfigure $ta_tab $i -weight 1 -uniform 1 } grid rowconfigure $ta_tab 0 -weight 1 _create_ta_box source $fm_source "Source type/attribute" 1 1 1 _create_ta_box target $fm_target "Target type/attribute" 1 0 1 _create_ta_box default $fm_default "Default type" 0 0 0 $widgets(search_opts) raise typeattrib } proc Apol_TE::_create_ta_box {prefix f title has_indirect has_which has_attribs} { variable vals variable widgets set widgets(ta:use_${prefix}) [checkbutton $f.use -text $title \ -variable Apol_TE::vals(ta:use_${prefix})] pack $widgets(ta:use_${prefix}) -side top -anchor w trace add variable Apol_TE::vals(ta:use_${prefix}) write \ [list Apol_TE::_toggle_ta_box $prefix] set w {} if {$has_attribs} { set helptext "Type or select a type or attribute" } else { set helptext "Type or select a type" } set widgets(ta:${prefix}_sym) [ComboBox $f.sym \ -state disabled -entrybg $ApolTop::default_bg_color \ -textvariable Apol_TE::vals(ta:${prefix}_sym) \ -helptext $helptext -autopost 1] pack $widgets(ta:${prefix}_sym) -expand 0 -fill x -padx 8 lappend w $widgets(ta:${prefix}_sym) if {$has_attribs} { set ta_frame [frame $f.ta] pack $ta_frame -expand 0 -anchor center -pady 2 set types [checkbutton $ta_frame.types -text "Types" -state disabled \ -onvalue $::APOL_QUERY_SYMBOL_IS_TYPE -offvalue 0 \ -variable Apol_TE::vals(ta:${prefix}_sym,types)] set attribs [checkbutton $ta_frame.attribs -text "Attribs" -state disabled \ -onvalue $::APOL_QUERY_SYMBOL_IS_ATTRIBUTE -offvalue 0 \ -variable Apol_TE::vals(ta:${prefix}_sym,attribs)] $types configure -command [list Apol_TE::_toggle_ta_pushed $prefix $types] $attribs configure -command [list Apol_TE::_toggle_ta_pushed $prefix $attribs] trace add variable Apol_TE::vals(ta:${prefix}_sym,attribs) write \ [list Apol_TE::_toggle_ta_sym $prefix] pack $types $attribs -side left -padx 2 lappend w $types $attribs } if {$has_indirect} { set indirect [checkbutton $f.indirect -text "Only direct matches" \ -state disabled -variable Apol_TE::vals(ta:${prefix}_indirect) \ -onvalue 0 -offvalue 1] pack $indirect -anchor w -padx 8 lappend w $indirect } if {$has_which} { set which_fm [frame $f.which] set which_source [radiobutton $which_fm.source \ -text "As source" -state disabled \ -variable Apol_TE::vals(ta:${prefix}_which) \ -value source] set which_any [radiobutton $which_fm.any \ -text "Any" -state disabled \ -variable Apol_TE::vals(ta:${prefix}_which) \ -value either] trace add variable Apol_TE::vals(ta:${prefix}_which) write \ [list Apol_TE::_toggle_which] pack $which_source $which_any -side left -padx 2 pack $which_fm -anchor w -padx 6 lappend w $which_source $which_any } # update contents of the combobox whenever the 'Types' checkbutton # is enabled; for default type, this is invoked by a call to # reinitialize_default_search_options trace add variable Apol_TE::vals(ta:${prefix}_sym,types) write \ [list Apol_TE::_toggle_ta_sym $prefix] set widgets(ta:${prefix}_widgets) $w trace add variable Apol_TE::enabled(ta:use_${prefix}) write \ [list Apol_TE::_toggle_enable_ta ${prefix}] } proc Apol_TE::_toggle_rule_selection {name1 name2 op} { _maybe_enable_default_type _maybe_enable_perms } ## lots of obscure callbacks here to determine when to enable a ta box ## # called when there is a change in state to the top checkbutton within # a ta box proc Apol_TE::_toggle_ta_box {col name1 name2 op} { variable vals variable enabled if {$col == "source"} { _maybe_enable_target_type _maybe_enable_default_type } # force a refresh of this box's state; this invokes # _toggle_enable_ta callback set enabled(ta:use_${col}) $enabled(ta:use_${col}) } # disable target type/attrib and default type if source box is marked as "any" proc Apol_TE::_toggle_which {name1 name2 op} { _maybe_enable_target_type _maybe_enable_default_type } proc Apol_TE::_maybe_enable_target_type {} { variable vals variable enabled set any_set 0 if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_which) == "either"} { set any_set 1 } if {!$any_set} { set enabled(ta:use_target) 1 } else { set enabled(ta:use_target) 0 } } proc Apol_TE::_maybe_enable_default_type {} { variable vals variable enabled set typerule_set 0 set any_set 0 foreach x {type_transition type_member type_change} { if {$vals(rs:$x)} { set typerule_set 1 break } } if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_which) == "either"} { set any_set 1 } if {$typerule_set && !$any_set} { set enabled(ta:use_default) 1 } else { set enabled(ta:use_default) 0 } } # called whenever a ta box is enabled or disabled proc Apol_TE::_toggle_enable_ta {col name1 name2 op} { variable vals variable widgets variable enabled if {$enabled(ta:use_${col})} { $widgets(ta:use_${col}) configure -state normal } else { $widgets(ta:use_${col}) configure -state disabled } if {$enabled(ta:use_${col}) && $vals(ta:use_${col})} { foreach w $widgets(ta:${col}_widgets) { $w configure -state normal } $widgets(ta:${col}_sym) configure -entrybg white } else { foreach w $widgets(ta:${col}_widgets) { $w configure -state disabled } $widgets(ta:${col}_sym) configure -entrybg $ApolTop::default_bg_color } # update this tab's name if one of the columns is enabled and used if {($enabled(ta:use_source) && $vals(ta:use_source)) || \ ($enabled(ta:use_target) && $vals(ta:use_target)) || \ ($enabled(ta:use_default) && $vals(ta:use_default))} { $widgets(search_opts) itemconfigure typeattrib -text "Types/Attributes *" } else { $widgets(search_opts) itemconfigure typeattrib -text "Types/Attributes" } } proc Apol_TE::_toggle_ta_sym {col name1 name2 op} { variable vals variable widgets if {!$vals(ta:${col}_sym,types) && !$vals(ta:${col}_sym,attribs)} { # don't change combobox if both types and attribs are deselected return } if {$vals(ta:${col}_sym,types) && $vals(ta:${col}_sym,attribs)} { set items [lsort [concat [Apol_Types::getTypes] [Apol_Types::getAttributes]]] } elseif {$vals(ta:${col}_sym,types)} { set items [Apol_Types::getTypes] } else { set items [Apol_Types::getAttributes] } $widgets(ta:${col}_sym) configure -values $items } # disallow both types and attribs to be deselected within a ta box proc Apol_TE::_toggle_ta_pushed {col cb} { variable vals if {!$vals(ta:${col}_sym,types) && !$vals(ta:${col}_sym,attribs)} { $cb select } } # code to create and handle the classe/permissions subtab proc Apol_TE::_createClassesPermsTab {} { variable vals variable widgets variable enabled set objects_tab [$widgets(search_opts) insert end classperms -text "Classes/Permissions"] set fm_objs [TitleFrame $objects_tab.objs -text "Object Classes"] set fm_perms [TitleFrame $objects_tab.perms -text "AV Rule Permissions"] pack $fm_objs -side left -expand 0 -fill both -padx 2 -pady 2 pack $fm_perms -side left -expand 1 -fill both -padx 2 -pady 2 # object classes subframe set sw [ScrolledWindow [$fm_objs getframe].sw -auto both] set widgets(cp:classes) [listbox [$sw getframe].lb -height 5 -width 24 \ -highlightthickness 0 -selectmode multiple \ -exportselection 0 -state disabled \ -bg $ApolTop::default_bg_color \ -listvar Apol_TE::vals(cp:classes)] $sw setwidget $widgets(cp:classes) update grid propagate $sw 0 bind $widgets(cp:classes) <> \ [list Apol_TE::_toggle_cp_select classes] pack $sw -expand 1 -fill both set clear [button [$fm_objs getframe].b -text "Clear" -width 6 -state disabled \ -command [list Apol_TE::_clear_cp_listbox $widgets(cp:classes) classes]] pack $clear -expand 0 -pady 2 set widgets(cp:classes_widgets) [list $widgets(cp:classes) $clear] # permissions subframe set f [$fm_perms getframe] set sw [ScrolledWindow $f.sw -auto both] set widgets(cp:perms) [listbox [$sw getframe].lb -height 5 -width 24 \ -highlightthickness 0 -selectmode multiple \ -exportselection 0 -bg white \ -listvar Apol_TE::vals(cp:perms)] $sw setwidget $widgets(cp:perms) update grid propagate $sw 0 bind $widgets(cp:perms) <> \ [list Apol_TE::_toggle_cp_select perms] set clear [button $f.clear -text "Clear" \ -command [list Apol_TE::_clear_cp_listbox $widgets(cp:perms) perms]] set reverse [button $f.reverse -text "Reverse" \ -command [list Apol_TE::_reverse_cp_listbox $widgets(cp:perms)]] set perm_opts_f [frame $f.perms] set perm_rb_f [frame $perm_opts_f.rb] set l [label $perm_rb_f.l -text "Permissions to show:" -state disabled] set all [radiobutton $perm_rb_f.all -text "All" \ -variable Apol_TE::vals(cp:perms_toshow) -value all] set union [radiobutton $perm_rb_f.union -text "All for selected classes" \ -variable Apol_TE::vals(cp:perms_toshow) -value union] set intersect [radiobutton $perm_rb_f.inter -text "Common to selected classes" \ -variable Apol_TE::vals(cp:perms_toshow) -value intersect] trace add variable Apol_TE::vals(cp:perms_toshow) write \ Apol_TE::_toggle_perms_toshow pack $l $all $union $intersect -anchor w set all_perms [checkbutton $perm_opts_f.all -text "AV rule must have all selected permissions" \ -variable Apol_TE::vals(cp:perms_matchall)] pack $perm_rb_f $all_perms -anchor w -pady 4 -padx 4 grid $sw - $perm_opts_f -sticky nsw grid $clear $reverse ^ -pady 2 -sticky ew grid columnconfigure $f 0 -weight 0 -uniform 1 -pad 2 grid columnconfigure $f 1 -weight 0 -uniform 1 -pad 2 grid columnconfigure $f 2 -weight 1 grid rowconfigure $f 0 -weight 1 set widgets(cp:perms_widgets) \ [list $widgets(cp:perms) $clear $reverse $l $all $union $intersect $all_perms] trace add variable Apol_TE::vals(cp:classes_selected) write \ [list Apol_TE::_update_cp_tabname] trace add variable Apol_TE::vals(cp:perms_selected) write \ [list Apol_TE::_update_cp_tabname] trace add variable Apol_TE::enabled(cp:classes) write \ [list Apol_TE::_toggle_enable_cp classes] trace add variable Apol_TE::enabled(cp:perms) write \ [list Apol_TE::_toggle_enable_cp perms] } proc Apol_TE::_toggle_enable_cp {prefix name1 name2 op} { variable vals variable widgets variable enabled if {$enabled(cp:${prefix})} { foreach w $widgets(cp:${prefix}_widgets) { $w configure -state normal } $widgets(cp:${prefix}) configure -bg white } else { foreach w $widgets(cp:${prefix}_widgets) { $w configure -state disabled } $widgets(cp:${prefix}) configure -bg $ApolTop::default_bg_color } # force a refresh of this tab's name set vals(cp:${prefix}_selected) $vals(cp:${prefix}_selected) } proc Apol_TE::_maybe_enable_perms {} { variable vals variable enabled set avrule_set 0 foreach x {avrule_allow avrule_neverallow avrule_auditallow avrule_dontaudit} { if {$vals(rs:$x)} { set avrule_set 1 break } } if {$avrule_set} { set enabled(cp:perms) 1 } else { set enabled(cp:perms) 0 } } proc Apol_TE::_toggle_perms_toshow {name1 name2 op} { variable vals variable widgets if {$vals(cp:perms_toshow) == "all"} { # don't change the list of permissions if there was a new # object class selection and the current radiobutton is all if {$op != "update"} { set vals(cp:perms) $Apol_Class_Perms::perms_list set vals(cp:perms_selected) {} } } elseif {$vals(cp:perms_toshow) == "union"} { set vals(cp:perms) {} set vals(cp:perms_selected) {} foreach class $vals(cp:classes_selected) { set vals(cp:perms) [lsort -unique -dictionary [concat $vals(cp:perms) [Apol_Class_Perms::getPermsForClass $class]]] } } else { ;# intersection set vals(cp:perms) {} set vals(cp:perms_selected) {} set classes {} foreach i [$widgets(cp:classes) curselection] { lappend classes [$widgets(cp:classes) get $i] } if {$classes == {}} { return } set vals(cp:perms) [Apol_Class_Perms::getPermsForClass [lindex $classes 0]] foreach class [lrange $classes 1 end] { set this_perms [Apol_Class_Perms::getPermsForClass $class] set new_perms {} foreach p $vals(cp:perms) { if {[lsearch -exact $this_perms $p] >= 0} { lappend new_perms $p } } set vals(cp:perms) $new_perms } } } # called whenever an item with a class/perm listbox is # selected/deselected proc Apol_TE::_toggle_cp_select {col} { variable vals variable widgets set items {} foreach i [$widgets(cp:${col}) curselection] { lappend items [$widgets(cp:${col}) get $i] } set vals(cp:${col}_selected) $items if {$col == "classes"} { _toggle_perms_toshow {} {} update } } proc Apol_TE::_clear_cp_listbox {lb prefix} { variable vals $lb selection clear 0 end set vals(cp:${prefix}_selected) {} if {$prefix == "classes"} { _toggle_perms_toshow {} {} update } } proc Apol_TE::_reverse_cp_listbox {lb} { variable vals set old_selection [$lb curselection] set items {} for {set i 0} {$i < [$lb index end]} {incr i} { if {[lsearch $old_selection $i] >= 0} { $lb selection clear $i } else { $lb selection set $i lappend items [$lb get $i] } } set vals(cp:perms_selected) $items } proc Apol_TE::_update_cp_tabname {name1 name2 op} { variable vals variable widgets variable enabled if {($enabled(cp:classes) && $vals(cp:classes_selected) > 0) || \ ($enabled(cp:perms) && $vals(cp:perms_selected) > 0)} { $widgets(search_opts) itemconfigure classperms -text "Classes/Permissions *" } else { $widgets(search_opts) itemconfigure classperms -text "Classes/Permissions" } } proc Apol_TE::_delete_results {pageID} { variable widgets variable tabs # Remove tab and its widgets set curpos [$widgets(results) index $pageID] $widgets(results) delete $pageID array unset tabs $pageID:* array unset tabs $pageID # try to raise the next tab if {[set next_id [$widgets(results) pages $curpos]] != {}} { _switch_to_tab $next_id } elseif {$curpos > 0} { # raise the previous page instead _switch_to_tab [$widgets(results) pages [expr {$curpos - 1}]] } else { # no tabs remaining $widgets(update) configure -state disabled } } proc Apol_TE::_display_rename_tab_dialog {pageID} { variable widgets variable tabs set d [Dialog .apol_te_tab_rename -homogeneous 1 -spacing 2 -cancel 1 \ -default 0 -modal local -parent . -place center -separator 1 \ -side bottom -title "Rename Results Tab"] $d add -text "OK" -command [list $d enddialog "ok"] $d add -text "Cancel" -command [list $d enddialog "cancel"] set f [$d getframe] set l [label $f.l -text "Tab name:"] set tabs(tab:new_name) [$widgets(results) itemcget $pageID -text] set e [entry $f.e -textvariable Apol_TE::tabs(tab:new_name) -width 16 -bg white] pack $l $e -side left -padx 2 set retval [$d draw] destroy $d if {$retval == "ok"} { $widgets(results) itemconfigure $pageID -text $tabs(tab:new_name) } } proc Apol_TE::_delete_current_results {} { variable widgets if {[set curid [$widgets(results) raise]] != {}} { _delete_results $curid } } proc Apol_TE::_create_new_results_tab {} { variable vals variable widgets variable tabs set i $tabs(next_result_id) incr tabs(next_result_id) set id "results$i" set frame [$widgets(results) insert end "$id" -text "Results $i"] $widgets(results) raise $id set tabs($id) [Apol_Widget::makeSearchResults $frame.results] pack $tabs($id) -expand 1 -fill both set tabs($id:vals) [array get vals] return $tabs($id) } proc Apol_TE::_switch_to_tab {pageID} { variable vals variable widgets variable tabs # check if switching to already visible tab if {[$Apol_TE::widgets(results) raise] == $pageID} { return } $widgets(results) raise $pageID set cur_search_opts [$widgets(search_opts) raise] # restore the tab's search criteria array set tmp_vals $tabs($pageID:vals) set classes_selected $tmp_vals(cp:classes_selected) set perms_selected $tmp_vals(cp:perms_selected) array set vals $tabs($pageID:vals) _initializeWidgets set vals(cp:classes_selected) $classes_selected set vals(cp:perms_selected) $perms_selected foreach c $classes_selected { $widgets(cp:classes) selection set [lsearch $vals(cp:classes) $c] } foreach p $perms_selected { $widgets(cp:perms) selection set [lsearch $vals(cp:perms) $p] } $widgets(search_opts) raise $cur_search_opts } ######################################################################## proc Apol_TE::_reset {} { variable enabled set old_classes_enabled $enabled(cp:classes) _initializeVars _initializeWidgets if {[set enabled(cp:classes) $old_classes_enabled]} { variable vals set vals(cp:classes) [Apol_Class_Perms::getClasses] set enabled(cp:classes) 1 set enabled(cp:perms) 1 } } proc Apol_TE::_search_terules {whichButton} { variable vals variable widgets variable enabled variable tabs if {![ApolTop::is_policy_open]} { tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No current policy file is opened." return } # check search options if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_sym) == {}} { tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No source type/attribute was selected." return } if {$enabled(ta:use_target) && $vals(ta:use_target) && $vals(ta:target_sym) == {}} { tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No target type/attribute was selected." return } if {$enabled(ta:use_default) && $vals(ta:use_default) && $vals(ta:default_sym) == {}} { tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No default type selected." return } set avrule_selection 0 foreach {key value} [array get vals rs:avrule_*] { set avrule_selection [expr {$avrule_selection | $value}] } set terule_selection 0 foreach {key value} [array get vals rs:type_*] { set terule_selection [expr {$terule_selection | $value}] } if {$avrule_selection == 0 && $terule_selection == 0} { tk_messageBox -icon error -type ok -title "TE Rule Search" -message "At least one rule must be selected." return } # start building queries set avq [new_apol_avrule_query_t] set teq [new_apol_terule_query_t] if {$enabled(ta:use_source) && $vals(ta:use_source)} { if {$vals(ta:source_which) == "either"} { $avq set_source_any $::ApolTop::policy 1 } $avq set_source $::ApolTop::policy $vals(ta:source_sym) $vals(ta:source_indirect) $avq set_source_component $::ApolTop::policy [expr {$vals(ta:source_sym,types) | $vals(ta:source_sym,attribs)}] $teq set_source $::ApolTop::policy $vals(ta:source_sym) $vals(ta:source_indirect) $teq set_source_component $::ApolTop::policy [expr {$vals(ta:source_sym,types) | $vals(ta:source_sym,attribs)}] } if {$enabled(ta:use_target) && $vals(ta:use_target)} { $avq set_target $::ApolTop::policy $vals(ta:target_sym) $vals(ta:target_indirect) $avq set_target_component $::ApolTop::policy [expr {$vals(ta:target_sym,types) | $vals(ta:target_sym,attribs)}] $teq set_target $::ApolTop::policy $vals(ta:target_sym) $vals(ta:target_indirect) $teq set_target_component $::ApolTop::policy [expr {$vals(ta:target_sym,types) | $vals(ta:target_sym,attribs)}] } if {$enabled(ta:use_default) && $vals(ta:use_default)} { $teq set_default $::ApolTop::policy $vals(ta:default_sym) } if {$enabled(cp:classes)} { foreach c $vals(cp:classes_selected) { $avq append_class $::ApolTop::policy $c $teq append_class $::ApolTop::policy $c } } if {$enabled(cp:perms)} { foreach p $vals(cp:perms_selected) { $avq append_perm $::ApolTop::policy $p } $avq set_all_perms $::ApolTop::policy $vals(cp:perms_matchall) } $avq set_rules $::ApolTop::policy $avrule_selection $teq set_rules $::ApolTop::policy $terule_selection $avq set_enabled $::ApolTop::policy $vals(oo:enabled) $teq set_enabled $::ApolTop::policy $vals(oo:enabled) $avq set_regex $::ApolTop::policy $vals(oo:regexp) $teq set_regex $::ApolTop::policy $vals(oo:regexp) foreach x {new update reset} { $widgets($x) configure -state disabled } if {$vals(rs:avrule_neverallow)} { ApolTop::loadNeverAllows } if {![ApolTop::is_capable "neverallow"]} { set avrule_selection [expr {$avrule_selection & (~$::QPOL_RULE_NEVERALLOW)}] $avq set_rules $::ApolTop::policy $avrule_selection } Apol_Progress_Dialog::wait "TE Rules" "Searching rules" \ { set numTEs {0 0 0} set numAVs {0 0 0} set avresults NULL set teresults NULL set num_avresults 0 set num_teresults 0 if {![ApolTop::is_capable "syntactic rules"]} { if {$avrule_selection != 0} { set avresults [$avq run $::ApolTop::policy] } if {$terule_selection != 0} { set teresults [$teq run $::ApolTop::policy] } } else { $::ApolTop::qpolicy build_syn_rule_table if {$avrule_selection != 0} { set avresults [$avq run_syn $::ApolTop::policy] } if {$terule_selection != 0} { set teresults [$teq run_syn $::ApolTop::policy] } } $avq -acquire $avq -delete $teq -acquire $teq -delete if {$avresults != "NULL"} { set num_avresults [$avresults get_size] } if {$teresults != "NULL"} { set num_teresults [$teresults get_size] } if {$whichButton == "new"} { set sr [_create_new_results_tab] } else { set id [$widgets(results) raise] set tabs($id:vals) [array get vals] set sr $tabs($id) Apol_Widget::clearSearchResults $sr } if {![ApolTop::is_capable "syntactic rules"]} { apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_avresults AV rule results" apol_tcl_terule_sort $::ApolTop::policy $teresults if {$num_avresults > 0} { set numAVs [Apol_Widget::appendSearchResultRules $sr 0 $avresults qpol_avrule_from_void] } apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_teresults TE rule results" apol_tcl_avrule_sort $::ApolTop::policy $avresults if {$num_teresults > 0} { set numTEs [Apol_Widget::appendSearchResultRules $sr 0 $teresults qpol_terule_from_void] } } else { apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_avresults AV rule results" if {$num_avresults > 0} { set numAVs [Apol_Widget::appendSearchResultSynRules $sr 0 $avresults qpol_syn_avrule_from_void] } apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_teresults TE rule results" if {$num_teresults > 0} { set numTEs [Apol_Widget::appendSearchResultSynRules $sr 0 $teresults qpol_syn_terule_from_void] } } set num_rules [expr {[lindex $numAVs 0] + [lindex $numTEs 0]}] set num_enabled [expr {[lindex $numAVs 1] + [lindex $numTEs 1]}] set num_disabled [expr {[lindex $numAVs 2] + [lindex $numTEs 2]}] set header "$num_rules rule" if {$num_rules != 1} { append header s } append header " match the search criteria.\n" append header "Number of enabled conditional rules: $num_enabled\n" append header "Number of disabled conditional rules: $num_disabled\n" Apol_Widget::appendSearchResultHeader $sr $header } $widgets(new) configure -state normal $widgets(reset) configure -state normal if {[$widgets(results) pages] != {} || $retval == 0} { $widgets(update) configure -state normal } }