Code

Replaced in_array calls with in_array_strict
[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 {
30     protected $cn= "";
31     protected $description= "";
33     protected $sudoUser   = array("ALL");
34     protected $sudoCommand= array();
35     protected $sudoHost   = array("ALL");
36     protected $sudoRunAs  = array("ALL");
38     private $is_default = FALSE;
40     public $objectclasses = array("top","sudoRole");
41     public $attributes    = array("cn","description","sudoUser","sudoCommand","sudoHost","sudoRunAs");
43     public $ignore_account = TRUE;
45         
46     public $orig_dn;
47     private $systemEnabled = FALSE;
49     /*! \brief  Returns to the base department for sudo roles.
50       This department is then used to store new roles.
51       @param  Object  GOsa configuration object.
52       @return String sudo store department
53      */
54     public static function get_sudoers_ou($config)
55     {
56         return(get_ou("sudo", "sudoRDN").$config->current['BASE']);
57     }
59     /*! \brief  Initializes this sudo class, with all required attributes.
60       @param  Object $config  GOsa configuration object.
61       @param  String $db      "new" or the sudo role dn.
62       @return .
63      */
64     function sudo(&$config, $dn= NULL)
65     {
66         plugin::plugin ($config, $dn);
68         $this->systemEnabled = class_available("systemSelect");
70         $this->trustModeDialog = new trustModeDialog($this->config, $this->dn,NULL);
71         $this->trustModeDialog->setAcl('sudo/sudo');
73         if($this->initially_was_account){
74             foreach(array("sudoUser","sudoCommand","sudoHost","sudoRunAs") as $attr){
75                 $this->$attr = array();
76                 if(isset($this->attrs[$attr])){
77                     $tmp = array();
78                     for($i = 0 ; $i < $this->attrs[$attr]['count']; $i++){
79                         $tmp[] = $this->attrs[$attr][$i];
80                     }
81                     $this->$attr = $tmp;
82                 }
83             }
84         }
86         if(preg_match("/^defaults$/i",$this->cn)){
87             $this->is_default = TRUE;
88         }
90         /* Get global filter config */
91         if (!session::is_set("sysfilter")){
92             $ui= get_userinfo();
93             $base= get_base_from_people($ui->dn);
94             $sysfilter= array( "depselect"       => $base,
95                     "regex"           => "*");
96             session::set("sysfilter", $sysfilter);
97         }
99         $this->orig_dn = $this->dn;
101         // Build sortable lists 
102         foreach(array('sudoUser','sudoCommand','sudoHost','sudoRunAs') as $l){
103             $ll = $l."List";
104             $this->$ll = new sortableListing($this->$l);
105             $this->$ll->setDeleteable(false);
106             $this->$ll->setEditable(false);
107             $this->$ll->setWidth("100%");
108             $this->$ll->setHeight("100px");
109             $this->$ll->setAcl($this->getacl($l));
110             $this->$ll->setDefaultSortColumn(1);
111         }
112         $this->sudoUserList->setHeader(array("!",_("Type"),_("Member"),_("Option")));
113         $this->sudoUserList->setColspecs(array('24px','24px','*','46px'));
114         $this->sudoUserList->setDefaultSortColumn(2);
115         $this->sudoHostList->setHeader(array("!",_("System"),_("Option")));
116         $this->sudoHostList->setColspecs(array('24px','*','46px'));
117         $this->sudoCommandList->setHeader(array("!",_("Command"),_("Option")));
118         $this->sudoCommandList->setColspecs(array('24px','*','46px'));
119         $this->sudoRunAsList->setHeader(array("!",_("User"),_("Option")));
120         $this->sudoRunAsList->setColspecs(array('24px','*','46px'));
121     }
124     /*! \brief  Creates the sudo generic ui. 
125       @return String  The generated HTML content for this plugin. 
126      */
127     function execute()
128     {
129         /* Call parent execute */
130         plugin::execute();
132         // Set list ACLs
133         foreach(array('sudoUser','sudoCommand','sudoHost','sudoRunAs') as $l){
134             $ll = $l."List";
135             $this->$ll->setAcl($this->getacl($l));
136         }
138         // Handle trust mode dialog
139         $trustModeDialog = $this->trustModeDialog->execute();
140         if($this->trustModeDialog->trustSelect){
141             $this->dialog = TRUE;
142             return($trustModeDialog);
144         }
146         if(!is_object($this->dialog)){
147             $this->dialog = FALSE;
148         }
150         /*********************
151           Add users 
152          *********************/ 
154         if(isset($_POST['list_sudoUser']) && !is_object($this->dialog) && $this->acl_is_writeable("sudoUser")){
155             $this->dialog =new userGroupSelect($this->config,get_userinfo());
156         }
158         /* Add selected hosts  to the sudoUser list */ 
159         if(isset($_POST['userGroupSelect_save']) && $this->dialog instanceof userGroupSelect){
160             if($this->acl_is_writeable("sudoUser")){
161                 foreach($this->dialog->save() as $entry){
162                     if(in_array_strict("posixGroup",$entry['objectClass'])){
163                         $name = trim("%".$entry['cn'][0]);
164                     }elseif(isset($entry['uid'][0])){
165                         $name = trim($entry['uid'][0]);
166                     }
167                     if(!in_array_strict($name,$this->sudoUser) && !in_array_strict("!".$name,$this->sudoUser)){
168                         $this->sudoUser[] = $name;
169                     }
170                 }   
171             }
172             unset($this->dialog);
173             $this->dialog = NULL;
174         }    
176         if(isset($_POST['userGroupSelect_cancel']) && $this->dialog instanceOf userGroupSelect){
177             unset($this->dialog);
178             $this->dialog = NULL;
179         }    
181         if($this->dialog instanceOf userGroupSelect){
182             $used = array();
183             foreach($this->sudoUser as $name){
184                 $str = preg_replace("/^!/","",$name);
185                 if(preg_match("/^%/", $str)){
186                     $used['cn'][] = preg_replace("/^%/","",$str);
187                 }else{
188                     $used['uid'][] = $str;
189                 }
190             }
192             // Build up blocklist
193             session::set('filterBlacklist', $used);
194             return($this->dialog->execute());
195         }
199         /*********************
200           Add systems 
201          *********************/ 
203         if(isset($_POST['list_sudoHost']) && !is_object($this->dialog) && $this->acl_is_writeable("sudoHost")){
204             $this->dialog =new systemSelect($this->config,get_userinfo());
205         }
207         /* Add selected hosts  to the sudoHost list */ 
208         if(isset($_POST['systemSelect_save']) && $this->dialog instanceof systemSelect){
209             if($this->acl_is_writeable("sudoHost")){
210                 foreach($this->dialog->save() as $entry){
211                     $cn = trim($entry['cn'][0]);
212                     if(!in_array_strict($cn,$this->sudoHost) && !in_array_strict("!".$cn,$this->sudoHost)){
213                         $this->sudoHost[] = $cn;
214                     }
215                 }   
216             }   
217             unset($this->dialog);
218             $this->dialog = NULL;
219         }    
221         if(isset($_POST['systemSelect_cancel']) && $this->dialog instanceOf systemSelect){
222             unset($this->dialog);
223             $this->dialog = NULL;
224         }    
226         if($this->dialog instanceOf systemSelect){
227             $used = array();
228             foreach($this->sudoHost as $name){
229                 $used['cn'][] = preg_replace("/^!/","",$name);
230             }
232             // Build up blocklist
233             session::set('filterBlacklist', $used);
234             return($this->dialog->execute());
235         }
237         /*********************
238           Dialog handling / display / close  
239          *********************/ 
241         if(is_object($this->dialog)){
242             return($this->dialog->execute());
243         }
246         /*********************
247           NEGATE values 
248          *********************/ 
249         foreach($_POST as $name => $value){
250             $value =get_post($name);
251             if(preg_match("/^neg_/",$name)){
252                 $attr = preg_replace("/^neg_([^_]*)_.*$/","\\1",$name);
253                 $value= preg_replace("/^neg_[^_]*_([0-9]*)$/","\\1",$name);
255                 if($this->acl_is_writeable($attr)){
256                     $attrs = $this->$attr;
257                     if(isset( $attrs[$value])){
258                         $v =  $attrs[$value];
259                         if(preg_match("/^!/",$v)){
260                             $attrs[$value] = preg_replace("/^!/","",$v);
261                         }else{
262                             $attrs[$value] = "!".$v;
263                         }
264                         $this->$attr = $attrs;  
265                     }
266                 }
267                 break; // Do it once, image inputs will be posted twice
268             }
269         }
271         /*********************
272           Delete values 
273          *********************/ 
274         foreach($_POST as $name => $value){
275             $value =get_post($name);
276             if(preg_match("/^delS_/",$name)){
277                 $attr = preg_replace("/^delS_([^_]*).*$/","\\1",$name);
278                 $value= preg_replace("/^delS_[^_]*_([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])){
302                 $c = preg_quote(' *+-?_|!\'"()','/');
303                 if(preg_match("/^[a-z0-9{$c}]*$/i",get_post('new_'.$attr))){
304                     $attrs = $this->$attr;
305                     $attrs[] =  trim(get_post('new_'.$attr)); 
306                     $this->$attr = $attrs;
307                 }else{
308                     msg_dialog::display(_("Error"),msgPool::invalid($attr,get_post('new_'.$attr),"/[a-z0-9{$c}]/i"));
309                 }
310             }
311         }
313         /* Command */
314         foreach(array("sudoCommand") as $attr){
315             if($this->acl_is_writeable($attr) && isset($_POST["add_".$attr]) && isset($_POST['new_'.$attr])){
316                 $attrs = $this->$attr;
317                 $attrs[] =  trim(get_post('new_'.$attr)); 
318                 $this->$attr = $attrs;
319             }
320         }
323         /*********************
324           SMARTY assignments 
325          *********************/
327         $smarty = get_smarty();
328         $smarty->assign("systemEnabled", $this->systemEnabled);
329         $smarty->assign("trustModeDialog" , $trustModeDialog);
330         $smarty->assign("is_default",$this->is_default);
331         foreach($this->attributes as $attr){
332             $smarty->assign($attr, set_post($this->$attr));
333             $smarty->assign($attr."ACL",$this->getacl($attr));
334         }
336         /* Fill listings
337          */
338         $neg_img= image('plugins/sudo/images/negate.png','','!');
339         $option = image('plugins/sudo/images/negate.png','neg_%ATTR%_%KEY%');
340         $option.= image('images/lists/trash.png', 'delS_%ATTR%_%KEY%');
341         foreach(array('sudoUser','sudoCommand','sudoHost','sudoRunAs') as $l){
342             $l.="Data";
343             $$l = array();
344         }
346         foreach(array("sudoCommand","sudoHost","sudoRunAs") as $attr){
347             $tmp =array();
348             $list = $attr."List";
349             $data = $attr."Data";
350             foreach($this->$attr as $id => $entry){
351                 $neg = "";
352                 if(preg_match("/^!/",$entry)){
353                     $neg = $neg_img;
354                 }
355                 $entry = preg_replace("/^!/","",$entry);
357                 $action =preg_replace(array("/%KEY%/","/%ATTR%/"),array($id,$attr),$option);
358                 $tmp[$id] = array('data'=>array($neg,$entry,$action)) ;
359             }
360             $this->$list->setListData($this->$attr, $tmp);
361             $this->$list->update();
362             $smarty->assign("listing_{$attr}", $this->$list->render());
363         }
366         $img1 = image('plugins/users/images/select_user.png','',_("User"));
367         $img2 = image('plugins/groups/images/select_group.png','',_("Group"));
368         $sudoUserData  = array();
369         foreach($this->sudoUser as $id => $entry){
370             $neg = "";
371             if(preg_match("/^!/",$entry)){
372                 $neg = $neg_img;
373             }
374             $entry = preg_replace("/^!/","",$entry);
376             $img = $img1;
377             if(preg_match("/^%/",$entry)){
378                 $img = $img2;
379             }
380             $entry = preg_replace("/^%/","",$entry);
381             $action =preg_replace(array("/%KEY%/","/%ATTR%/"),array($id,'sudoUser'),$option);
382             $sudoUserData[$id] = array('data'=>array($neg,$img,$entry,$action)) ;
383         }
384         $this->sudoUserList->setListData($this->sudoUser,$sudoUserData);
385         $this->sudoUserList->update();
386         $smarty->assign("listing_sudoUser", $this->sudoUserList->render());
387         return($smarty->fetch(get_template_path('generic.tpl', TRUE)));
388     }
391     /*! \brief  Remove this sudo role from the ldap server 
392      */
393     function remove_from_parent()
394     {
395         plugin::remove_from_parent();
397         $ldap = $this->config->get_ldap_link();
398         $ldap->cd($this->dn);
399         $ldap->rmdir($this->dn);
401         /* Send signal to the world that we've done */
402         $this->handle_post_events("remove");
403     }
406     /*! \brief  Save all relevant HTML posts. 
407      */
408     function save_object()
409     {
410         plugin::save_object();
411         $this->trustModeDialog->save_object();
413         if($this->is_default){
414             $this->cn = "defaults";
415         }  
416     }
419     function set_acl_base($base)
420     {
421         plugin::set_acl_base($base); 
422         $this->trustModeDialog->set_acl_base($base);
423     }
426     /*! \brief  Save changes into the ldap database.
427      */
428     function save()
429     {
430         plugin::save();
432         /* Ensure a correct array index 
433          */ 
434         $this->attrs['sudoHost']    = array_values($this->attrs['sudoHost']);
435         $this->attrs['sudoRunAs']   = array_values($this->attrs['sudoRunAs']);
436         $this->attrs['sudoUser']    = array_values($this->attrs['sudoUser']);
437         $this->attrs['sudoCommand'] = array_values($this->attrs['sudoCommand']);
439         $this->cleanup();
441         $ldap = $this->config->get_ldap_link();
442         $ldap->cd($this->config->current['BASE']);
444         if($this->is_new){
445             $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
446             $ldap->cd($this->dn);
447             $ldap->add($this->attrs);
449             /* Send signal to the world that we've done */
450             $this->handle_post_events("add");
451         }else{
452             $ldap->cd($this->dn);
453             $ldap->modify($this->attrs);;
455             /* Send signal to the world that we've done */
456             $this->handle_post_events("modify");
457         }
458         $this->trustModeDialog->dn = $this->dn;
459         $this->trustModeDialog->save();
461         if (!$ldap->success()){
462             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
463         }
464     }
467     /*! \brief  Check the given input.
468       @return Array   All error messages in an array();
469      */
470     function check()
471     {
472         $message = plugin::check();
474         /* Is a name given? */
475         if($this->cn == ""){
476             $message[] = msgPool::required(_("Name"));
477         }
479         /* Check if name is reserved */
480         if(!$this->is_default && preg_match("/^defaults$/i",$this->cn)){
481             $message[] = msgPool::reserved(_("Name"));
482         }
484         /* Check name */
485         if(!preg_match("/^[0-9a-z\@]*$/i",$this->cn)){
486             $message[] = msgPool::invalid(_("Name"),$this->cn,"/[0-9a-z\@]/i");
487         }
489         /* Check if this entry will cause duplicated ldap entries */
490         $ldap = $this->config->get_ldap_link();
491         $ldap->cd($this->get_sudoers_ou($this->config));
492         $ldap->search("(&(objectClass=sudoRole)(cn=".$this->cn."))");
493         while($attrs = $ldap->fetch()){
494             if($attrs['dn'] != $this->dn){
495                 $message[] = msgPool::duplicated(_("Name"));
496             }
497         }
499         /* Check if we are allowed to create or move this object
500          */
501         if($this->orig_dn == "new" && !$this->acl_is_createable($this->get_sudoers_ou($this->config))){
502             $message[] = msgPool::permCreate();
503         }
505         return ($message);
506     }
509     /*! \brief Force this entry to be handled and saved as 'default'
510       @param  BOOL  TRUE -force defaults   FALSE -normal
511      */
512     public function set_default($state)
513     {
514         $this->is_default = TRUE;
515         $this->cn = "defaults";
516     }
519     /*! \brief  Add ACL object
520       @return Returns the ACL object.
521      */
522     static function plInfo()
523     {
524         return (array(  
525                     "plShortName" => _("Sudo"),
526                     "plDescription" => _("Sudo role"),
527                     "plSelfModify"  => FALSE,
528                     "plDepends"     => array(),
529                     "plPriority"    => 0,
530                     "plSection"     => array("administration"),
531                     "plCategory"    => array("sudo" => array("objectClass" => "sudoRole", "description" => _("Sudo role"))),
533                     "plProperties" => 
534                     array(
535                         array(
536                             "name"          => "sudoRDN",
537                             "type"          => "rdn",
538                             "default"       => "ou=sudoers,",
539                             "description"   => _("RDN for sudo rule storage."),
540                             "check"         => "gosaProperty::isRdn",
541                             "migrate"       => "migrate_sudoRDN",
542                             "group"         => "plugin",
543                             "mandatory"     => FALSE)),
546             "plProvidedAcls"    => array(
547                     "accessTo"          => _("System trust"),
548                     "cn"                => _("Name"),
549                     "description"       => _("Description"),
550                     "sudoUser"          => _("Users"),
551                     "sudoHost"          => _("Host"),
552                     "sudoCommand"       => _("Command"),
553                     "sudoRunAs"         => _("Run as user"),
554                     "trustModel"        => _("Access control list"))
555                 ));
556     }
559     /*! \brief  This function will be called if an object gets copied.
560       This function adapts attributes from the source object.
561       @param  Array The source object.
562      */
563     function PrepareForCopyPaste($source)
564     {
565         plugin::PrepareForCopyPaste($source);
567         $this->trustModeDialog->PrepareForCopyPaste($source);
569         foreach(array("sudoUser","sudoCommand","sudoHost","sudoRunAs") as $attr){
570             $this->$attr = array();
571             if(isset($source[$attr])){
572                 $tmp = array();
573                 for($i = 0 ; $i < $source[$attr]['count']; $i++){
574                     $tmp[] = $source[$attr][$i];
575                 }
576                 $this->$attr = $tmp;
577             }
578         }
579     }
582     /*! \brief  Used for copy & paste.
583       Returns a HTML input mask, which allows to change the cn of this entry.
584       @param  Array   Array containing current status && a HTML template.              
585      */
586     function getCopyDialog()
587     {
588         $vars = array("cn");
589         $smarty = get_smarty();
590         $smarty->assign("cn", set_post($this->cn));
591         $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
592         $ret = array();
593         $ret['string'] = $str;
594         $ret['status'] = "";
595         return($ret);
596     }
599     public function get_cn()
600     {
601         return($this->cn);
602     }
605     /*! \brief  Used for copy & paste.
606       Some entries must be renamed to avaoid duplicate entries.
607      */
608     function saveCopyDialog()
609     {
610         if(isset($_POST['cn'])){
611             $this->cn = get_post('cn');
612         }
613     }
615 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
616 ?>