diff options
Diffstat (limited to 'apol/classes_perms_tab.tcl')
-rw-r--r-- | apol/classes_perms_tab.tcl | 484 |
1 files changed, 484 insertions, 0 deletions
diff --git a/apol/classes_perms_tab.tcl b/apol/classes_perms_tab.tcl new file mode 100644 index 0000000..ab9c4d7 --- /dev/null +++ b/apol/classes_perms_tab.tcl @@ -0,0 +1,484 @@ +# 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_Class_Perms { + variable class_list {} + variable common_list {} + variable perms_list {} + variable opts + variable widgets +} + +proc Apol_Class_Perms::create {tab_name nb} { + variable opts + variable widgets + + _initializeVars + + set frame [$nb insert end $tab_name -text "Classes/Perms"] + + set pw1 [PanedWindow $frame.pw -side top] + set left_pane [$pw1 add -weight 0] + set center_pane [$pw1 add -weight 1] + set class_pane [frame $left_pane.class] + set common_pane [frame $left_pane.common] + set perms_pane [frame $left_pane.perms] + + set classes_box [TitleFrame $class_pane.tbox -text "Object Classes"] + set common_box [TitleFrame $common_pane.tbox -text "Common Permissions"] + set perms_box [TitleFrame $perms_pane.tbox -text "Permissions"] + set options_box [TitleFrame $center_pane.obox -text "Search Options"] + set results_box [TitleFrame $center_pane.rbox -text "Search Results"] + pack $classes_box -fill both -expand yes + pack $common_box -fill both -expand yes + pack $perms_box -fill both -expand yes + pack $options_box -padx 2 -fill both -expand 0 + pack $results_box -padx 2 -fill both -expand yes + pack $pw1 -fill both -expand yes + pack $class_pane $common_pane -expand 0 -fill both + pack $perms_pane -expand 1 -fill both + + # Object Classes listbox + set class_listbox [Apol_Widget::makeScrolledListbox [$classes_box getframe].lb -height 8 -width 20 -listvar Apol_Class_Perms::class_list] + Apol_Widget::setListboxCallbacks $class_listbox \ + {{"Display Object Class Info" {Apol_Class_Perms::_popupInfo class}}} + pack $class_listbox -fill both -expand yes + + # Common Permissions listbox + set common_listbox [Apol_Widget::makeScrolledListbox [$common_box getframe].lb -height 5 -width 20 -listvar Apol_Class_Perms::common_perms_list] + Apol_Widget::setListboxCallbacks $common_listbox \ + {{"Display Common Permission Class Info" {Apol_Class_Perms::_popupInfo common}}} + pack $common_listbox -fill both -expand yes + + # Permissions listbox + set perms_listbox [Apol_Widget::makeScrolledListbox [$perms_box getframe].lb -height 10 -width 20 -listvar Apol_Class_Perms::perms_list] + Apol_Widget::setListboxCallbacks $perms_listbox \ + {{"Display Permission Info" {Apol_Class_Perms::_popupInfo perm}}} + pack $perms_listbox -fill both -expand yes + + # Search options section + set ofm [$options_box getframe] + set classesfm [frame $ofm.classes] + set commonsfm [frame $ofm.commons] + set permsfm [frame $ofm.perms] + pack $classesfm $commonsfm $permsfm -side left -padx 4 -pady 2 -anchor ne + + # First set of checkbuttons + set classes [checkbutton $classesfm.classes -text "Object classes" \ + -variable Apol_Class_Perms::opts(classes:show)] + set perms [checkbutton $classesfm.perms -text "Include perms" \ + -variable Apol_Class_Perms::opts(classes:perms)] + set commons [checkbutton $classesfm.commons -text "Expand common perms" \ + -variable Apol_Class_Perms::opts(classes:commons)] + trace add variable Apol_Class_Perms::opts(classes:show) write \ + [list Apol_Class_Perms::_toggleCheckbuttons $perms $commons] + trace add variable Apol_Class_Perms::opts(classes:perms) write \ + [list Apol_Class_Perms::_toggleCheckbuttons $commons {}] + pack $classes -anchor w + pack $perms $commons -anchor w -padx 8 + + # Second set of checkbuttons + set commons [checkbutton $commonsfm.commons -text "Common permissions" \ + -variable Apol_Class_Perms::opts(commons:show)] + set perms [checkbutton $commonsfm.perms2 -text "Include perms" \ + -variable Apol_Class_Perms::opts(commons:perms) \ + -state disabled] + set classes [checkbutton $commonsfm.classes -text "Object classes" \ + -variable Apol_Class_Perms::opts(commons:classes) \ + -state disabled] + trace add variable Apol_Class_Perms::opts(commons:show) write \ + [list Apol_Class_Perms::_toggleCheckbuttons $perms $classes] + pack $commons -anchor w + pack $perms $classes -anchor w -padx 8 + + # Third set of checkbuttons + set perms [checkbutton $permsfm.prems -text "Permissions" \ + -variable Apol_Class_Perms::opts(perms:show)] + set classes [checkbutton $permsfm.classes -text "Object classes" \ + -variable Apol_Class_Perms::opts(perms:classes) \ + -state disabled] + set commons [checkbutton $permsfm.commons -text "Common perms" \ + -variable Apol_Class_Perms::opts(perms:commons) \ + -state disabled] + trace add variable Apol_Class_Perms::opts(perms:show) write \ + [list Apol_Class_Perms::_toggleCheckbuttons $classes $commons] + pack $perms -anchor w + pack $classes $commons -anchor w -padx 8 + + set widgets(regexp) [Apol_Widget::makeRegexpEntry $ofm.regexp] + + pack $widgets(regexp) -side left -padx 2 -pady 2 -anchor ne + + set ok [button $ofm.ok -text OK -width 6 \ + -command Apol_Class_Perms::_search] + pack $ok -side right -pady 5 -padx 5 -anchor ne + + set widgets(results) [Apol_Widget::makeSearchResults [$results_box getframe].results] + pack $widgets(results) -expand yes -fill both + + return $frame +} + +proc Apol_Class_Perms::open {ppath} { + set q [new_apol_class_query_t] + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + variable class_list [lsort [class_vector_to_list $v]] + $v -acquire + $v -delete + + set q [new_apol_common_query_t] + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + variable common_perms_list [lsort [common_vector_to_list $v]] + $v -acquire + $v -delete + + set q [new_apol_perm_query_t] + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + variable perms_list [lsort [str_vector_to_list $v]] + $v -acquire + $v -delete +} + +proc Apol_Class_Perms::close {} { + variable class_list {} + variable common_perms_list {} + variable perms_list {} + variable widgets + + _initializeVars + Apol_Widget::clearSearchResults $widgets(results) +} + +proc Apol_Class_Perms::getTextWidget {} { + variable widgets + return $widgets(results).tb +} + +proc Apol_Class_Perms::getClasses {} { + variable class_list + set class_list +} + +# Return a sorted list of all permissions assigned to a class. If the +# class has a common, include the common's permissions as well. +proc Apol_Class_Perms::getPermsForClass {class_name} { + set qpol_class_datum [new_qpol_class_t $::ApolTop::qpolicy $class_name] + set i [$qpol_class_datum get_perm_iter $::ApolTop::qpolicy] + set perms [iter_to_str_list $i] + $i -acquire + $i -delete + if {[set qpol_common_datum [$qpol_class_datum get_common $::ApolTop::qpolicy]] != "NULL"} { + set i [$qpol_common_datum get_perm_iter $::ApolTop::qpolicy] + set perms [concat $perms [iter_to_str_list $i]] + $i -acquire + $i -delete + } + lsort -dictionary -unique $perms +} + +# Given a permission name, return a 2-ple of lists. The first list +# will contain all classes that directly declare the permission. The +# second list is a list of classes that inherited from a common that +# declared the permission. Both lists will be sorted and uniquified +# when returned. +proc Apol_Class_Perms::getClassesForPerm {perm_name} { + set classes_list {} + set i [$::ApolTop::qpolicy get_class_iter $perm_name] + while {![$i end]} { + set qpol_class_datum [qpol_class_from_void [$i get_item]] + lappend classes_list [$qpol_class_datum get_name $::ApolTop::qpolicy] + $i next + } + $i -acquire + $i -delete + set indirect_classes_list {} + set i [$::ApolTop::qpolicy get_common_iter $perm_name] + while {![$i end]} { + set qpol_common_datum [qpol_common_from_void [$i get_item]] + set q [new_apol_class_query_t] + $q set_common $::ApolTop::policy [$qpol_common_datum get_name $::ApolTop::qpolicy] + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + set indirect_classes_list [concat $indirect_classes_list [class_vector_to_list $v]] + $v -acquire + $v -delete + $i next + } + $i -acquire + $i -delete + list [lsort $classes_list] [lsort -unique $indirect_classes_list] +} + +#### private functions below #### + +proc Apol_Class_Perms::_initializeVars {} { + variable opts + array set opts { + classes:show 1 classes:perms 1 classes:commons 1 + commons:show 0 commons:perms 1 commons:classes 1 + perms:show 0 perms:classes 1 perms:commons 1 + } +} + +proc Apol_Class_Perms::_popupInfo {which name} { + if {$which == "class"} { + set text [_renderClass $name 1 0] + } elseif {$which == "common"} { + set text [_renderCommon $name 1 0] + } else { + set text [_renderPerm $name 1 1] + } + Apol_Widget::showPopupText $name $text +} + +proc Apol_Class_Perms::_toggleCheckbuttons {cb1 cb2 name1 name2 op} { + variable opts + variable widgets + if {$opts($name2)} { + $cb1 configure -state normal + if {$name2 == "classes:show"} { + if {$opts(classes:perms)} { + $cb2 configure -state normal + } else { + $cb2 configure -state disabled + } + } elseif {$cb2 != {}} { + $cb2 configure -state normal + } + } else { + $cb1 configure -state disabled + if {$cb2 != {}} { + $cb2 configure -state disabled + } + } + if {!$opts(classes:show) && !$opts(commons:show) && !$opts(perms:show)} { + Apol_Widget::setRegexpEntryState $widgets(regexp) 0 + } else { + Apol_Widget::setRegexpEntryState $widgets(regexp) 1 + } +} + +proc Apol_Class_Perms::_search {} { + variable opts + variable widgets + + Apol_Widget::clearSearchResults $widgets(results) + if {![ApolTop::is_policy_open]} { + tk_messageBox -icon error -type ok -title "Error" -message "No current policy file is opened." + return + } + if {!$opts(classes:show) && !$opts(commons:show) && !$opts(perms:show)} { + tk_messageBox -icon error -type ok -title "Error" -message "No search options provided." + return + } + set use_regexp [Apol_Widget::getRegexpEntryState $widgets(regexp)] + set regexp [Apol_Widget::getRegexpEntryValue $widgets(regexp)] + if {$use_regexp} { + if {$regexp == {}} { + tk_messageBox -icon error -type ok -title "Error" -message "No regular expression provided." + return + } + } else { + set regexp {} + } + + set results {} + + if {$opts(classes:show)} { + if {[set classes_perms $opts(classes:perms)]} { + set classes_commons $opts(classes:commons) + } else { + set classes_commons 0 + } + set q [new_apol_class_query_t] + $q set_class $::ApolTop::policy $regexp + $q set_regex $::ApolTop::policy $use_regexp + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + set classes_data [class_vector_to_list $v] + $v -acquire + $v -delete + append results "OBJECT CLASSES:\n" + if {$classes_data == {}} { + append results "Search returned no results.\n" + } else { + foreach c [lsort -index 0 $classes_data] { + append results [_renderClass $c $opts(classes:perms) $classes_commons] + } + } + } + + if {$opts(commons:show)} { + set q [new_apol_common_query_t] + $q set_common $::ApolTop::policy $regexp + $q set_regex $::ApolTop::policy $use_regexp + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + set commons_data [common_vector_to_list $v] + $v -acquire + $v -delete + append results "\nCOMMON PERMISSIONS: \n" + if {$commons_data == {}} { + append results "Search returned no results.\n" + } else { + foreach c [lsort -index 0 $commons_data] { + append results [_renderCommon $c $opts(commons:perms) $opts(commons:classes)] + } + } + } + + if {$opts(perms:show)} { + set q [new_apol_perm_query_t] + $q set_perm $::ApolTop::policy $regexp + $q set_regex $::ApolTop::policy $use_regexp + set v [$q run $::ApolTop::policy] + $q -acquire + $q -delete + set perms_data [str_vector_to_list $v] + $v -acquire + $v -delete + append results "\nPERMISSIONS" + if {$opts(perms:classes)} { + append results " (* means class uses permission via a common permission)" + } + append results ":\n" + if {$perms_data == {}} { + append results "Search returned no results.\n" + } else { + foreach p [lsort -index 0 $perms_data] { + append results [_renderPerm $p $opts(perms:classes) $opts(perms:commons)] + } + } + } + Apol_Widget::appendSearchResultText $widgets(results) [string trim $results] +} + +proc Apol_Class_Perms::_renderClass {class_name show_perms expand_common} { + set qpol_class_datum [new_qpol_class_t $::ApolTop::qpolicy $class_name] + if {[set qpol_common_datum [$qpol_class_datum get_common $::ApolTop::qpolicy]] == "NULL"} { + set common_name {} + } else { + set common_name [$qpol_common_datum get_name $::ApolTop::qpolicy] + } + set text "$class_name\n" + if {$show_perms} { + set i [$qpol_class_datum get_perm_iter $::ApolTop::qpolicy] + set perms_list [iter_to_str_list $i] + $i -acquire + $i -delete + foreach perm [lsort $perms_list] { + append text " $perm\n" + } + if {$common_name != {}} { + append text " $common_name (common perm)\n" + if {$expand_common} { + set i [$qpol_common_datum get_perm_iter $::ApolTop::qpolicy] + foreach perm [lsort [iter_to_str_list $i]] { + append text " $perm\n" + } + $i -acquire + $i -delete + } + } + append text \n + } + return $text +} + +proc Apol_Class_Perms::_renderCommon {common_name show_perms show_classes} { + set qpol_common_datum [new_qpol_common_t $::ApolTop::qpolicy $common_name] + set text "$common_name\n" + if {$show_perms} { + set i [$qpol_common_datum get_perm_iter $::ApolTop::qpolicy] + foreach perm [lsort [iter_to_str_list $i]] { + append text " $perm\n" + } + $i -acquire + $i -delete + } + if {$show_classes} { + append text " Object classes that use this common permission:\n" + set i [$::ApolTop::qpolicy get_class_iter] + set classes_list {} + while {![$i end]} { + set qpol_class_t [qpol_class_from_void [$i get_item]] + set q [$qpol_class_t get_common $::ApolTop::qpolicy] + if {$q != "NULL" && [$q get_name $::ApolTop::qpolicy] == $common_name} { + lappend classes_list [$qpol_class_t get_name $::ApolTop::qpolicy] + } + $i next + } + $i -acquire + $i -delete + foreach class [lsort $classes_list] { + append text " $class\n" + } + } + if {$show_perms || $show_classes} { + append text "\n" + } + return $text +} + +proc Apol_Class_Perms::_renderPerm {perm_name show_classes show_commons} { + set text "$perm_name\n" + if {$show_classes} { + append text " object classes:\n" + foreach {classes_list indirect_classes_list} [getClassesForPerm $perm_name] {break} + foreach c $indirect_classes_list { + lappend classes_list ${c}* + } + if {$classes_list == {}} { + append text " <none>\n" + } else { + foreach class [lsort -uniq $classes_list] { + append text " $class\n" + } + } + } + if {$show_commons} { + append text " common permissions:\n" + set commons_list {} + set i [$::ApolTop::qpolicy get_common_iter $perm_name] + while {![$i end]} { + set qpol_common_datum [qpol_common_from_void [$i get_item]] + lappend commons_list [$qpol_common_datum get_name $::ApolTop::qpolicy] + $i next + } + $i -acquire + $i -delete + + if {$commons_list == {}} { + append text " <none>\n" + } else { + foreach common [lsort $commons_list] { + append text " $common\n" + } + } + } + if {$show_classes || $show_commons} { + append text "\n" + } + return $text +} |