Code

a9a33c1e4540ada30d6afd79e9fe50e33142caea
[gosa.git] / gosa-plugins / sudo / admin / sudo / class_sudoOption.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 option class.
25   Allows setting flags/options for a sudo role.
26  */
27 class sudoOption extends plugin
28 {
29     /* Group attributes */
30     protected $sudoOption = array();
31     public $attributes    = array("sudoOption");
32     private $options = array();
33     public $ignore_account = TRUE;
35     /*! \brief  Initializes this class
36       @param  Object $config  The GOsa configuration object.
37       @param  String $dn      The object dn.
38      */
39     function sudoOption(&$config, $dn= NULL)
40     {
41         plugin::plugin ($config, $dn);
43         /****
44           Create a list of known options
45          ****/
46         $options = array();
47         $option['long_otp_prompt']= array('NAME' =>'long_otp_prompt' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
48         $option['ignore_dot']=  array('NAME' =>'ignore_dot' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
49         $option['mail_always']= array('NAME' =>'mail_always' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
50         $option['mail_badpass']=  array('NAME' =>'mail_badpass' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
51         $option['mail_no_user']=  array('NAME' =>'mail_no_user' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
52         $option['mail_no_host']=  array('NAME' =>'mail_no_host' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
53         $option['mail_no_perms']= array('NAME' =>'mail_no_perms' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
54         $option['tty_tickets']= array('NAME' =>'tty_tickets' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
55         $option['authenticate']=  array('NAME' =>'authenticate' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
56         $option['root_sudo']= array('NAME' =>'root_sudo' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
57         $option['log_host']=  array('NAME' =>'log_host' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
58         $option['log_year']=  array('NAME' =>'log_year' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
59         $option['shell_noargs']=  array('NAME' =>'shell_noargs' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
60         $option['set_home']=  array('NAME' =>'set_home' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
61         $option['always_set_home']= array('NAME' =>'always_set_home' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
62         $option['path_info']= array('NAME' =>'path_info' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
63         $option['preserve_groups']= array('NAME' =>'preserve_groups' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
64         $option['fqdn']=  array('NAME' =>'fqdn' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
65         $option['insults']= array('NAME' =>'insults' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
66         $option['requiretty']=  array('NAME' =>'requiretty' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
67         $option['env_editor']=  array('NAME' =>'env_editor' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
68         $option['rootpw']=  array('NAME' =>'rootpw' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
69         $option['runaspw']= array('NAME' =>'runaspw' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
70         $option['targetpw']=  array('NAME' =>'targetpw' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
71         $option['set_logname']= array('NAME' =>'set_logname' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
72         $option['stay_setuid']= array('NAME' =>'stay_setuid' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
73         $option['env_reset']= array('NAME' =>'env_reset' ,   'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'TRUE');
74         $option['use_loginclass']=  array('NAME' =>'use_loginclass' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
75         $option['noexec']=  array('NAME' =>'noexec' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
76         $option['ignore_local_sudoers']=  array('NAME' =>'ignore_local_sudoers' ,  'TYPE' => 'BOOLEAN' ,   'DEFAULT' => 'FALSE');
77         $option['passwd_tries']=  array('NAME' =>'passwd_tries' ,  'TYPE' => 'INTEGER' ,   'DEFAULT' => 3);
78         $option['loglinelen']=  array('NAME' =>'loglinelen' ,  'TYPE' => 'BOOL_INTEGER' ,  'DEFAULT' => 80);
79         $option['timestamp_timeout']= array('NAME' =>'timestamp_timeout' ,   'TYPE' => 'BOOL_INTEGER' ,  'DEFAULT' => 0);
80         $option['passwd_timeout']=  array('NAME' =>'passwd_timeout' ,  'TYPE' => 'BOOL_INTEGER' ,  'DEFAULT' => 15);
81         $option['umask']= array('NAME' =>'umask' ,   'TYPE' => 'BOOL_INTEGER' ,  'DEFAULT' => "0022");
82         $option['mailsub']= array('NAME' =>'mailsub' ,   'TYPE' => 'STRING' ,   'DEFAULT' => '*** SECURITY information for %h ***');
83         $option['badpass_message']= array('NAME' =>'badpass_message' ,   'TYPE' => 'STRING' ,   'DEFAULT' => 'Sorry, try again');
84         $option['timestampdir']=  array('NAME' =>'timestampdir' ,  'TYPE' => 'STRING' ,   'DEFAULT' => '/var/run/sudo');
85         $option['timestampowner']=  array('NAME' =>'timestampowner' ,  'TYPE' => 'STRING' ,   'DEFAULT' => 'root');
86         $option['passprompt']=  array('NAME' =>'passprompt' ,  'TYPE' => 'STRING' ,   'DEFAULT' => '[sudo] password for %p: ');
87         $option['runas_default']= array('NAME' =>'runas_default' ,   'TYPE' => 'STRING' ,   'DEFAULT' => 'root');
88         $option['syslog_goodpri']=  array('NAME' =>'syslog_goodpri' ,  'TYPE' => 'STRING' ,   'DEFAULT' => 'notice');
89         $option['syslog_badpri']= array('NAME' =>'syslog_badpri' ,   'TYPE' => 'STRING' ,   'DEFAULT' => 'alert');
90         $option['editor']=  array('NAME' =>'editor' ,  'TYPE' => 'STRING' ,   'DEFAULT' => '/usr/bin/vi');
91         $option['noexec_file']= array('NAME' =>'noexec_file' ,   'TYPE' => 'STRING' ,   'DEFAULT' => '/usr/lib/sudo/sudo_noexec.so');
92         $option['lecture']= array('NAME' =>'lecture' ,   'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'once');
93         $option['lecture_file']=  array('NAME' =>'lecture_file' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => '');
94         $option['logfile']= array('NAME' =>'logfile' ,   'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'syslog');
95         $option['syslog']=  array('NAME' =>'syslog' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'authpriv');
96         $option['mailerpath']=  array('NAME' =>'mailerpath' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => '');
97         $option['mailerflags']= array('NAME' =>'mailerflags' ,   'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => '-t');
98         $option['mailto']=  array('NAME' =>'mailto' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'root');
99         $option['exempt_group']=  array('NAME' =>'exempt_group' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'root');
100         $option['verifypw']=  array('NAME' =>'verifypw' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'all');
101         $option['listpw']=  array('NAME' =>'listpw' ,  'TYPE' => 'STRING_BOOL' ,   'DEFAULT' => 'any');
102         $option['env_check']= array('NAME' =>'env_check' ,   'TYPE' => 'LISTS' ,   'DEFAULT' => '');
103         $option['env_delete']=  array('NAME' =>'env_delete' ,  'TYPE' => 'LISTS' ,   'DEFAULT' => '');
104         $option['env_keep']=  array('NAME' =>'env_keep' ,  'TYPE' => 'LISTS' ,   'DEFAULT' => '');
105         ksort($option);
106         $this->options = $option;
108         $this->load_options();
109     }
112     private function load_options()
113     {
115         /****
116           Parse given sudoOption attributes 
117          ****/
118         $this->sudoOption = array();
119         if(isset($this->attrs['sudoOption'])){
120             for($i = 0 ; $i < $this->attrs['sudoOption']['count']; $i++){
122                 /****
123                   Detect attribute name/value/negation
124                  ****/
125                 $opt = $this->attrs['sudoOption'][$i];
127                 /* Get negation */ 
128                 $negation = FALSE;
129                 if(preg_match("/^!/",$opt)){
130                     $negation = TRUE; 
131                     $opt = preg_replace("/^!/","",$opt);
132                 }
134                 /* Get value / name*/
135                 $value    = "";
136                 if(preg_match("/=/",$opt)){
137                     $value  = preg_replace("/^[^=]*+=/","",$opt);
138                     $opt    = preg_replace("/=.*$/","",$opt);
139                 }
141                 /* Special chars are escaped, remove escape char now.
142                    \\ => \
143                    \: => :
144                    \, => ,
145                    \= => = 
146                  */
147                 $value = $this->unescape_command($value);
149                 /* Check if the given value is part of our options list.
150                    If it is not, add it as type STRING and display a warning.  
151                  */
152                 if(!isset($this->options[$opt])){
153                     $this->options[$opt]=array('NAME'=>$opt,'TYPE'=>'STRING','DEFAULT' => '');
154                     msg_dialog::display(_("Unknown option"),
155                             sprintf(_("The Sudo option '%s' is invalid!"),
156                                 $opt),WARNING_DIALOG);
157                 }
159                 /* Create internal sudoOption object */
160                 $option = array();
161                 $option['NAME']   = $opt;
162                 $option['VALUE']  = $value;
163                 $option['NEGATE'] = $negation;
165                 /*  Special handling for mixed flag types. 
166                     Some attributes like (BOOL_INTEGER) can be TRUE/FALSE and INTEGER.
167                     This means, if the value is empty it is BOOL and $negation defines its boolean value.
168                  */
169                 if(in_array($this->options[$opt]['TYPE'],array("BOOL_INTEGER","STRING_BOOL"))){
170                     if(empty($value)){
171                         $option['NEGATE'] = FALSE;
172                         if($negation){
173                             $option['VALUE'] = "FALSE";
174                         }else{
175                             $option['VALUE'] = "TRUE";
176                         }
177                     }
178                 }
180                 /* Special handling for BOOLEAN values */
181                 if(in_array($this->options[$opt]['TYPE'],array("BOOLEAN"))){
182                     $option['NEGATE'] = FALSE;
183                     if($negation){
184                         $option['VALUE'] = "FALSE";
185                     }else{
186                         $option['VALUE'] = "TRUE";
187                     }
188                 }
190                 /* Append values */
191                 $this->sudoOption[$opt][] = $option;
192             }
193         }
194     }
198     /*! \brief  Create HTML output for this plugin 
199       @return String  HTML output for this plugin.
200      */
201     function execute()
202     {
203         /* Call parent execute */
204         plugin::execute();
206         /*****
207           Handle Posts 
208          *****/
209         if($this->acl_is_writeable("")){
211             foreach($_POST as $name => $value){
212     
213                 $value = get_post($name);
215                 if(preg_match("/^negOption_/",$name)){
217                     $opt = preg_replace("/^negOption_(.*)_[0-9]*$/","\\1", $name);
218                     $id  = preg_replace("/^negOption_.*_([0-9])*$/","\\1", $name);
220                     if(isset($this->sudoOption[$opt][$id])){
221                         $val = $this->sudoOption[$opt][$id]["VALUE"];
223                         /*****
224                           Negate STRING_BOOL && BOOL_INTEGER
225                          *****/
226                         if(in_array($this->options[$opt]['TYPE'],array('STRING_BOOL','BOOL_INTEGER'))){
227                             if(in_array($val, array("TRUE","FALSE"))){
228                                 if($val == "TRUE"){
229                                     $this->sudoOption[$opt][$id]["VALUE"] = "FALSE";
230                                 }else{
231                                     $this->sudoOption[$opt][$id]["VALUE"] = "TRUE";
232                                 }
233                             }else{
234                                 $this->sudoOption[$opt][$id]['NEGATE'] = !$this->sudoOption[$opt][$id]['NEGATE']; 
235                             }
236                         }
238                         /*****
239                           Negate STRING / INTEGER
240                          *****/
241                         if(in_array($this->options[$opt]['TYPE'],array('STRING','INTEGER','LISTS'))){
242                             $this->sudoOption[$opt][$id]['NEGATE'] = !$this->sudoOption[$opt][$id]['NEGATE']; 
243                         }
245                         /*****
246                           Negate BOOLEAN
247                          *****/
248                         if(in_array($this->options[$opt]['TYPE'],array('BOOLEAN'))){
249                             if($val == "TRUE"){
250                                 $this->sudoOption[$opt][$id]["VALUE"] = "FALSE";
251                             }else{
252                                 $this->sudoOption[$opt][$id]["VALUE"] = "TRUE";
253                             }
254                         }
255                     }
256                     break;
257                 }
259                 /*****
260                   Remove options
261                  *****/
262                 if(preg_match("/^delOption/",$name)){
263                     $opt = preg_replace("/^delOption_/","",$name);
264                     $opt = preg_replace("/_[^_]*$/","",$opt);
265                     $id  = preg_replace("/^.*_([0-9])*$/","\\1",$opt);
266                     $opt = preg_replace("/_[0-9]*$/","",$opt);
268                     if(isset($this->sudoOption[$opt][$id])){
269                         unset($this->sudoOption[$opt][$id]);
270                     }
271                     if(!count($this->sudoOption[$opt])){
272                         unset($this->sudoOption[$opt]);
273                     }
274                     break;
275                 }
276             }
277         }
280         $smarty = get_smarty();
281         $smarty->assign("ACL",$this->getacl(""));
282         $smarty->assign("map",  
283                     set_post(    array(
284                     "STRING" => _("string"), "BOOLEAN" => _("boolean"),
285                     "INTEGER" => _("integer") , "BOOL_INTEGER" => _("integer")."-"._("boolean") ,
286                     "STRING_BOOL" => _("string")."-"._("boolean"),"LISTS" => _("list"))));
287         $smarty->assign("sudoOption",$this->prepare_for_html($this->sudoOption));
288         $smarty->assign("options",$this->options);
289         return($smarty->fetch(get_template_path('options.tpl', TRUE)));
290     }
293     /*! \brief  Prepare options array to be used in HTML.
294       @param  Array   The options array ($this->sudoOption) 
295       @return Array   HTML ready sudoOption. Can now be used in smarty templates
296      */
297     function prepare_for_html($a_options)
298     {
299         foreach($a_options as $name => $options){
300             foreach($options as $key => $option){
301                 $a_options[set_post($name)][$key]['VALUE'] = set_post($option['VALUE']);
302             }
303         }
304         return($a_options);
305     }
308     /*! \brief  Removes this plugin 
309      */
310     function remove_from_parent()
311     {
312     }
315     /*! \brief  Saves all relevant HTML post values for this plugin 
316      */
317     function save_object()
318     {
319         if($this->acl_is_writeable("")){
320             plugin::save_object();
322             if(isset($_POST['add_option']) && isset($_POST['option'])){
323                 $opt = get_post("option");
325                 /* Append attribute only once, lists are handled below */
326                 if(isset($this->options[$opt])){
327                     $type = $this->options[$opt]['TYPE'];
328                     $val  = $this->options[$opt]['DEFAULT'];
329                     $option = array("NAME" => $opt, "VALUE" => $val , "NEGATE" => FALSE);
330                     $this->sudoOption[$opt][] = $option;
331                 }
332             }
334             foreach($this->sudoOption as $name => $opts){
335                 foreach($opts as $id => $opt){
337                     /****
338                       Get posted value for BOOLEAN
339                      ****/
340                     if(in_array($this->options[$name]['TYPE'],array("BOOLEAN"))){
341                         if(isset($_POST['option_value__'.$name.'_'.$id])){
342                             $this->sudoOption[$name][$id]["VALUE"] = get_post('option_value__'.$name.'_'.$id);
343                         }
344                     }
346                     /****
347                       Get posted value for STRING / INTEGER
348                      ****/
349                     if(in_array($this->options[$name]['TYPE'],array("STRING","INTEGER"))){
350                         if(isset($_POST['option_value__'.$name.'_'.$id])){
351                             $this->sudoOption[$name][$id]["VALUE"] = get_post('option_value__'.$name.'_'.$id);
352                         }
353                     }
355                     /****
356                       Get posted value for STRING_BOOL / BOOL_INTEGER
357                      ****/
358                     if(in_array($this->options[$name]['TYPE'],array("BOOL_INTEGER","STRING_BOOL"))){
359                         if(isset($_POST['option_selection__'.$name.'_'.$id])){
360                             $sel = get_post('option_selection__'.$name.'_'.$id);
361                             $val = "";
362                             if(isset($_POST['option_value__'.$name.'_'.$id])){
363                                 $val = get_post('option_value__'.$name.'_'.$id);
364                             }
366                             if($sel == "FALSE" || $sel == "TRUE"){
367                                 $this->sudoOption[$name][$id]['VALUE'] = $sel;
368                                 $this->sudoOption[$name][$id]['NEGATE'] = FALSE;
369                             }else{
370                                 $this->sudoOption[$name][$id]['VALUE'] = $val;
371                             }
372                         }
373                     }
375                     /****
376                       Get posted value for LISTS
377                      ****/
378                     if(in_array($this->options[$name]['TYPE'],array("LISTS"))){
379                         foreach($this->sudoOption[$name] as $entry_key => $entry){
380                             if(isset($_POST['list_value__'.$name.'_'.$entry_key])){
381                                 $val = get_post('list_value__'.$name.'_'.$entry_key);
382                                 $this->sudoOption[$name][$entry_key]["VALUE"] = $val;
383                             }
384                         } 
385                     }
386                 }
387             }
388         }
389     }
392     /*! \brief  Save changes to ldap 
393      */
394     function save()
395     {
396         plugin::save(); 
398         $this->attrs['sudoOption'] = array();
399         foreach($this->sudoOption as $name => $opts){
400             foreach($opts as $id => $opt){
402                 $type   = $this->options[$name]['TYPE'];
403                 $neg    = $opt['NEGATE'];
404                 $value  = $opt['VALUE'];
405                 $option = "";
407                 /* Escape special chars */
408                 $value = $this->escape_command($value);
410                 /****
411                   Save LISTS 
412                  ****/
413                 if($type=="LISTS"){
414                     if($value == ""){
415                         $option = $name;
416                     }else{
417                         $option = $name."=".$value;
418                     }
419                     if($neg){
420                         $option = "!".$option;
421                     }
422                 }
424                 /****
425                   Save BOOLEAN
426                  ****/
427                 if(in_array($type,array("BOOLEAN"))){ 
428                     $option = $name;
429                     if($value == "FALSE"){
430                         $option = "!".$option;
431                     }
432                 }
434                 /****
435                   Save STRING / INTEGER
436                  ****/
437                 if(in_array($type,array("STRING","INTEGER"))){ 
438                     if($value != ""){
439                         $option = $name."=".$value;
440                     }else{
441                         $option = $name; 
442                     }
443                     if($neg){
444                         $option = "!".$option;
445                     }
446                 }
448                 /****
449                   Save STRING_BOOL / BOOL_INTEGER
450                  ****/
451                 if(in_array($type,array("STRING_BOOL","BOOL_INTEGER"))){
452                     if($value == "FALSE"){
453                         $option = "!".$name;
454                     }elseif($value == "TRUE"){
455                         $option = $name;
456                     }else{
457                         if($value != ""){
458                             $option = $name."=".$value;
459                         }else{
460                             $option = $name; 
461                         }
462                         if($neg){
463                             $option = "!".$option;
464                         }
465                     }
466                 }
468                 $this->attrs['sudoOption'][] = $option;
469             }
470         }
471         $this->cleanup();
472         $ldap = $this->config->get_ldap_link();
473         $ldap->cd($this->dn);
474         $ldap->modify($this->attrs);;
475     }
478     /*! \brief  Checks input validity
479      */
480     function check()
481     {
482         $message = plugin::check();
484         foreach($this->sudoOption as $name => $options){
485             foreach($options as $id => $option){
486                 switch($this->options[$name]['TYPE']){
488                     /* Check for a valid integer value */
489                     case 'INTEGER' : 
490                         {
491                             if(!preg_match("/^[0-9]*$/",$option['VALUE'])){
492                                 $message[] = msgPool::invalid($name,$option['VALUE'],"/[0-9]/");
493                             }
494                         } break;
495                 }
496             }
497         }
498         return ($message);
499     }
502     /*! \brief  This function will be called if an object gets copied.
503       This function adapts attributes from the source object.
504       @param  Array The source object.
505      */
506     function PrepareForCopyPaste($source)
507     {
508         plugin::PrepareForCopyPaste($source);
509         if(isset($source['sudoOption'])){
510             $this->attrs['sudoOption'] = $source['sudoOption'];
511             $this->load_options();
512         }
513     }
516     /*!  \brief   Escape special chars in function parameters.
517       @param   String the string to that must be escaped.
518      */
519     private function escape_command($str)
520     {
521         /* Check if given value is a command (/[a-z]/ ..)
522          */
523         if(preg_match("/^\//",$str)){
524             $cmd = preg_replace("/^([^ ]*).*$/","\\1",$str);
525             $val = preg_replace("/^[^ ]*(.*)$/","\\1",$str);
526             $str = $cmd.addcslashes($val,":.,\\");
527         }
528         return($str);
529     }
532     /*! \brief  Add ACL object
533       @return Returns the ACL object.
534      */
535     static function plInfo()
536     {
537         return (array(  
538                     "plShortName" => _("Options"),
539                     "plDescription" => _("Sudo options"),
540                     "plSelfModify"  => FALSE,
541                     "plDepends"     => array(),
542                     "plPriority"    => 2,
543                     "plSection"     => array("administration"),
544                     "plCategory"    => array("sudo"),
545                     "plProvidedAcls"    => array(
546                         "sudoOption"  => _("Sudo options") 
547                         )
548                     ));
549     }
551     /*!  \brief   Unescape special chars in function parameters.
552       @param   String the string to that must be unescaped.
553      */
554     private function unescape_command($str)
555     {
556         /* Check if given value is a command (/[a-z]/ ..)
557          */
558         if(preg_match("/^\//",$str)){
559             $cmd = preg_replace("/^([^ ]*).*$/","\\1",$str);
560             $val = preg_replace("/^[^ ]*(.*)$/","\\1",$str);
561             $val = preg_replace(array("/\\\\\\\\/","/\\\\,/","/\\\\:/","/\\\\=/"),
562                     array("\\",",",":","="),$val);
563             $str = $cmd.$val;
564         }
565         return($str);
566     }
568 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
569 ?>