Code

ffccd2576e83f8bb7c777795d3b4b87fdabeeafb
[gosa.git] / gosa-plugins / sudo / admin / sudo / class_sudoGeneric.inc
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_sudo.inc 9975 2008-03-25 14:09:30Z 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  */
24 /*! \brief Sudo generic class. Allow setting User/Host/Command/Runas
25            for a sudo role object.
26  */
27 class sudo extends plugin
28 {
29   /* Group attributes */
30   var $cn= "";
31   var $description= "";
33   var $sudoUser   = array("ALL");
34   var $sudoCommand= array();
35   var $sudoHost   = array("ALL");
36   var $sudoRunAs  = array("ALL");
38   var $accessTo         = array();
39   var $trustModel       = "";
40   var $show_ws_dialog   = FALSE;
41   var $was_trust_account= FALSE;
43   var $objectclasses = array("top","sudoRole");
44   var $attributes    = array("cn","description","sudoUser","sudoCommand","sudoHost","sudoRunAs","accessTo","trustModel");
46   var $is_account = TRUE;
47   var $is_default = FALSE;
48   var $dialog;
50   /*! \brief  Returns to the base department for sudo roles.
51               This department is then used to store new roles.
52       @param  Object  GOsa configuration object.
53       @return String sudo store department
54    */
55   public static function get_sudoers_ou($config)
56   {
57     /***
58       GET sudo base
59      ***/
60     $base ="";
61     if(empty($base)){
62       /* Default is ou=sudoers,BASE */
63       $base = "ou=sudoers,".$config->current['BASE'];
64     }else{
66       /* Append base to given sudoers ou if missing */
67       if(!preg_match("/".normalizePreg($config->current['BASE'])."$/i",$base)){
68         if(!preg_match("/,$/",$base)){
69           $base = $base.",".$config->current['BASE'];
70         }else{
71           $base = $base.$config->current['BASE'];
72         }
73       }
74     }
75     return($base);
76   }
78   /*! \brief  Initializes this sudo class, with all required attributes.
79       @param  Object $config  GOsa configuration object.
80       @param  String $db      "new" or the sudo role dn.
81       @return .
82    */
83   function sudo(&$config, $dn= NULL)
84   {
85     plugin::plugin ($config, $dn);
87     if($this->initially_was_account){
88       foreach(array("sudoUser","sudoCommand","sudoHost","sudoRunAs") as $attr){
89         $this->$attr = array();
90         if(isset($this->attrs[$attr])){
91           $tmp = array();
92           for($i = 0 ; $i < $this->attrs[$attr]['count']; $i++){
93             $tmp[] = $this->attrs[$attr][$i];
94           }
95           $this->$attr = $tmp;
96         }
97       }
99       /* Is this account a trustAccount? */
100       if ($this->is_account && isset($this->attrs['trustModel'])){
101         $this->trustModel= $this->attrs['trustModel'][0];
102         $this->was_trust_account= TRUE;
103       } else {
104         $this->was_trust_account= FALSE;
105         $this->trustModel= "";
106       }
108       $this->accessTo = array();
109       if ($this->is_account && isset($this->attrs['accessTo'])){
110         for ($i= 0; $i<$this->attrs['accessTo']['count']; $i++){
111           $tmp= $this->attrs['accessTo'][$i];
112           $this->accessTo[$tmp]= $tmp;
113         }
114       }
116     }
118     if(preg_match("/^default$/i",$this->cn)){
119       $this->is_default = TRUE;
120     }
122     /* Get global filter config */
123     if (!session::is_set("sysfilter")){
124       $ui= get_userinfo();
125       $base= get_base_from_people($ui->dn);
126       $sysfilter= array( "depselect"       => $base,
127           "regex"           => "*");
128       session::set("sysfilter", $sysfilter);
129     }
130   }
133   /*! \brief  Creates the sudo generic ui. 
134       @return String  The generated HTML content for this plugin. 
135    */
136   function execute()
137   {
138     /* Call parent execute */
139     plugin::execute();
141     /*********************
142        Access control list / trust mode 
143      *********************/ 
145     /* Add user workstation? */
146     if (isset($_POST["add_ws"])){
147       $this->show_ws_dialog= TRUE;
148       $this->dialog= TRUE;
149     }
151     /* Add user workstation? */
152     if (isset($_POST["add_ws_finish"]) && isset($_POST['wslist'])){
153       foreach($_POST['wslist'] as $ws){
154         $this->accessTo[$ws]= $ws;
155       }
156       ksort($this->accessTo);
157       $this->is_modified= TRUE;
158     }
160     /* Remove user workstations? */
161     if (isset($_POST["delete_ws"]) && isset($_POST['workstation_list'])){
162       foreach($_POST['workstation_list'] as $name){
163         unset ($this->accessTo[$name]);
164       }
165       $this->is_modified= TRUE;
166     }
168     /* Add user workstation finished? */
169     if (isset($_POST["add_ws_finish"]) || isset($_POST["add_ws_cancel"])){
170       $this->show_ws_dialog= FALSE;
171       $this->dialog= FALSE;
172     }
174     /* Show ws dialog */
175     if ($this->show_ws_dialog){
176       return($this->display_trust_add_dialog());
177     }
180     /*********************
181        Add users 
182      *********************/ 
183   
184     if(isset($_POST['list_sudoUser']) && !is_object($this->dialog) && $this->acl_is_writeable("sudoUser")){
185       $used = array();
186       foreach($this->sudoUser as $name){
187         $used[] = preg_replace("/^!/","",$name);
188       }
189       $this->dialog =new target_list_users($this->config,$used);
190     }
191    
192     /* Add selected hosts  to the sudoUser list */ 
193     if(isset($_POST['SaveMultiSelectWindow']) && $this->dialog instanceof target_list_users){
194       if($this->acl_is_writeable("sudoUser")){
195         foreach($this->dialog->save() as $entry){
196           $cn = trim($entry['uid'][0]);
197           if(!in_array($cn,$this->sudoUser) && !in_array("!".$cn,$this->sudoUser)){
198             $this->sudoUser[] = $cn;
199           }
200         }   
201       }
202       unset($this->dialog);
203       $this->dialog = NULL;
204     }    
207     /*********************
208        Add systems 
209      *********************/ 
210   
211     if(isset($_POST['list_sudoHost']) && !is_object($this->dialog) && $this->acl_is_writeable("sudoHost")){
212       $used = array();
213       foreach($this->sudoHost as $name){
214         $used[] = preg_replace("/^!/","",$name);
215       }
216       $this->dialog =new target_list_systems($this->config,$used);
217     }
218    
219     /* Add selected hosts  to the sudoHost list */ 
220     if(isset($_POST['SaveMultiSelectWindow']) && $this->dialog instanceof target_list_systems){
221       if($this->acl_is_writeable("sudoHost")){
222         foreach($this->dialog->save() as $entry){
223           $cn = trim($entry['cn'][0]);
224           if(!in_array($cn,$this->sudoHost) && !in_array("!".$cn,$this->sudoHost)){
225             $this->sudoHost[] = $cn;
226           }
227         }   
228       }   
229       unset($this->dialog);
230       $this->dialog = NULL;
231     }    
234     /*********************
235        Dialog handling / display / close  
236      *********************/ 
237   
238     if(isset($_POST['CloseMultiSelectWindow']) && is_object($this->dialog)){
239       unset($this->dialog);
240       $this->dialog = NULL;
241     }    
243     if(is_object($this->dialog)){
244       return($this->dialog->execute());
245     }
247  
248     /*********************
249        NEGATE values 
250      *********************/ 
251     foreach($_POST as $name => $value){
252       if(preg_match("/^neg_/",$name)){
253         $attr = preg_replace("/^neg_([^_]*)_.*$/","\\1",$name);
254         $value= preg_replace("/^neg_[^_]*_([0-9]*)_.*$/","\\1",$name);
255  
256         if($this->acl_is_writeable($attr)){
257           $attrs = $this->$attr;
258           if(isset( $attrs[$value])){
259             $v =  $attrs[$value];
260             if(preg_match("/^!/",$v)){
261               $attrs[$value] = preg_replace("/^!/","",$v);
262             }else{
263               $attrs[$value] = "!".$v;
264             }
265             $this->$attr = $attrs;  
266           }
267         }
268         break; // Do it once, image inputs will be posted twice
269       }
270     }
271   
272     /*********************
273        Delete values 
274      *********************/ 
275     foreach($_POST as $name => $value){
276       if(preg_match("/^del_/",$name)){
277         $attr = preg_replace("/^del_([^_]*)_.*$/","\\1",$name);
278         $value= preg_replace("/^del_[^_]*_([0-9]*)_.*$/","\\1",$name);
279         if($this->acl_is_writeable($attr)){
280           $attrs = $this->$attr;
281           if(isset( $attrs[$value])){
282             unset($attrs[$value]);
283             $this->$attr = $attrs;  
284           }
285         }
286         break; // Do it once, image inputs will be posted twice
287       }
288     }
291     /*********************
292        ADD values 
293      *********************/
295     /* User / Host / Runas */ 
296     foreach(array("sudoUser","sudoHost","sudoRunAs") as $attr){
297       if($this->acl_is_writeable($attr) && 
298           isset($_POST["add_".$attr]) && 
299           isset($_POST['new_'.$attr]) && 
300           !empty($_POST['new_'.$attr])){
301         if(preg_match("/^[a-z\.0-9]*$/i",$_POST['new_'.$attr])){
302           $attrs = $this->$attr;
303           $attrs[] =  trim($_POST['new_'.$attr]); 
304           $this->$attr = $attrs;
305         }else{
306           msg_dialog::display(_("Error"),msgPool::invalid($attr,$_POST['new_'.$attr],"/[a-z0-9]/"));
307         }
308       }
309     }
311     /* Command */
312     foreach(array("sudoCommand") as $attr){
313       if($this->acl_is_writeable($attr) && isset($_POST["add_".$attr]) && isset($_POST['new_'.$attr])){
314         $attrs = $this->$attr;
315         $attrs[] =  trim($_POST['new_'.$attr]); 
316         $this->$attr = $attrs;
317       }
318     }
320     
321     /*********************
322        SMARTY assignments 
323      *********************/
325     $smarty = get_smarty();
326     $smarty->assign("is_default",$this->is_default);
327     foreach($this->attributes as $attr){
328       $smarty->assign($attr,$this->$attr);
329       $smarty->assign($attr."ACL",$this->getacl($attr));
330     }
332     /* Work on trust modes */
333     $smarty->assign("trusthide", " disabled ");
334     if ($this->trustModel == "fullaccess"){
335       $trustmode= 1;
336     } elseif ($this->trustModel == "byhost"){
337       $trustmode= 2;
338       $smarty->assign("trusthide", "");
339     } else {
340       $trustmode= 0;
341     }
342     $smarty->assign("trustmode", $trustmode);
343     $smarty->assign("trustmodes", array( 
344           0 => _("disabled"), 
345           1 => _("full access"),
346           2 => _("allow access to these hosts")));
348     if((count($this->accessTo))==0){
349       $smarty->assign("emptyArrAccess",true);
350     }else{
351       $smarty->assign("emptyArrAccess",false);
352     }
353     $smarty->assign("workstations", $this->accessTo);
354     
355     /* Create lists 
356      */
357     $divlist_sudoUser = new divSelectBox("divlist_sudoUser");
358     $divlist_sudoUser->SetHeight("90");
359     $divlist_sudoHost = new divSelectBox("divlist_sudoHost");
360     $divlist_sudoHost->Setheight("90");
361     $divlist_sudoRunAs = new divSelectBox("divlist_sudoRunAs");
362     $divlist_sudoRunAs->Setheight("90");
363     $divlist_sudoCommand = new divSelectBox("divlist_sudoCommand");
364     $divlist_sudoCommand->Setheight("90");
366     /* Fill divlists
367      */
368     $neg_img= "<img src='images/negate.png' alt='!' class='center'>"; 
369     $option = "<input type='image' src='images/negate.png'     name='neg_%ATTR%_%KEY%' class='center'>"; 
370     $option.= "<input type='image' src='images/edittrash.png'  name='del_%ATTR%_%KEY%' class='center'>"; 
371     foreach(array("sudoUser","sudoCommand","sudoHost","sudoRunAs") as $attr){
372       if($this->acl_is_readable($attr)){
373         foreach($this->$attr as $key => $entry){
374           $entry = preg_replace("/^!/",$neg_img,$entry);
375           $list_name = "divlist_".$attr;
376           $$list_name->AddEntry(
377               array(
378                 array("string" => $entry),
379                 array("string" => preg_replace(array("/%KEY%/","/%ATTR%/"),array($key,$attr),$option),
380                   "attach" => "style='width:40px; border-right: 0px;'")));
381         }
382       }
383     }
385     /* Tell smarty about our divlists 
386      */
387     $smarty->assign("divlist_sudoUser",   $divlist_sudoUser->DrawList());
388     $smarty->assign("divlist_sudoHost",   $divlist_sudoHost->DrawList());
389     $smarty->assign("divlist_sudoRunAs",  $divlist_sudoRunAs->DrawList());
390     $smarty->assign("divlist_sudoCommand",$divlist_sudoCommand->DrawList());
391     return($smarty->fetch(get_template_path('generic.tpl', TRUE)));
392   }
395   /*! \brief  Remove this sudo role from the ldap server 
396    */
397   function remove_from_parent()
398   {
399     plugin::remove_from_parent();
401     $ldap = $this->config->get_ldap_link();
402     $ldap->cd($this->dn);
403     $ldap->rmdir($this->dn);
405     /* Send signal to the world that we've done */
406     $this->handle_post_events("remove");
407   }
410   /*! \brief  Save all relevant HTML posts. 
411    */
412   function save_object()
413   {
414     plugin::save_object();
415     
416     if($this->is_default){
417       $this->cn = "default";
418     }  
420     if(is_object($this->dialog)){
421       $this->dialog->save_object();
422     }
424     /* Trust mode - special handling */
425     if($this->acl_is_writeable("trustModel")){
426       if (isset($_POST['trustmode'])){
427         $saved= $this->trustModel;
428         if ($_POST['trustmode'] == "1"){
429           $this->trustModel= "fullaccess";
430         } elseif ($_POST['trustmode'] == "2"){
431           $this->trustModel= "byhost";
432         } else {
433           $this->trustModel= "";
434         }
435         if ($this->trustModel != $saved){
436           $this->is_modified= TRUE;
437         }
438       }
439     }
440   }
443   /*! \brief  Save changes into the ldap database.
444    */
445   function save()
446   {
447     plugin::save();
448    /* Trust accounts */
449     $objectclasses= array();
450     foreach ($this->attrs['objectClass'] as $key => $class){
451       if (preg_match('/trustAccount/i', $class)){
452         continue;
453       }
454       $objectclasses[]= $this->attrs['objectClass'][$key];
455     }
457     $this->attrs['objectClass']= $objectclasses;
458     if ($this->trustModel != ""){
459       $this->attrs['objectClass'][]= "trustAccount";
460       $this->attrs['trustModel']= $this->trustModel;
461       $this->attrs['accessTo']= array();
462       if ($this->trustModel == "byhost"){
463         foreach ($this->accessTo as $host){
464           $this->attrs['accessTo'][]= $host;
465         }
466       }
467     } else {
468       if ($this->was_trust_account){
469         $this->attrs['accessTo']= array();
470         $this->attrs['trustModel']= array();
471       }
472     }
475     /* Ensure a correct array index 
476      */ 
477     $this->attrs['sudoHost']    = array_values($this->attrs['sudoHost']);
478     $this->attrs['sudoRunAs']   = array_values($this->attrs['sudoRunAs']);
479     $this->attrs['sudoUser']    = array_values($this->attrs['sudoUser']);
480     $this->attrs['sudoCommand'] = array_values($this->attrs['sudoCommand']);
481     $this->cleanup();
483     $ldap = $this->config->get_ldap_link();
484     $ldap->cd($this->config->current['BASE']);
485     if($this->is_new){
486       $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
487       $ldap->cd($this->dn);
488       $ldap->add($this->attrs);
490       /* Send signal to the world that we've done */
491       $this->handle_post_events("create");
492     }else{
493       $ldap->cd($this->dn);
494       $ldap->modify($this->attrs);;
496       /* Send signal to the world that we've done */
497       $this->handle_post_events("modify");
498     }
500     if (!$ldap->success()){
501       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
502     }
503   }
506   /*! \brief  Check the given input.
507       @return Array   All error messages in an array();
508    */
509   function check()
510   {
511     $message = plugin::check();
513     /* Is a name given? */
514     if(empty($this->cn)){
515       $message[] = msgPool::required(_("Name"));
516     }
518     /* Check if name is reserved */
519     if(!$this->is_default && preg_match("/^default$/i",$this->cn)){
520       $message[] = msgPool::reserved(_("Name"));
521     }
523     /* Check name */
524     if(!preg_match("/^[a-z]*$/i",$this->cn)){
525       $message[] = msgPool::invalid(_("Name"),$this->cn,"/[a-z]/i");
526     }
528     /* Check if this entry will cause duplicated ldap entries */
529     $ldap = $this->config->get_ldap_link();
530     $ldap->cd($this->get_sudoers_ou($this->config));
531     $ldap->search("(&(objectClass=sudoRole)(cn=".$this->cn."))");
532     while($attrs = $ldap->fetch()){
533       if($attrs['dn'] != $this->dn){
534         $message[] = msgPool::duplicated(_("Name"));
535       }
536     }
538     return ($message);
539   }
542   /*! \brief  Display the System Trust Add Workstation dialog 
543     @return String  HTML dialog to add a system to the trust list.
545    */
546   private function display_trust_add_dialog()
547   {
548     $smarty = get_smarty();
550     /* Save data */
551     $sysfilter= session::get("sysfilter");
552     foreach( array("depselect", "regex") as $type){
553       if (isset($_POST[$type])){
554         $sysfilter[$type]= $_POST[$type];
555       }
556     }
557     if (isset($_GET['search'])){
558       $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
559       if ($s == "**"){
560         $s= "*";
561       }
562       $sysfilter['regex']= $s;
563     }
564     session::set("sysfilter", $sysfilter);
566     /* Get workstation list */
567     $exclude= "";
568     foreach($this->accessTo as $ws){
569       $exclude.= "(cn=$ws)";
570     }
571     if ($exclude != ""){
572       $exclude= "(!(|$exclude))";
573     }
574     $regex= $sysfilter['regex'];
575     $filter= "(&(|(objectClass=goServer)(objectClass=gotoWorkstation)(objectClass=gotoTerminal))$exclude(cn=*)(cn=$regex))";
577     $res = array();
578     $res= array_merge($res,get_sub_list($filter, array("terminal"), get_ou("terminalou"),
579         get_ou("systemsou").$sysfilter['depselect'],          array("cn"), GL_SUBSEARCH | GL_SIZELIMIT));
580     $res= array_merge($res,get_sub_list($filter, array("server"), get_ou("serverou"), 
581         get_ou("systemsou").$sysfilter['depselect'],          array("cn"), GL_SUBSEARCH | GL_SIZELIMIT));
582     $res= array_merge($res,get_sub_list($filter, array("workstation"), get_ou("workstationou"),
583         get_ou("systemsou").$sysfilter['depselect'],          array("cn"), GL_SUBSEARCH | GL_SIZELIMIT));
585     $wslist= array();
586     foreach ($res as $attrs){
587       $wslist[]= preg_replace('/\$/', '', $attrs['cn'][0]);
588     }
589     asort($wslist);
590     foreach( array("depselect","regex") as $type){
591       $smarty->assign("$type", $sysfilter[$type]);
592     }
593     $smarty->assign("search_image", get_template_path('images/search.png'));
594     $smarty->assign("launchimage",  get_template_path('images/small_filter.png'));
595     $smarty->assign("tree_image",   get_template_path('images/tree.png'));
596     $smarty->assign("deplist",      $this->config->idepartments);
597     $smarty->assign("alphabet",     generate_alphabet());
598     $smarty->assign("hint",         print_sizelimit_warning());
599     $smarty->assign("wslist",       $wslist);
600     $smarty->assign("apply",        apply_filter());
601     $display= $smarty->fetch (get_template_path('trust_machines.tpl', TRUE, dirname(__FILE__)));
602     return ($display);
603   }
606   public function set_default($state)
607   {
608     $this->is_default = TRUE;
609     $this->cn = "default";
610   }
613   /*! \brief  Add ACL object
614       @return Returns the ACL object.
615    */
616   static function plInfo()
617   {
618     return (array(  
619           "plShortName" => _("Sudo"),
620           "plDescription" => _("Sudo role"),
621           "plSelfModify"  => FALSE,
622           "plDepends"     => array(),
623           "plPriority"    => 0,
624           "plSection"     => array("admin"),
625           "plCategory"    => array("sudo" => array("objectClass" => "sudoRole", "description" => _("Sudo role"))),
627           "plProvidedAcls"    => array(
628             "cn"                => _("Name"),
629             "description"       => _("Description"),
630             "sudoUser"          => _("Users"),
631             "sudoHost"          => _("Host"),
632             "sudoCommand"       => _("Command"),
633             "sudoRunAs"         => _("Run as user"),
634             "trustModel"        => _("Access control list"))
635         ));
636   }
638 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
639 ?>