1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id: class_sudoManagement.inc 10099 2008-04-01 12:52:01Z hickert $$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 /*! \brief This is the sudo management class. \
24 This class allows to add/remove/edit sudo roles with GOsa. \
25 All roles will be listed by this plugin, the displayed objects \
26 can also be filtered.
27 */
28 class sudoManagement extends plugin
29 {
30 /* Definitions */
31 public $plHeadline = "Sudo roles";
32 public $plDescription = "Manage sudo roles";
33 public $plIcon ="plugins/sudo/images/sudo.png";
35 private $DivListSudo = NULL;
36 private $sudotabs = NULL;
37 private $base = "";
39 private $start_pasting_copied_objects = FALSE;
41 public $acl_module = array("sudo");
42 public $CopyPasteHandler = NULL;
44 /*! \brief */
45 public function __construct(&$config, &$ui)
46 {
47 /* Save configuration for internal use */
48 $this->config = &$config;
49 $this->ui = &$ui;
50 $this->base = sudo::get_sudoers_ou($this->config);
52 /* Copy & Paste enabled ?*/
53 if ($this->config->get_cfg_value("copyPaste") == "true"){
54 $this->CopyPasteHandler = new CopyPasteHandler($this->config);
55 }
57 /* Create dialog object */
58 $this->DivListSudo = new divListSudo($this->config,$this);
59 }
62 /*! \brief Generate && Display HTML content
63 */
64 public function execute()
65 {
66 /* Call parent execute */
67 plugin::execute();
69 /********************
70 Handle Posts
71 ********************/
73 /* Store these posts if the current object is locked (used by somebody else)*/
74 session::set('LOCK_VARS_TO_USE',array(
75 "/^act$/","/^id$/","/^sudo_edit_/","/^cut_/","/^copy_/",
76 "/^sudo_del_/","/^item_selected/","/menu_action/"));
79 /* Get html posts */
80 $s_action = "";
81 $s_entry = "";
82 foreach($_POST as $name => $value){
83 if(preg_match("/^sudo_edit_/",$name)){
84 $s_action = "edit_role";
85 $s_entry = preg_replace("/^sudo_edit_([0-9]*).*$/","\\1",$name);
86 }
87 if(preg_match("/^sudo_del_/",$name)){
88 $s_action = "del_role";
89 $s_entry = preg_replace("/^sudo_del_([0-9]*).*$/","\\1",$name);
90 }elseif(preg_match("/^editPaste.*/i",$name)){
91 $s_action="editPaste";
92 }elseif(preg_match("/^copy_.*/",$name)){
93 $s_action="copy";
94 $s_entry = preg_replace("/^copy_([0-9]*).*$/i","\\1",$name);
95 # }elseif(preg_match("/^cut_.*/",$name)){
96 # $s_action="cut";
97 # $s_entry = preg_replace("/^cut_([0-9]*).*$/i","\\1",$name);
98 }
99 }
101 if(isset($_GET['act']) && isset($_GET['id']) && $_GET['act'] == "edit_entry"){
102 $id = trim($_GET['id']);
103 if(isset($this->list[$id])){
104 $s_action = "edit_role";
105 $s_entry = $id;
106 }
107 }
109 if(isset($_POST['menu_action']) && in_array($_POST['menu_action'],array("new_role","del_role","new_default","editPaste"))){
110 $s_action = $_POST['menu_action'];
111 }
113 /* handle C&P from layers menu */
114 if(isset($_POST['menu_action']) && preg_match("/^multiple_copy_systems/",$_POST['menu_action'])){
115 $s_action = "copy_multiple";
116 }
118 $smarty= get_smarty();
120 /********************
121 Copy & Paste Handling ...
122 ********************/
124 /* Display the copy & paste dialog, if it is currently open */
125 $ret = $this->copyPasteHandling_from_queue($s_action,$s_entry);
126 if($ret){
127 return($ret);
128 }
131 /********************
132 Create a new sudo ...
133 ********************/
135 /* New sudo? */
136 if ($s_action=="new_role" || $s_action == "new_default"){
138 /* Check create permissions */
139 $acl = $this->ui->get_permissions($this->base,"sudo/sudo");
140 if(preg_match("/c/",$acl)){
142 /* By default we set 'dn' to 'new', all relevant plugins will
143 react on this. */
144 $this->dn= "new";
146 /* Create new sudotabs object */
147 $this->sudotabs= new sudotabs($this->config, $this->config->data['TABS']['SUDOTABS'], $this->dn);
149 /* Set up the sudo ACL's for this 'dn' */
150 $this->sudotabs->set_acl_base($this->base);
152 /* This entry will become the default entry */
153 if($s_action == "new_default"){
154 $this->sudotabs->set_default(TRUE);
155 }
156 }
157 }
160 /********************
161 Save Sudo Tab/Object Changes
162 ********************/
164 /* Save changes */
165 if ((isset($_POST['edit_finish']) || isset($_POST['edit_apply'])) && is_object($this->sudotabs)){
167 /* Check tabs, will feed message array
168 Save, or display error message? */
169 $message= $this->sudotabs->check();
170 if (count($message) == 0){
172 /* Save user data to ldap */
173 $this->sudotabs->save();
175 if (!isset($_POST['edit_apply'])){
177 /* Sudo has been saved successfully, remove lock from LDAP. */
178 if ($this->dn != "new"){
179 $this->remove_lock();
180 }
181 unset ($this->sudotabs);
182 $this->sudotabs= NULL;
183 set_object_info();
184 }else{
186 /* Reinitialize tab */
187 if($this->sudotabs instanceof tabs){
188 $this->sudotabs->re_init();
189 }
190 }
191 } else {
192 /* Ok. There seem to be errors regarding to the tab data,
193 show message and continue as usual. */
194 msg_dialog::displayChecks($message);
195 }
196 }
199 /********************
200 Edit existing role
201 ********************/
203 /* User wants to edit data? */
204 if (($s_action=="edit_role") && !is_object($this->sudotabs)){
206 /* Get 'dn' from posted 'uid', must be unique */
207 $this->dn= $this->list[trim($s_entry)]['dn'];
209 /* Check locking & lock entry if required */
210 $user = get_lock($this->dn);
211 if ($user != ""){
212 return(gen_locked_message ($user, $this->dn));
213 }
214 add_lock ($this->dn, $this->ui->dn);
216 /* Register sudotabs to trigger edit dialog */
217 $this->sudotabs= new sudotabs($this->config,$this->config->data['TABS']['SUDOTABS'], $this->dn);
218 $this->sudotabs->set_acl_base($this->base);
219 set_object_info($this->dn);
220 }
223 /********************
224 Delete entries requested, display confirm dialog
225 ********************/
227 if ($s_action=="del_role"){
228 $ids = $this->list_get_selected_items();
229 if(!count($ids) && $s_entry!=""){
230 $ids = array($s_entry);
231 }
233 $this->dns = array();
234 if(count($ids)){
235 $disallowed = array();
236 foreach($ids as $id){
237 $dn = $this->list[$id]['dn'];
238 $acl = $this->ui->get_permissions($dn, "sudo/sudo");
239 if(preg_match("/d/",$acl)){
240 $this->dns[$id] = $dn;
241 }else{
242 $disallowed[] = $dn;
243 }
244 }
246 if(count($disallowed)){
247 msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
248 }
250 if(count($this->dns)){
252 /* Check locking of entries */
253 $users = get_multiple_locks($this->dns);
254 if(count($users)){
255 return(gen_locked_message($users,$this->dns));
256 }
258 /* Add locks */
259 add_lock($this->dns,$this->ui->dn);
261 /* Lock the current entry, so nobody will edit it during deletion */
262 $smarty->assign("info", msgPool::deleteInfo($this->dns,_("Sudo role")));
263 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
264 }
265 }
266 }
269 /********************
270 Delete entries confirmed
271 ********************/
273 /* Confirmation for deletion has been passed. Sudo should be deleted. */
274 if (isset($_POST['delete_sudos_confirmed'])){
276 /* Remove user by user and check acls before removeing them */
277 foreach($this->dns as $key => $dn){
279 /* Load permissions for selected 'dn' and check if
280 we're allowed to remove this 'dn' */
281 $acl = $this->ui->get_permissions($dn,"sudo/sudo");
282 if(preg_match("/d/",$acl)){
284 /* Delete request is permitted, perform LDAP action */
285 $this->sudotabs= new sudotabs($this->config,$this->config->data['TABS']['SUDOTABS'], $dn);
286 $this->sudotabs->set_acl_base($dn);
287 $this->sudotabs->delete ();
288 unset ($this->sudotabs);
289 $this->sudotabs= NULL;
291 } else {
293 /* Normally this shouldn't be reached, send some extra
294 logs to notify the administrator */
295 msg_dialog::display(_("Permission error"), msgPool::permDelete(), ERROR_DIALOG);
296 new log("security","sudo/".get_class($this),$dn,array(),"Tried to trick deletion.");
297 }
298 }
300 /* Remove lock file after successfull deletion */
301 $this->remove_lock();
302 $this->dns = array();
303 }
306 /********************
307 Delete entries Canceled
308 ********************/
310 /* Remove lock */
311 if(isset($_POST['delete_sudo_cancel'])){
312 $this->remove_lock();
313 $this->dns = array();
314 }
316 /********************
317 A dialog was canceled
318 ********************/
320 /* Cancel dialogs */
321 if (isset($_POST['edit_cancel']) && is_object($this->sudotabs)){
322 $this->remove_lock();
323 $this->sudotabs= NULL;
324 set_object_info();
325 }
328 /********************
329 If there is currently a dialog open, display it
330 ********************/
332 /* Show tab dialog if object is present */
333 if (is_object($this->sudotabs)){
334 $display= $this->sudotabs->execute();
336 /* Don't show buttons if tab dialog requests this */
337 if(isset($this->sudotabs->by_object)){
338 if (!$this->sudotabs->by_object[$this->sudotabs->current]->dialog){
339 $display.= "<p style=\"text-align:right\">\n";
340 $display.= "<input type=submit name=\"edit_finish\" style=\"width:80px\" value=\"".msgPool::okButton()."\">\n";
341 $display.= " \n";
342 if ($this->dn != "new"){
343 $display.= "<input type=submit name=\"edit_apply\" value=\"".msgPool::applyButton()."\">\n";
344 $display.= " \n";
345 }
346 $display.= "<input type=submit name=\"edit_cancel\" value=\"".msgPool::cancelButton()."\">\n";
347 $display.= "</p>";
348 }
349 }
350 return ($display);
351 }
353 /* Check if there is a snapshot dialog open */
354 if($str = $this->showSnapshotDialog(sudo::get_sudoers_ou($this->config),$this->get_used_snapshot_bases(),$this)){
355 return($str);
356 }
358 /* Display dialog with sudo list */
359 $this->DivListSudo->execute();
360 $this->reload ();
361 $this->DivListSudo->setEntries($this->list);
362 return($this->DivListSudo->Draw());
363 }
366 /*! \brief Return all selected elements from HTML list
367 @return Array List of all selected list elements
368 */
369 private function list_get_selected_items()
370 {
371 $ids = array();
372 foreach($_POST as $name => $value){
373 if(preg_match("/^item_selected_[0-9]*$/",$name)){
374 $id = preg_replace("/^item_selected_/","",$name);
375 $ids[$id] = $id;
376 }
377 }
378 return($ids);
379 }
382 /*! \brief Reload the list of sudo roles.
383 */
384 private function reload($CreatePosixsList=false)
385 {
386 $this->list = array();
387 $base = $this->base;
389 $Regex = trim($this->DivListSudo->Regex);
390 $UserRegex = trim($this->DivListSudo->UserRegex);
391 $SubSearch = $this->DivListSudo->SubSearch;
393 /********************
394 Create filter depending on selected checkboxes
395 ********************/
396 $values = array("cn","description","sudoUser","sudoCommand","sudoOption");
397 if($UserRegex == "*"){
398 $ff = "(&(|(cn=".$Regex.")(description=".$Regex."))(objectClass=sudoRole))";
399 }else{
400 $ff = "(&(|(cn=".$Regex.")(description=".$Regex."))(sudoUser=".$UserRegex.")(objectClass=sudoRole))";
401 }
402 $res = get_list($ff, "sudo",$base,$values, GL_SIZELIMIT);
403 $tmp = array();
404 foreach($res as $attrs){
405 $tmp[$attrs['cn'][0]] = $attrs;
406 }
407 uksort($tmp, 'strnatcasecmp');
408 $this->list = array_values($tmp);
409 }
412 /*! \brief Save HTML post data to object
413 */
414 public function save_object()
415 {
416 $this->DivListSudo->save_object();
417 if(is_object($this->CopyPasteHandler)){
418 $this->CopyPasteHandler->save_object();
419 }
420 }
423 /*! \brief Remove this account
424 */
425 public function remove_from_parent()
426 {
427 /* Optionally execute a command after we're done */
428 $this->postremove();
429 }
432 /*! \brief Save to LDAP
433 */
434 public function save()
435 {
436 /* Optionally execute a command after we're done */
437 $this->postcreate();
438 }
441 /*! \brief Remove lock from entry
442 */
443 public function remove_lock()
444 {
445 if (is_object($this->sudotabs) && $this->sudotabs->dn != "new"){
446 del_lock ($this->sudotabs->dn);
447 }
448 if(isset($this->dns) && is_array($this->dns) && count($this->dns)){
449 del_lock($this->dns);
450 }
451 }
453 function get_used_snapshot_bases()
454 {
455 return(array(sudo::get_sudoers_ou($this->config)));
456 }
459 function copyPasteHandling_from_queue($s_action,$s_entry)
460 {
461 /* Check if Copy & Paste is disabled */
462 if(!is_object($this->CopyPasteHandler)){
463 return("");
464 }
466 $ui = get_userinfo();
468 /* Add a single entry to queue */
469 if($s_action == "cut" || $s_action == "copy"){
471 /* Cleanup object queue */
472 $this->CopyPasteHandler->cleanup_queue();
473 $dn = $this->list[$s_entry]['dn'];
475 if($s_action == "copy" && $ui->is_copyable($dn,"sudo","sudo")){
476 $this->CopyPasteHandler->add_to_queue($dn,$s_action,"sudotabs","SUDOTABS","sudo");
477 }
478 # if($s_action == "cut" && $ui->is_cutable($dn,"sudo","sudo")){
479 # $this->CopyPasteHandler->add_to_queue($dn,$s_action,"sudotabs","SUDOTABS","sudo");
480 # }
481 }
483 /* Add entries to queue */
484 if($s_action == "copy_multiple" || $s_action == "cut_multiple"){
486 /* Cleanup object queue */
487 $this->CopyPasteHandler->cleanup_queue();
489 /* Add new entries to CP queue */
490 foreach($this->list_get_selected_items() as $id){
491 $dn = $this->list[$id]['dn'];
493 if($s_action == "copy_multiple" && $ui->is_copyable($dn,"sudo","sudo")){
494 $this->CopyPasteHandler->add_to_queue($dn,"copy","sudotabs","SUDOTABS","sudo");
495 }
496 # if($s_action == "cut_multiple" && $ui->is_cutable($dn,"sudo","sudo")){
497 # $this->CopyPasteHandler->add_to_queue($dn,"cut","sudotabs","SUDOTABS","sudo");
498 # }
499 }
500 }
502 /* Start pasting entries */
503 if($s_action == "editPaste"){
504 $this->start_pasting_copied_objects = TRUE;
505 }
507 /* Return C&P dialog */
508 if($this->start_pasting_copied_objects && $this->CopyPasteHandler->entries_queued()){
510 /* Get dialog */
511 $this->CopyPasteHandler->SetVar("base",$this->DivListSudo->selectedBase);
512 $data = $this->CopyPasteHandler->execute();
514 /* Return dialog data */
515 if(!empty($data)){
516 return($data);
517 }
518 }
520 /* Automatically disable status for pasting */
521 if(!$this->CopyPasteHandler->entries_queued()){
522 $this->start_pasting_copied_objects = FALSE;
523 }
524 return("");
525 }
526 }
527 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
528 ?>