# 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_Users { variable opts variable widgets variable users_list {} } proc Apol_Users::create {tab_name nb} { variable opts variable widgets _initializeVars # Layout frames set frame [$nb insert end $tab_name -text "Users"] set pw1 [PanedWindow $frame.pw -side top] set rpane [$pw1 add -weight 0] set spane [$pw1 add -weight 1] # Title frames set userbox [TitleFrame $rpane.userbox -text "Users"] set s_optionsbox [TitleFrame $spane.obox -text "Search Options"] set resultsbox [TitleFrame $spane.rbox -text "Search Results"] pack $pw1 -fill both -expand yes pack $s_optionsbox -side top -expand 0 -fill both -padx 2 pack $userbox -fill both -expand yes pack $resultsbox -expand yes -fill both -padx 2 # Users listbox widget set users_listbox [Apol_Widget::makeScrolledListbox [$userbox getframe].lb -width 20 -listvar Apol_Users::users_list] Apol_Widget::setListboxCallbacks $users_listbox \ {{"Display User Info" {Apol_Users::_popupUserInfo users}}} pack $users_listbox -fill both -expand yes # Search options subframes set ofm [$s_optionsbox getframe] set verboseFrame [frame $ofm.verbose] set rolesFrame [frame $ofm.roles] set defaultFrame [frame $ofm.default] set rangeFrame [frame $ofm.range] pack $verboseFrame $rolesFrame $defaultFrame $rangeFrame \ -side left -padx 4 -pady 2 -anchor nw -expand 0 -fill y radiobutton $verboseFrame.all_info -text "All information" \ -variable Apol_Users::opts(showSelection) -value all radiobutton $verboseFrame.names_only -text "Names only" \ -variable Apol_Users::opts(showSelection) -value names pack $verboseFrame.all_info $verboseFrame.names_only -anchor w -padx 5 -pady 4 checkbutton $rolesFrame.cb -variable Apol_Users::opts(useRole) -text "Role" set widgets(role) [ComboBox $rolesFrame.combo -width 12 -textvariable Apol_Users::opts(role) \ -helptext "Type or select a role" -state disabled \ -autopost 1] trace add variable Apol_Users::opts(useRole) write \ [list Apol_Users::_toggleRolesCheckbutton $widgets(role)] pack $rolesFrame.cb -anchor nw pack $widgets(role) -padx 4 set widgets(defaultCB) [checkbutton $defaultFrame.cb -variable Apol_Users::opts(enable_default) -text "Default MLS level"] set defaultDisplay [Entry $defaultFrame.display -textvariable Apol_Users::opts(default_level_display) -width 16 -editable 0] set defaultButton [button $defaultFrame.button -text "Select Level..." -state disabled -command [list Apol_Users::_show_level_dialog]] trace add variable Apol_Users::opts(enable_default) write \ [list Apol_Users::_toggleDefaultCheckbutton $widgets(defaultCB) $defaultDisplay $defaultButton] trace add variable Apol_Users::opts(default_level) write \ [list Apol_Users::_updateDefaultDisplay $defaultDisplay] pack $widgets(defaultCB) -side top -anchor nw -expand 0 pack $defaultDisplay -side top -expand 0 -fill x -padx 4 pack $defaultButton -side top -expand 1 -fill none -padx 4 -anchor ne set widgets(range) [Apol_Widget::makeRangeSelector $rangeFrame.range Users] pack $widgets(range) -expand 1 -fill x # Action Buttons button $ofm.ok -text OK -width 6 -command Apol_Users::_searchUsers pack $ofm.ok -side right -pady 5 -padx 5 -anchor ne set widgets(results) [Apol_Widget::makeSearchResults [$resultsbox getframe].results] pack $widgets(results) -expand yes -fill both return $frame } proc Apol_Users::open {ppath} { set q [new_apol_user_query_t] set v [$q run $::ApolTop::policy] $q -acquire $q -delete variable users_list [lsort [user_vector_to_list $v]] $v -acquire $v -delete variable opts variable widgets $Apol_Users::widgets(role) configure -values [Apol_Roles::getRoles] if {[ApolTop::is_capable "mls"]} { Apol_Widget::setRangeSelectorCompleteState $widgets(range) normal $widgets(defaultCB) configure -state normal } else { Apol_Widget::clearRangeSelector $widgets(range) Apol_Widget::setRangeSelectorCompleteState $widgets(range) disabled set opts(enable_default) 0 $widgets(defaultCB) configure -state disabled } } proc Apol_Users::close {} { variable widgets _initializeVars variable users_list {} $widgets(role) configure -values "" Apol_Widget::clearSearchResults $widgets(results) Apol_Widget::clearRangeSelector $widgets(range) Apol_Widget::setRangeSelectorCompleteState $widgets(range) normal $widgets(defaultCB) configure -state normal } proc Apol_Users::getTextWidget {} { variable widgets return $widgets(results).tb } # Return a list of all user names within the current policy. If no # policy is loaded then return an empty list. proc Apol_Users::getUsers {} { variable users_list set users_list } #### private functions below #### proc Apol_Users::_initializeVars {} { variable opts array set opts { showSelection all useRole 0 role {} enable_default 0 default_level {} } } proc Apol_Users::_toggleRolesCheckbutton {path name1 name2 op} { variable opts if {$opts($name2)} { $path configure -state normal -entrybg white } else { $path configure -state disabled -entrybg $ApolTop::default_bg_color } } proc Apol_Users::_toggleDefaultCheckbutton {cb display button name1 name2 op} { variable opts if {$opts($name2)} { $button configure -state normal $display configure -state normal } else { $button configure -state disabled $display configure -state disabled } } proc Apol_Users::_show_level_dialog {} { variable opts .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.default.button configure -state disabled set new_level [Apol_Level_Dialog::getLevel $opts(default_level)] if {$new_level != {}} { set opts(default_level) $new_level $opts(default_level) -acquire } .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.default.button configure -state normal } proc Apol_Users::_updateDefaultDisplay {display name1 name2 op} { variable opts if {$opts(default_level) == {}} { set opts(default_level_display) {} $display configure -helptext {} } else { set level [$opts(default_level) render $::ApolTop::policy] if {$level == {}} { set opts(default_level_display) "" } else { set opts(default_level_display) $level } $display configure -helptext $opts(default_level_display) } } proc Apol_Users::_popupUserInfo {which user} { Apol_Widget::showPopupText $user [_renderUser $user 1] } proc Apol_Users::_searchUsers {} { variable opts variable widgets .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state disabled 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." .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state normal return } if {$opts(useRole)} { if {$opts(role) == ""} { tk_messageBox -icon error -type ok -title "Error" -message "No role selected." .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state normal return } set role $opts(role) } else { set role {} } if {$opts(enable_default)} { if {$opts(default_level) == {}} { tk_messageBox -icon error -type ok -title "Error" -message "No default level selected." .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state normal return } set default $opts(default_level) # the user query will handle destroying the apol_mls_level object } else { set default NULL } set range_enabled [Apol_Widget::getRangeSelectorState $widgets(range)] foreach {range range_type} [Apol_Widget::getRangeSelectorValue $widgets(range)] {break} if {$range_enabled} { if {$range == {}} { tk_messageBox -icon error -type ok -title "Error" -message "No range selected." .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state normal return } # the user query will handle destroying the apol_mls_range object } else { set range NULL } if {$opts(showSelection) == "all"} { set show_all 1 } else { set show_all 0 } set q [new_apol_user_query_t] $q set_role $::ApolTop::policy $role $q set_default_level $::ApolTop::policy $default $q set_range $::ApolTop::policy $range $range_type set v [$q run $::ApolTop::policy] $q -acquire $q -delete set users_data [user_vector_to_list $v] $v -acquire $v -delete set text "USERS:\n" if {[llength $users_data] == 0} { append text "Search returned no results." } else { foreach u [lsort -index 0 $users_data] { append text "\n[_renderUser $u $show_all]" } } Apol_Widget::appendSearchResultText $widgets(results) $text .mainframe.frame.nb.fcomponents.nb.fApol_Users.pw.f1.frame.obox.f.ok configure -state normal } proc Apol_Users::_renderUser {user_name show_all} { set text "$user_name" if {!$show_all} { return $text } set qpol_user_datum [new_qpol_user_t $::ApolTop::qpolicy $user_name] if {[ApolTop::is_capable "mls"]} { set default [$qpol_user_datum get_dfltlevel $::ApolTop::qpolicy] set apol_default [new_apol_mls_level_t $::ApolTop::policy $default] append text " level [$apol_default render $::ApolTop::policy]" $apol_default -acquire $apol_default -delete set range [$qpol_user_datum get_range $::ApolTop::qpolicy] set apol_range [new_apol_mls_range_t $::ApolTop::policy $range] append text " range [$apol_range render $::ApolTop::policy]" $apol_range -acquire $apol_range -delete } set i [$qpol_user_datum get_role_iter $::ApolTop::qpolicy] set roles {} while {![$i end]} { set qpol_role_datum [qpol_role_from_void [$i get_item]] lappend roles [$qpol_role_datum get_name $::ApolTop::qpolicy] $i next } append text " ([llength $roles] role" if {[llength $roles] != 1} { append text "s" } append text ")\n" foreach r $roles { append text " $r\n" } return $text }