summaryrefslogtreecommitdiffstats
path: root/apol/context_dialog.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'apol/context_dialog.tcl')
-rw-r--r--apol/context_dialog.tcl340
1 files changed, 340 insertions, 0 deletions
diff --git a/apol/context_dialog.tcl b/apol/context_dialog.tcl
new file mode 100644
index 0000000..2bc63bc
--- /dev/null
+++ b/apol/context_dialog.tcl
@@ -0,0 +1,340 @@
+# Copyright (C) 2005-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_Context_Dialog {
+ variable dialog ""
+ variable vars
+}
+
+# Create a dialog box to allow the user to select a single context
+# (user + role + type + level [if MLS]). This will return a 2-ple
+# list. The first is an apol_context_t; the caller must delete this
+# afterwards. Note that the context may be partially filled. The
+# second element is the attribute used to filter types; it may be an
+# empty string to indicate no filtering. If the dialog is cancelled
+# then return an empty list.
+proc Apol_Context_Dialog::getContext {{defaultContext {}} {defaultAttribute {}} {parent .}} {
+ variable dialog
+ variable vars
+
+ if {![winfo exists $dialog]} {
+ _create_dialog $parent
+ }
+
+ set user {}
+ set role {}
+ set type {}
+ set low_level {}
+ set high_level {}
+
+ # initialize widget states
+ array set vars [list $dialog:low_enable 0 $dialog:high_enable 0]
+ if {$defaultContext != {}} {
+ set user [$defaultContext get_user] #line causing segfault. most likely the entire $defaultContext doesn't exist
+ set role [$defaultContext get_role]
+ set type [$defaultContext get_type]
+ if {$defaultAttribute != {}} {
+ lappend type $defaultAttribute
+ }
+ set range [$defaultContext get_range]
+ if {$range != "NULL"} {
+ set low_level [$range get_low]
+ set high_level [$range get_high]
+ }
+ }
+
+ $vars($dialog:user_box) configure -values [Apol_Users::getUsers]
+ set vars($dialog:user) $user
+ if {$user == {}} {
+ set vars($dialog:user_enable) 0
+ } else {
+ set vars($dialog:user_enable) 1
+ }
+
+
+
+ $vars($dialog:role_box) configure -values [Apol_Roles::getRoles]
+ set vars($dialog:role) $role
+ if {$role == {}} {
+ set vars($dialog:role_enable) 0
+ } else {
+ set vars($dialog:role_enable) 1
+ }
+
+ Apol_Widget::resetTypeComboboxToPolicy $vars($dialog:type_box)
+ Apol_Widget::setTypeComboboxValue $vars($dialog:type_box) $type
+ if {$type == {}} {
+ set vars($dialog:type_enable) 0
+ } else {
+ set vars($dialog:type_enable) 1
+ }
+
+ Apol_Widget::resetLevelSelectorToPolicy $vars($dialog:low_level)
+ Apol_Widget::resetLevelSelectorToPolicy $vars($dialog:high_level)
+ if {[ApolTop::is_policy_open] && [ApolTop::is_capable "mls"]} {
+ if {$low_level != {}} {
+ set vars($dialog:low_enable) 1
+ Apol_Widget::setLevelSelectorLevel $vars($dialog:low_level) $low_level
+ }
+ if {$high_level != {} && $high_level != "NULL"} {
+ set vars($dialog:low_enable) 1
+ set vars($dialog:high_enable) 1
+ Apol_Widget::setLevelSelectorLevel $vars($dialog:high_level) $high_level
+ }
+ $vars($dialog:low_cb) configure -state normal
+ } else {
+ set vars($dialog:low_enable) 0
+ set vars($dialog:high_enable) 0
+ $vars($dialog:low_cb) configure -state disabled
+ }
+
+ # force a recomputation of button sizes (bug in ButtonBox)
+ $dialog.bbox _redraw
+ set retval [$dialog draw]
+ if {$retval == -1 || $retval == 1} {
+ return {}
+ }
+ set context [_get_context $dialog]
+ set attribute [lindex [Apol_Widget::getTypeComboboxValueAndAttrib $vars($dialog:type_box)] 1]
+ list $context $attribute
+}
+
+
+########## private functions below ##########
+
+proc Apol_Context_Dialog::_create_dialog {parent} {
+ variable dialog
+ variable vars
+
+ set dialog [Dialog .context_dialog -modal local -parent $parent \
+ -separator 1 -homogeneous 1 -title "Select Context"]
+ array unset vars $dialog:*
+
+
+ set f [$dialog getframe]
+ set left_f [frame $f.left]
+
+ set user_f [frame $left_f.user]
+ set vars($dialog:user_cb) [checkbutton $user_f.enable -text "User" \
+ -variable Apol_Context_Dialog::vars($dialog:user_enable)]
+ set vars($dialog:user_box) [ComboBox $user_f.user -entrybg white \
+ -width 12 \
+ -textvariable Apol_Context_Dialog::vars($dialog:user) \
+ -autopost 1]
+ trace add variable Apol_Context_Dialog::vars($dialog:user_enable) write \
+ [list Apol_Context_Dialog::_user_changed $dialog]
+ pack $vars($dialog:user_cb) -anchor nw
+ pack $vars($dialog:user_box) -anchor nw -padx 4 -expand 0 -fill x
+
+ set role_f [frame $left_f.role]
+ set vars($dialog:role_cb) [checkbutton $role_f.enable -text "Role" \
+ -variable Apol_Context_Dialog::vars($dialog:role_enable)]
+ set vars($dialog:role_box) [ComboBox $role_f.role -entrybg white -width 12 \
+ -textvariable Apol_Context_Dialog::vars($dialog:role) -autopost 1]
+ trace add variable Apol_Context_Dialog::vars($dialog:role_enable) write \
+ [list Apol_Context_Dialog::_role_changed $dialog]
+ pack $vars($dialog:role_cb) -anchor nw
+ pack $vars($dialog:role_box) -anchor nw -padx 4 -expand 0 -fill x
+
+ set type_f [frame $left_f.type]
+ set vars($dialog:type_cb) [checkbutton $type_f.enable -text "Type" \
+ -variable Apol_Context_Dialog::vars($dialog:type_enable)]
+ set vars($dialog:type_box) [Apol_Widget::makeTypeCombobox $type_f.type]
+ pack $vars($dialog:type_cb) -anchor nw
+ pack $vars($dialog:type_box) -anchor nw -padx 4 -expand 0 -fill x
+ trace add variable Apol_Context_Dialog::vars($dialog:type_enable) write \
+ [list Apol_Context_Dialog::_type_changed $dialog]
+ pack $user_f $role_f $type_f -side top -expand 1 -fill x
+
+ set mlsbox [TitleFrame $f.mlsbox -text "MLS Range"]
+ set mls_f [$mlsbox getframe]
+ set vars($dialog:low_cb) [checkbutton $mls_f.low_cb -text "Single Level" \
+ -variable Apol_Context_Dialog::vars($dialog:low_enable)]
+ set vars($dialog:low_level) [Apol_Widget::makeLevelSelector $mls_f.low 8]
+ trace add variable Apol_Context_Dialog::vars($dialog:low_enable) write \
+ [list Apol_Context_Dialog::_low_changed $dialog]
+ set vars($dialog:high_cb) [checkbutton $mls_f.high_cb \
+ -text "High Level" \
+ -variable Apol_Context_Dialog::vars($dialog:high_enable)]
+ set vars($dialog:high_level) [Apol_Widget::makeLevelSelector $mls_f.high 8]
+ trace add variable Apol_Context_Dialog::vars($dialog:high_enable) write \
+ [list Apol_Context_Dialog::_high_changed $dialog]
+ grid $vars($dialog:low_cb) $vars($dialog:high_cb) -sticky w
+ grid $vars($dialog:low_level) $vars($dialog:high_level) -sticky nsew
+ grid columnconfigure $mls_f 0 -weight 1 -uniform 1 -pad 2
+ grid columnconfigure $mls_f 1 -weight 1 -uniform 1 -pad 2
+ grid rowconfigure $mls_f 1 -weight 1
+
+ pack $left_f $mlsbox -side left -expand 1 -fill both
+
+ $dialog add -text "OK" -command [list Apol_Context_Dialog::_okay $dialog]
+ $dialog add -text "Cancel"
+}
+
+# For all options that have been enabled, ensure that the user also
+# selected a value. With those values, ensure that they are
+# authorized (user has the role, etc). For the MLS range, also check
+# that the level is legal by constructing a 'range' with it (as both
+# the low and high level).
+proc Apol_Context_Dialog::_okay {dialog} {
+ variable vars
+ set context [new_apol_context_t]
+ if {[ApolTop::is_policy_open]} {
+ set p $::ApolTop::policy
+ } else {
+ set p NULL
+ }
+
+ if {$vars($dialog:user_enable)} {
+ if {[set user $vars($dialog:user)] == {}} {
+ tk_messageBox -icon error -type ok -title "Could Not Validate Context" \
+ -message "No user was selected."
+ return
+ }
+ $context set_user $p $user
+ }
+ if {$vars($dialog:role_enable)} {
+ if {[set role $vars($dialog:role)] == {}} {
+ tk_messageBox -icon error -type ok -title "Could Not Validate Context" \
+ -message "No role was selected."
+ return
+ }
+ $context set_role $p $role
+ }
+ if {$vars($dialog:type_enable)} {
+ set type [lindex [Apol_Widget::getTypeComboboxValueAndAttrib $vars($dialog:type_box)] 0]
+ if {$type == {}} {
+ tk_messageBox -icon error -type ok -title "Could Not Validate Context" \
+ -message "No type was selected."
+ return
+ }
+ $context set_type $p $type
+ }
+ if {$vars($dialog:low_enable)} {
+ set range [_get_range $dialog]
+ if {$range == {}} {
+ tk_messageBox -icon error -type ok -title "Could Not Validate Context" \
+ -message "No level was selected."
+ return
+ }
+ $context set_range $p $range
+ }
+ if {![ApolTop::is_policy_open] || [$context validate_partial $p] <= 0} {
+ tk_messageBox -icon error -type ok -title "Could Not Validate Context" \
+ -message "The selected context is not valid for the current policy."
+ return
+ } else {
+ $dialog enddialog 0
+ }
+ $context -acquire
+ $context -delete
+}
+
+proc Apol_Context_Dialog::_get_context {dialog} {
+ variable vars
+ set context [new_apol_context_t]
+ if {[ApolTop::is_policy_open]} {
+ set p $::ApolTop::policy
+ } else {
+ set p NULL
+ }
+ if {$vars($dialog:user_enable)} {
+ $context set_user $p $vars($dialog:user)
+ }
+ if {$vars($dialog:role_enable)} {
+ $context set_role $p $vars($dialog:role)
+ }
+ if {$vars($dialog:type_enable)} {
+ set type [lindex [Apol_Widget::getTypeComboboxValueAndAttrib $vars($dialog:type_box)] 0]
+ $context set_type $p $type
+ }
+ set range [_get_range $dialog]
+ if {$range != {}} {
+ $context set_range $p $range
+ }
+ return $context
+}
+
+proc Apol_Context_Dialog::_get_range {dialog} {
+ variable vars
+ if {!$vars($dialog:low_enable)} {
+ return {}
+ }
+ if {[ApolTop::is_policy_open]} {
+ set p $::ApolTop::policy
+ } else {
+ set p NULL
+ }
+ set range [new_apol_mls_range_t]
+ $range set_low $p [Apol_Widget::getLevelSelectorLevel $vars($dialog:low_level)]
+
+ if {$vars($dialog:high_enable)} {
+ $range set_high $p [Apol_Widget::getLevelSelectorLevel $vars($dialog:high_level)]
+ }
+ return $range
+}
+
+proc Apol_Context_Dialog::_user_changed {dialog name1 name2 op} {
+ variable vars
+ if {$vars($dialog:user_enable)} {
+ $vars($dialog:user_box) configure -state normal
+ } else {
+ $vars($dialog:user_box) configure -state disabled
+ }
+}
+
+proc Apol_Context_Dialog::_role_changed {dialog name1 name2 op} {
+ variable vars
+ if {$vars($dialog:role_enable)} {
+ $vars($dialog:role_box) configure -state normal
+ } else {
+ $vars($dialog:role_box) configure -state disabled
+ }
+}
+
+proc Apol_Context_Dialog::_type_changed {dialog name1 name2 op} {
+ variable vars
+ if {$vars($dialog:type_enable)} {
+ Apol_Widget::setTypeComboboxState $vars($dialog:type_box) 1
+ } else {
+ Apol_Widget::setTypeComboboxState $vars($dialog:type_box) 0
+ }
+}
+
+proc Apol_Context_Dialog::_low_changed {dialog name1 name2 op} {
+ variable vars
+ if {$vars($dialog:low_enable)} {
+ $vars($dialog:high_cb) configure -state normal
+ Apol_Widget::setLevelSelectorState $vars($dialog:low_level) 1
+ if {$vars($dialog:high_enable)} {
+ Apol_Widget::setLevelSelectorState $vars($dialog:high_level) 1
+ }
+ } else {
+ $vars($dialog:high_cb) configure -state disabled
+ Apol_Widget::setLevelSelectorState $vars($dialog:low_level) 0
+ Apol_Widget::setLevelSelectorState $vars($dialog:high_level) 0
+ }
+}
+
+proc Apol_Context_Dialog::_high_changed {dialog name1 name2 op} {
+ variable vars
+ if {$vars($dialog:high_enable)} {
+ $vars($dialog:low_cb) configure -text "Low Level"
+ Apol_Widget::setLevelSelectorState $vars($dialog:high_level) 1
+ } else {
+ $vars($dialog:low_cb) configure -text "Single Level"
+ Apol_Widget::setLevelSelectorState $vars($dialog:high_level) 0
+ }
+}