Code

Updated config and pluglist to supprt the new shortCut menu
[gosa.git] / gosa-core / include / class_config.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$$
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 Configuration class
24  *  \ingroup coreclasses
25  *
26  * The configuration class, responsible for parsing and querying the
27  * gosa configuration file.
28  */
30 class config  {
32   /* XML parser */
33   var $parser;
34   var $config_found= FALSE;
35   var $tags= array();
36   var $level= 0;
37   var $gpc= 0;
38   var $section= "";
39   var $currentLocation= "";
41   /*! \brief Store configuration for current location */
42   var $current= array(); 
44   /* Link to LDAP-server */
45   var $ldap= NULL;
46   var $referrals= array();
48   /* \brief Configuration data
49    *
50    * - $data['SERVERS'] contains server informations.
51    * */
52   var $data= array( 'TABS' => array(), 'LOCATIONS' => array(), 'SERVERS' => array(),
53       'MAIN' => array(),
54       'MENU' => array(), 'SERVICE' => array());
55   var $basedir= "";
56   var $config_version ="NOT SET";
58   /* Keep a copy of the current deparment list */
59   var $departments= array();
60   var $idepartments= array();
61   var $adepartments= array();
62   var $tdepartments= array();
63   var $department_info= array();
64   var $filename = "";
65   var $last_modified = 0;
67     private $jsonRPChandle = NULL; 
69   public $configRegistry = NULL;
71   /*! \brief Class constructor of the config class
72    *  
73    *  \param string 'filename' path to the configuration file
74    *  \param string 'basedir' base directory
75    *
76    * */
77   function config($filename, $basedir= "")
78   {
79     $this->parser = xml_parser_create();
80     $this->basedir= $basedir;
82     xml_set_object($this->parser, $this);
83     xml_set_element_handler($this->parser, "tag_open", "tag_close");
85     /* Parse config file directly? */
86     if ($filename != ""){
87       $this->parse($filename);
88     }
90     // Load configuration registry
91     $this->configRegistry = new configRegistry($this);
92   }
95   /*! \brief Check and reload the configuration
96    * 
97    * This function checks if the configuration has changed, since it was
98    * read the last time and reloads it. It uses the file mtime to check
99    * weither the file changed or not.
100    *
101    * */ 
102   function check_and_reload()
103   {
104     global $ui;
106     /* Check if class_location.inc has changed, this is the case 
107         if we have installed or removed plugins. 
108      */
109     if(session::global_is_set("class_location.inc:timestamp")){
110       $tmp = stat("../include/class_location.inc");
111       if($tmp['mtime'] != session::global_get("class_location.inc:timestamp")){
112         session::global_un_set("plist");
113       }
114     }
115     $tmp = stat("../include/class_location.inc");
116     session::global_set("class_location.inc:timestamp",$tmp['mtime']);
118     if($this->filename != "" && filemtime($this->filename) != $this->last_modified){
120       $this->config_found= FALSE;
121       $this->tags= array();
122       $this->level= 0;
123       $this->gpc= 0;
124       $this->section= "";
125       $this->currentLocation= "";
127       $this->parser = xml_parser_create();
128       xml_set_object($this->parser, $this);
129       xml_set_element_handler($this->parser, "tag_open", "tag_close");
130       $this->parse($this->filename);
131       $this->set_current($this->current['NAME']);
132     }
133   }  
136   /*! \brief Parse the given configuration file 
137    *
138    *  Parses the configuration file and displays errors if there
139    *  is something wrong with it.
140    *
141    *  \param string 'filename' The filename of the configuration file.
142    * */
144   function parse($filename)
145   {
146     $this->data = array(
147         "TABS"      => array(), 
148         "LOCATIONS" => array(), 
149         "MAIN"      => array(), 
150         "MENU"      => array(), 
151         "SERVICE"   => array());
153     $this->last_modified = filemtime($filename);
154     $this->filename = $filename;
155     $fh= fopen($filename, "r"); 
156     $xmldata= fread($fh, 100000);
157     fclose($fh);
158     if(!xml_parse($this->parser, chop($xmldata))){
159       $msg = sprintf(_("XML error in gosa.conf: %s at line %d"),
160             bold(xml_error_string(xml_get_error_code($this->parser))),
161             bold(xml_get_current_line_number($this->parser)));
162       msg_dialog::display(_("Configuration error"), $msg, FATAL_ERROR_DIALOG);
163       exit;
164     }
165   }
167   function tag_open($parser, $tag, $attrs)
168   {
169     /* Save last and current tag for reference */
170     $this->tags[$this->level]= $tag;
171     $this->level++;
173     /* Trigger on CONF section */
174     if ($tag == 'CONF'){
175       $this->config_found= TRUE;
176       if(isset($attrs['CONFIGVERSION'])){
177         $this->config_version = $attrs['CONFIGVERSION'];
178       }
179     }
181     /* Return if we're not in config section */
182     if (!$this->config_found){
183       return;
184     }
186     /* yes/no to true/false and upper case TRUE to true and so on*/
187     foreach($attrs as $name => $value){
188       if(preg_match("/^(true|yes)$/i",$value)){
189         $attrs[$name] = "true";
190       }elseif(preg_match("/^(false|no)$/i",$value)){
191         $attrs[$name] = "false";
192       } 
193     }
195     /* Look through attributes */
196     switch ($this->tags[$this->level-1]){
199       /* Handle tab section */
200       case 'TAB':       $name= $this->tags[$this->level-2];
202                   /* Create new array? */
203                   if (!isset($this->data['TABS'][$name])){
204                     $this->data['TABS'][$name]= array();
205                   }
207                   /* Add elements */
208                   $this->data['TABS'][$name][]= $attrs;
209                   break;
211                   /* Handle location */
212       case 'LOCATION':
213                   if ($this->tags[$this->level-2] == 'MAIN'){
214                     $name= $attrs['NAME'];
215                     $name = preg_replace("/[<>\"']/","",$name);
216                     $attrs['NAME'] = $name;
217                     $this->currentLocation= $name;
219                     /* Add location elements */
220                     $this->data['LOCATIONS'][$name]= $attrs;
221                   }
222                   break;
224                   /* Handle referral tags */
225       case 'REFERRAL':
226                   if ($this->tags[$this->level-2] == 'LOCATION'){
227                     $url= $attrs['URI'];
228                     $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
230                     /* Add location elements */
231                     if (!isset($this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'])){
232                       $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL']= array();
233                     }
235                     $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'][$server]= $attrs;
236                   }
237                   break;
239                   /* Load main parameters */
240       case 'MAIN':
241                   $this->data['MAIN']= array_merge ($this->data['MAIN'], $attrs);
242                   break;
244                   /* Load menu */
245       case 'SECTION':
246                   if ($this->tags[$this->level-2] == 'MENU'){
247                     $this->section= $attrs['NAME'];
248                     $this->data['MENU'][$this->section]= array(); ;
249                   }
250                   break;
252       case 'PATHMENU':
253                   $this->data['PATHMENU']= array(); ;
254                   break;
256       case 'SHORTCUTMENU':
257                   $this->data['SHORTCUTMENU']= array(); ;
258                   break;
260                   /* Inser plugins */
261       case 'PLUGIN':
262                   if ($this->tags[$this->level-3] == 'MENU' &&
263                       $this->tags[$this->level-2] == 'SECTION'){
265                     $this->data['MENU'][$this->section][$this->gpc++]= $attrs;
266                   }
267                   if ($this->tags[$this->level-2] == 'PATHMENU'){
268                     $this->data['PATHMENU'][$this->gpc++]= $attrs;
269                   }
270                   if ($this->tags[$this->level-2] == 'SHORTCUTMENU'){
271                     $this->data['SHORTCUTMENU'][$this->gpc++]= $attrs;
272                   }
273                   if ($this->tags[$this->level-2] == 'SERVICEMENU'){
274                     $this->data['SERVICE'][$attrs['CLASS']]= $attrs;
275                   }
276                   break;
277     }
278   }
280   function tag_close($parser, $tag)
281   {
282     /* Close config section */
283     if ($tag == 'CONF'){
284       $this->config_found= FALSE;
285     }
286     $this->level--;
287   }
290   function get_credentials($creds)
291   {
292     if (isset($_SERVER['HTTP_GOSA_KEY'])){
293       if (!session::global_is_set('HTTP_GOSA_KEY_CACHE')){
294         session::global_set('HTTP_GOSA_KEY_CACHE',array());
295       }
296       $cache = session::global_get('HTTP_GOSA_KEY_CACHE');
297       if(!isset($cache[$creds])){
298         $cache[$creds] = cred_decrypt($creds, $_SERVER['HTTP_GOSA_KEY']);
299         session::global_set('HTTP_GOSA_KEY_CACHE',$cache);
300       }
301       return ($cache[$creds]);
302     }
303     return ($creds);
304   }
307   function getRpcHandle()
308   {
309       // Create jsonRPC handle on demand.
310       if(!$this->jsonRPChandle){
311           $this->jsonRPChandle = new jsonRPC($this);
312       }
313       return($this->jsonRPChandle);
314   }
315     
317   /*! \brief Get a LDAP link object
318    *
319    * This function can be used to get an ldap object, which in turn can
320    * be used to query the LDAP. See the LDAP class for more information
321    * on how to use it.
322    *
323    * Example usage:
324    * \code
325    * $ldap = $this->config->get_ldap_link();
326    * \endcode
327    *
328    * \param boolean sizelimit Weither to impose a sizelimit on the LDAP object or not.
329    * Defaults to false. If set to true, the size limit in the configuration
330    * file will be used to set the option LDAP_OPT_SIZELIMIT.
331    * \return ldapMultiplexer object
332    */
333   function get_ldap_link($sizelimit= FALSE)
334   {
335     if($this->ldap === NULL || !is_resource($this->ldap->cid)){
337       /* Build new connection */
338       $this->ldap= ldap_init ($this->current['SERVER'], $this->current['BASE'],
339           $this->current['ADMINDN'], $this->get_credentials($this->current['ADMINPASSWORD']));
341       /* Check for connection */
342       if (is_null($this->ldap) || (is_int($this->ldap) && $this->ldap == 0)){
343         $smarty= get_smarty();
344         msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP!"), FATAL_ERROR_DIALOG);
345         exit();
346       }
348       /* Move referrals */
349       if (!isset($this->current['REFERRAL'])){
350         $this->ldap->referrals= array();
351       } else {
352         $this->ldap->referrals= $this->current['REFERRAL'];
353       }
355       if (!session::global_is_set('size_limit')){
356         session::global_set('size_limit', $this->get_cfg_value('core', 'ldapSizelimit'));
357         session::global_set('size_ignore', $this->boolValueIsTrue('core', 'ldapSizeIgnore'));
358       }
359     }
361     $obj  = new ldapMultiplexer($this->ldap);
362     if ($sizelimit){
363       $obj->set_size_limit(session::global_get('size_limit'));
364     } else {
365       $obj->set_size_limit(0);
366     }
367     return($obj);
368   }
370   /*! \brief Set the current location
371    *  
372    *  \param string name the name of the location
373    */
374   function set_current($name)
375   {
376     $this->current= $this->data['LOCATIONS'][$name];
378     if (isset($this->current['INITIAL_BASE'])){
379       session::global_set('CurrentMainBase',$this->current['INITIAL_BASE']);
380     }
381   
382     /* Sort referrals, if present */
383     if (isset ($this->current['REFERRAL'])){
384       $bases= array();
385       $servers= array();
386       foreach ($this->current['REFERRAL'] as $ref){
387         $server= preg_replace('%^(.*://[^/]+)/.*$%', '\\1', $ref['URI']);
388         $base= preg_replace('%^.*://[^/]+/(.*)$%', '\\1', $ref['URI']);
389         $bases[$base]= strlen($base);
390         $servers[$base]= $server;
391       }
392       asort($bases);
393       reset($bases);
394     }
396     /* SERVER not defined? Load the one with the shortest base */
397     if (!isset($this->current['SERVER'])){
398       $this->current['SERVER']= $servers[key($bases)];
399     }
401     /* BASE not defined? Load the one with the shortest base */
402     if (!isset($this->current['BASE'])){
403       $this->current['BASE']= key($bases);
404     }
406     /* Convert BASE to have escaped special characters */
407     $this->current['BASE']= @LDAP::convert($this->current['BASE']);
409     /* Parse LDAP referral informations */
410     if (!isset($this->current['ADMINDN']) || !isset($this->current['ADMINPASSWORD'])){
411       $url= $this->current['SERVER'];
412       $referral= $this->current['REFERRAL'][$url];
413       $this->current['ADMINDN']= $referral['ADMINDN'];
414       $this->current['ADMINPASSWORD']= $referral['ADMINPASSWORD'];
415     }
417     /* Load server informations */
418     $this->load_servers();
419   }
422   /*! \brief Load server information from config/LDAP
423    *
424    *  This function searches the LDAP for servers (e.g. goImapServer, goMailServer etc.)
425    *  and stores information about them $this->data['SERVERS']. In the case of mailservers
426    *  the main section of the configuration file is searched, too.
427    */
428   function load_servers ()
429   {
430     /* Only perform actions if current is set */
431     if ($this->current === NULL){
432       return;
433     }
435     /* Fill imap servers */
436     $ldap= $this->get_ldap_link();
437     $ldap->cd ($this->current['BASE']);
439     /* Search mailMethod konfiguration in main section too 
440      */
441     $tmp = $this->get_cfg_value("core","mailMethod");
442     if ($tmp){
443       $ldap->search ("(objectClass=goMailServer)", array('cn'));
444       $this->data['SERVERS']['IMAP']= array();
445       while ($attrs= $ldap->fetch()){
446         $name= $attrs['cn'][0];
447         $this->data['SERVERS']['IMAP'][$name]= 
448           array( 
449               "server_dn"   => $attrs['dn'],
450               "connect"     => "",
451               "admin"       => "",
452               "password"    => "",
453               "sieve_server"=> "",
454               "sieve_option"=> "",
455               "sieve_port"  => "");
456       }
457     } else {
458       $ldap->search ("(&(objectClass=goImapServer)(goImapSieveServer=*))", 
459                     array('goImapName', 'goImapConnect', 'goImapAdmin', 'goImapPassword',
460             'goImapSieveServer', 'goImapSievePort'));
462       $this->data['SERVERS']['IMAP']= array();
464       while ($attrs= $ldap->fetch()){
466         /* Check if the given goImapSieveServer is in the new style "{cn:port/option}"
467            or the old style just "cn".
468          */
469         if(preg_match("/\{/",$attrs['goImapSieveServer'][0])){
470           $sieve_server = preg_replace("/^\{([^:]*).*$/","\\1",$attrs['goImapSieveServer'][0]);
471           $sieve_option = preg_replace("/^[^:]*[^\/]*+\/(.*)\}$/","\\1",$attrs['goImapSieveServer'][0]);
472         }else{
473           $sieve_server = $attrs['goImapSieveServer'][0];
474           $sieve_option = "";
475         }
477         $pwd            = $attrs['goImapPassword'][0];
478         $imap_admin     = $attrs['goImapAdmin'][0];
479         $imap_connect   = $attrs['goImapConnect'][0];
480         $imap_server    = $attrs['goImapName'][0];
481         $sieve_port     = $attrs['goImapSievePort'][0];
482         
483         $this->data['SERVERS']['IMAP'][$imap_server]= 
484             array( 
485             "server_dn"   => $attrs['dn'],
486             "connect"     => $imap_connect,
487             "admin"       => $imap_admin,
488             "password"    => $pwd,
489             "sieve_server"=> $sieve_server,
490             "sieve_option"=> $sieve_option,
491             "sieve_port"  => $sieve_port);
492       }
493     }
495     /* Get kerberos server. FIXME: only one is supported currently */
496     $ldap->cd ($this->current['BASE']);
497     $ldap->search ("(&(goKrbRealm=*)(goKrbAdmin=*)(objectClass=goKrbServer))");
498     if ($ldap->count()){
499       $attrs= $ldap->fetch();
500       $this->data['SERVERS']['KERBEROS']= array( 'SERVER' => $attrs['cn'][0],
501           'REALM' => $attrs['goKrbRealm'][0],
502           'ADMIN' => $attrs['goKrbAdmin'][0]);
503     }
505     /* Get cups server. FIXME: only one is supported currently */
506     $ldap->cd ($this->current['BASE']);
507     $ldap->search ("(objectClass=goCupsServer)");
508     if ($ldap->count()){
509       $attrs= $ldap->fetch();
510       $this->data['SERVERS']['CUPS']= $attrs['cn'][0];  
511     }
513     /* Get fax server. FIXME: only one is supported currently */
514     $ldap->cd ($this->current['BASE']);
515     $ldap->search ("(objectClass=goFaxServer)");
516     if ($ldap->count()){
517       $attrs= $ldap->fetch();
518       $this->data['SERVERS']['FAX']= array( 'SERVER' => $attrs['cn'][0],
519           'LOGIN' => $attrs['goFaxAdmin'][0],
520           'PASSWORD' => $attrs['goFaxPassword'][0]);
521     }
524     /* Get asterisk servers */
525     $ldap->cd ($this->current['BASE']);
526     $ldap->search ("(objectClass=goFonServer)");
527     $this->data['SERVERS']['FON']= array();
528     if ($ldap->count()){
529       while ($attrs= $ldap->fetch()){
531         /* Add 0 entry for development */
532         if(count($this->data['SERVERS']['FON']) == 0){
533           $this->data['SERVERS']['FON'][0]= array(
534               'DN'      => $attrs['dn'],
535               'SERVER'  => $attrs['cn'][0],
536               'LOGIN'   => $attrs['goFonAdmin'][0],
537               'PASSWORD'  => $attrs['goFonPassword'][0],
538               'DB'    => "gophone",
539               'SIP_TABLE'   => "sip_users",
540               'EXT_TABLE'   => "extensions",
541               'VOICE_TABLE' => "voicemail_users",
542               'QUEUE_TABLE' => "queues",
543               'QUEUE_MEMBER_TABLE'  => "queue_members");
544         }
546         /* Add entry with 'dn' as index */
547         $this->data['SERVERS']['FON'][$attrs['dn']]= array(
548             'DN'      => $attrs['dn'],
549             'SERVER'  => $attrs['cn'][0],
550             'LOGIN'   => $attrs['goFonAdmin'][0],
551             'PASSWORD'  => $attrs['goFonPassword'][0],
552             'DB'    => "gophone",
553             'SIP_TABLE'   => "sip_users",
554             'EXT_TABLE'   => "extensions",
555             'VOICE_TABLE' => "voicemail_users",
556             'QUEUE_TABLE' => "queues",
557             'QUEUE_MEMBER_TABLE'  => "queue_members");
558       }
559     }
562     /* Get glpi server */
563     $ldap->cd ($this->current['BASE']);
564     $ldap->search ("(&(objectClass=goGlpiServer)(cn=*)(goGlpiAdmin=*)(goGlpiDatabase=*))",array("cn","goGlpiPassword","goGlpiAdmin","goGlpiDatabase"));
565     if ($ldap->count()){
566       $attrs= $ldap->fetch();
567       if(!isset($attrs['goGlpiPassword'])){
568         $attrs['goGlpiPassword'][0] ="";
569       }
570       $this->data['SERVERS']['GLPI']= array( 
571           'SERVER'      => $attrs['cn'][0],
572           'LOGIN'       => $attrs['goGlpiAdmin'][0],
573           'PASSWORD'    => $attrs['goGlpiPassword'][0],
574           'DB'          => $attrs['goGlpiDatabase'][0]);
575     }
578     /* Get logdb server */
579     $ldap->cd ($this->current['BASE']);
580     $ldap->search ("(objectClass=goLogDBServer)");
581     if ($ldap->count()){
582       $attrs= $ldap->fetch();
583       if(!isset($attrs['gosaLogDB'][0])){
584         $attrs['gosaLogDB'][0] = "gomon";
585       }
586       $this->data['SERVERS']['LOG']= array( 'SERVER' => $attrs['cn'][0],
587           'LOGIN' => $attrs['goLogAdmin'][0],
588           'DB' => $attrs['gosaLogDB'][0],
589           'PASSWORD' => $attrs['goLogPassword'][0]);
590     }
593     /* GOsa logging databases */
594     $ldap->cd ($this->current['BASE']);
595     $ldap->search ("(objectClass=gosaLogServer)");
596     if ($ldap->count()){
597       while($attrs= $ldap->fetch()){
598       $this->data['SERVERS']['LOGGING'][$attrs['cn'][0]]= 
599           array(
600           'DN'    => $attrs['dn'],
601           'USER'  => $attrs['goLogDBUser'][0],
602           'DB'    => $attrs['goLogDB'][0],
603           'PWD'   => $attrs['goLogDBPassword'][0]);
604       }
605     }
608     /* Get NFS server lists */
609     $tmp= array("default");
610     $tmp2= array("default");
611     $ldap->cd ($this->current['BASE']);
612     $ldap->search ("(&(objectClass=goShareServer)(goExportEntry=*))");
613     while ($attrs= $ldap->fetch()){
614       for ($i= 0; $i<$attrs["goExportEntry"]["count"]; $i++){
615         if(preg_match('/^[^|]+\|[^|]+\|NFS\|.*$/', $attrs["goExportEntry"][$i])){
616           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
617           $tmp[]= $attrs["cn"][0].":$path";
618         }
619         if(preg_match('/^[^|]+\|[^|]+\|NBD\|.*$/', $attrs["goExportEntry"][$i])){
620           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
621           $tmp2[]= $attrs["cn"][0].":$path";
622         }
623       }
624     }
625     $this->data['SERVERS']['NFS']= $tmp;
626     $this->data['SERVERS']['NBD']= $tmp2;
628     /* Load Terminalservers */
629     $ldap->cd ($this->current['BASE']);
630     $ldap->search ("(objectClass=goTerminalServer)",array("cn","gotoSessionType"));
631     $this->data['SERVERS']['TERMINAL']= array();
632     $this->data['SERVERS']['TERMINAL'][]= "default";
633     $this->data['SERVERS']['TERMINAL_SESSION_TYPES'] = array();
636     while ($attrs= $ldap->fetch()){
637       $this->data['SERVERS']['TERMINAL'][]= $attrs["cn"][0];
638       if(isset( $attrs["gotoSessionType"]['count'])){
639         for($i =0 ; $i < $attrs["gotoSessionType"]['count'] ; $i++){
640           $this->data['SERVERS']['TERMINAL_SESSION_TYPES'][$attrs["cn"][0]][] = $attrs["gotoSessionType"][$i]; 
641         }
642       }
643     }
645     /* Ldap Server 
646      */
647     $this->data['SERVERS']['LDAP']= array();
648     $ldap->cd ($this->current['BASE']);
649     $ldap->search ("(&(objectClass=goLdapServer)(goLdapBase=*))");
650     while ($attrs= $ldap->fetch()){
651       $this->data['SERVERS']['LDAP'][$attrs['dn']] = $attrs;
652     }
654     /* Get misc server lists */
655     $this->data['SERVERS']['SYSLOG']= array("default");
656     $this->data['SERVERS']['NTP']= array("default");
657     $ldap->cd ($this->current['BASE']);
658     $ldap->search ("(objectClass=goNtpServer)");
659     while ($attrs= $ldap->fetch()){
660       $this->data['SERVERS']['NTP'][]= $attrs["cn"][0];
661     }
662     $ldap->cd ($this->current['BASE']);
663     $ldap->search ("(objectClass=goSyslogServer)");
664     while ($attrs= $ldap->fetch()){
665       $this->data['SERVERS']['SYSLOG'][]= $attrs["cn"][0];
666     }
668     /* Get samba servers from LDAP, in case of samba3 */
669     $this->data['SERVERS']['SAMBA']= array();
670     $ldap->cd ($this->current['BASE']);
671     $ldap->search ("(objectClass=sambaDomain)");
672     while ($attrs= $ldap->fetch()){
673       $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]= array( "SID" =>"","RIDBASE" =>"");
674       if(isset($attrs["sambaSID"][0])){
675         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["SID"]  = $attrs["sambaSID"][0];
676       }
677       if(isset($attrs["sambaAlgorithmicRidBase"][0])){
678         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["RIDBASE"] = $attrs["sambaAlgorithmicRidBase"][0];
679       }
680     }
682     /* If no samba servers are found, look for configured sid/ridbase */
683     if (count($this->data['SERVERS']['SAMBA']) == 0){
684       if (!isset($this->current["SAMBASID"]) || !isset($this->current["SAMBARIDBASE"])){
685         msg_dialog::display(_("Configuration error"), _("sambaSID and/or sambaRidBase missing in the configuration!"), ERROR_DIALOG);
686       } else {
687         $this->data['SERVERS']['SAMBA']['DEFAULT']= array(
688             "SID" => $this->current["SAMBASID"],
689             "RIDBASE" => $this->current["SAMBARIDBASE"]);
690       }
691     }
692     
693   }
696   function get_departments($ignore_dn= "")
697   {
698     global $config;
700     /* Initialize result hash */
701     $result= array();
702     $administrative= array();
703     $result['/']= $this->current['BASE'];
704     $this->tdepartments= array();
706     /* Get all department types from department Management, to be able detect the department type.
707         -It is possible that differnty department types have the same name, 
708          in this case we have to mark the department name to be able to differentiate.
709           (e.g l=Name  or   o=Name)
710      */    
711     $types = departmentManagement::get_support_departments();
712     
713     /* Create a list of attributes to fetch */
714     $ldap_values = array("objectClass","gosaUnitTag", "description");
715     $filter = "";
716     foreach($types as $type){
717       $ldap_values[] = $type['ATTR'];
718       $filter .= "(objectClass=".$type['OC'].")";
719     }
720     $filter = "(&(objectClass=gosaDepartment)(|".$filter."))";
722     /* Get list of department objects */
723     $ldap= $this->get_ldap_link();
724     $ldap->cd ($this->current['BASE']);
725     $ldap->search ($filter, $ldap_values);
726     while ($attrs= $ldap->fetch()){
728       /* Detect department type */
729       $type_data = array();
730       foreach($types as $t => $data){
731         if(in_array($data['OC'],$attrs['objectClass'])){
732           $type_data = $data;
733           break;
734         }
735       }
737       /* Unknown department type -> skip */
738       if(!count($type_data)) continue;
740       $dn= $ldap->getDN();
741       $this->tdepartments[$dn]= "";
742       $this->department_info[$dn]= array("img" => $type_data['IMG'],
743                                          "description" => isset($attrs['description'][0])?$attrs['description'][0]:"",
744                                          "name" => $attrs[$type_data['ATTR']][0]);
746       /* Save administrative departments */
747       if (in_array_ics("gosaAdministrativeUnit", $attrs['objectClass']) &&
748           isset($attrs['gosaUnitTag'][0])){
749         $administrative[$dn]= $attrs['gosaUnitTag'][0];
750         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
751       }
752     
753       if (in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass']) &&
754           isset($attrs['gosaUnitTag'][0])){
755         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
756       }
757     
758       if ($dn == $ignore_dn){
759         continue;
760       }
761       $c_dn = convert_department_dn($dn)." (".$type_data['ATTR'].")";
763       /* Only assign non-root departments */
764       if ($dn != $result['/']){
765         $result[$c_dn]= $dn;
766       }
767     }
769     $this->adepartments= $administrative;
770     $this->departments= $result;
771   }
774   function make_idepartments($max_size= 28)
775   {
776     global $config;
777     $base = $config->current['BASE'];
778                 $qbase = preg_quote($base, '/');
779     $utags= isset($config->current['HONOURUNITTAGS']) && preg_match('/true/i', $config->current['HONOURUNITTAGS']);
781     $arr = array();
782     $ui= get_userinfo();
784     $this->idepartments= array();
786     /* Create multidimensional array, with all departments. */
787     foreach ($this->departments as $key => $val){
789       /* When using strict_units, filter non relevant parts */
790       if ($utags){
791         if ($ui->gosaUnitTag != '' && isset($this->tdepartments[$val]) &&
792             $this->tdepartments[$val] != $ui->gosaUnitTag){
794                                                 #TODO: link with strict*
795                                                 #continue;
796         }
797       }
799       /* Split dn into single department pieces */
800       $elements = array_reverse(explode(',',preg_replace("/$qbase$/",'',$val)));                
802       /* Add last ou element of current dn to our array */
803       $last = &$arr;
804       foreach($elements as $key => $ele){
806         /* skip empty */
807         if(empty($ele)) continue;
809         /* Extract department name */           
810         $elestr = trim(preg_replace('/^[^=]*+=/','', $ele),',');
811         $nameA  = trim(preg_replace('/=.*$/','', $ele),',');
812         if($nameA != 'ou'){
813           $nameA = " ($nameA)";
814         }else{
815           $nameA = '';
816         }
817     
818         /* Add to array */      
819         if($key == (count($elements)-1)){
820           $last[$elestr.$nameA]['ENTRY'] = $val;
821         }
823         /* Set next array appending position */
824         $last = &$last[$elestr.$nameA]['SUB'];
825       }
826     }
829     /* Add base entry */
830     $ret['/']['ENTRY']  = $base;
831     $ret['/']['SUB']    = $arr;
832     $this->idepartments= $this->generateDepartmentArray($ret,-1,$max_size);
833   }
836   /* Creates display friendly output from make_idepartments */
837   function generateDepartmentArray($arr,$depth = -1,$max_size = 256)
838   {
839     $ret = array();
840     $depth ++;
842     /* Walk through array */    
843     ksort($arr);
844     foreach($arr as $name => $entries){
846       /* If this department is the last in the current tree position 
847        * remove it, to avoid generating output for it */
848       if(count($entries['SUB'])==0){
849         unset($entries['SUB']);
850       }
852       /* Fix name, if it contains a replace tag */
853       $name= preg_replace('/\\\\,/', ',', LDAP::fix($name));
855       /* Check if current name is too long, then cut it */
856       if(mb_strlen($name, 'UTF-8')> $max_size){
857         $name = mb_substr($name,0,($max_size-3), 'UTF-8')." ...";
858       }
860       /* Append the name to the list */ 
861       if(isset($entries['ENTRY'])){
862         $a = "";
863         for($i = 0 ; $i < $depth ; $i ++){
864           $a.=".";
865         }
866         $ret[$entries['ENTRY']]=$a."&nbsp;".$name;
867       } 
869       /* recursive add of subdepartments */
870       if(isset($entries['SUB'])){
871         $ret = array_merge($ret,$this->generateDepartmentArray($entries['SUB'],$depth,$max_size));
872       }
873     }
875     return($ret);
876   }
878   /*! \brief Get all available shares defined in the current LDAP
879    *
880    *  This function returns all available Shares defined in this ldap
881    *  
882    *  \param boolean listboxEntry If set to TRUE, only name and path are
883    *  attached to the array. If FALSE, the whole entry will be parsed an atached to the result.
884    *  \return array
885    */
886   function getShareList($listboxEntry = false)
887   {
888     $tmp = get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))","server",get_ou("servgeneric", "serverRDN"),
889         $this->current['BASE'],array("goExportEntry","cn"), GL_NONE);
890     $return =array();
891     foreach($tmp as $entry){
893       if(isset($entry['goExportEntry']['count'])){
894         unset($entry['goExportEntry']['count']);
895       }
896       if(isset($entry['goExportEntry'])){
897         foreach($entry['goExportEntry'] as $export){
898           $shareAttrs = explode("|",$export);
899           if($listboxEntry) {
900             $return[$shareAttrs[0]."|".$entry['cn'][0]] = $shareAttrs[0]." - ".$entry['cn'][0];
901           }else{
902             $return[$shareAttrs[0]."|".$entry['cn'][0]]['server']       = $entry['cn'][0];
903             $return[$shareAttrs[0]."|".$entry['cn'][0]]['name']         = $shareAttrs[0];
904             $return[$shareAttrs[0]."|".$entry['cn'][0]]['description']  = $shareAttrs[1];
905             $return[$shareAttrs[0]."|".$entry['cn'][0]]['type']         = $shareAttrs[2];
906             $return[$shareAttrs[0]."|".$entry['cn'][0]]['charset']      = $shareAttrs[3];
907             $return[$shareAttrs[0]."|".$entry['cn'][0]]['path']         = $shareAttrs[4];
908             $return[$shareAttrs[0]."|".$entry['cn'][0]]['option']       = $shareAttrs[5];
909           }
910         }
911       }
912     }
913     return($return);
914   }
917   /*! \brief Return al available share servers
918    *
919    * This function returns all available ShareServers.
920    *
921    * \return array
922    * */
923   function getShareServerList()
924   {
925     global $config;
926     $return = array();
927     $ui = get_userinfo();
928     $base = $config->current['BASE'];
929     $res= get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))", "server",
930           get_ou("servgeneric", "serverRDN"), $base,array("goExportEntry","cn"),GL_NONE | GL_NO_ACL_CHECK);
932     foreach($res as $entry){
933         
934         $acl = $ui->get_permissions($entry['dn'],"server","");
935         if(isset($entry['goExportEntry']['count'])){
936           unset($entry['goExportEntry']['count']);
937         }
938         foreach($entry['goExportEntry'] as $share){
939           $a_share = explode("|",$share);
940           $sharename = $a_share[0];
941           $data= array();
942           $data['NAME']   = $sharename;
943           $data['ACL']    = $acl;
944           $data['SERVER'] = $entry['cn']['0'];
945           $data['SHARE']  = $sharename;
946           $data['DISPLAY']= $entry['cn'][0]." [".$sharename."]";
947           $return[$entry['cn'][0]."|".$sharename] = $data;
948         }
949     }
950     return($return);
951   }
954   /*! \brief Checks if there's a bool property set in the configuration.
955    *
956    *  The function checks, weither the specified bool value is set to a true
957    *  value in the configuration file. 
958    *
959    *  Example usage:
960    *  \code
961    *  if ($this->config->boolValueIsTrue("core", "copyPaste")) {
962    *    echo "Copy Paste Handling is enabled";
963    *  }
964    *  \endcode
965    *
966    *  \param string 'class' The properties class. e.g. 'core','user','sudo',...
967    *  \param string 'value' Key in the given section, which is subject to check
968    *
969    *
970    * */
971   function boolValueIsTrue($class, $name)
972   {
973     return(preg_match("/true/i", $this->get_cfg_value($class,$name)));
974   }
977   function __search(&$arr, $name, $return)
978   {
979     $return= strtoupper($return);
980     if (is_array($arr)){
981       foreach ($arr as &$a){
982         if (isset($a['CLASS']) && strcasecmp($name, $a['CLASS']) == 0){
983           return(isset($a[$return])?$a[$return]:"");
984         } else {
985           $res= $this->__search ($a, $name, $return);
986           if ($res != ""){
987             return $res;
988           }
989         }
990       }
991     }
992     return ("");
993   }
996   /*! Outdated - try to use pluginEnabled, boolValueIsTrue or get_cfg_value instead. 
997    *
998    *  (Search for a configuration setting in different categories
999    *
1000    *  Searches for the value of a given key in the configuration data.
1001    *  Optionally the list of categories to search (tabs, main, locations) can
1002    *  be specified. The first value that matches is returned.
1003    *
1004    *  Example usage:
1005    *  \code
1006    *  $postcmd = $this->config->search(get_class($this), "POSTCOMMAND", array("menu", "tabs"));
1007    *  \endcode
1008    *  ) 
1009    *
1010    * */
1011   function search($class, $value, $categories= "")
1012   {
1013     if (is_array($categories)){
1014       foreach ($categories as $category){
1015         $res= $this->__search($this->data[strtoupper($category)], $class, $value);
1016         if ($res != ""){
1017           return $res;
1018         }
1019       }
1020     } else {
1021       if ($categories == "") {
1022         return $this->__search($this->data, $class, $value);
1023       } else {
1024         return $this->__search($this->data[strtoupper($categories)], $class, $value);
1025       }
1026     } 
1028     return ("");
1029   }
1031    
1032   /*! \brief          Check whether a plugin is activated or not 
1033    */ 
1034   function pluginEnabled($class){
1035       $tmp = $this->search($class, "CLASS",array('menu','tabs'));
1036       return(!empty($tmp));
1037   }
1040   /*! \brief Get a configuration value from the config
1041    *
1042    *  This returns a configuration value from the config. It either
1043    *  uses the data of the current location ($this->current),
1044    *  if it contains the value (e.g. current['BASE']) or otherwise
1045    *  uses the data from the main configuration section.
1046    *
1047    *  If no value is found and an optional default has been specified,
1048    *  then the default is returned.
1049    *
1050    *  \param string 'name' the configuration key (case-insensitive)
1051    *  \param string 'default' a default that is returned, if no value is found
1052    *
1053    *
1054    */
1055   function get_cfg_value($class,$name, $default= NULL) 
1056   {
1057     // The default parameter is deprecated 
1058     if($default != NULL){
1059 #        trigger_error("Third parameter 'default' is deprecated for function 'get_cfg_value'!");
1060     }
1062     // Return the matching property value if it exists.
1063     if($this->configRegistry->propertyExists($class,$name)){
1064         return($this->configRegistry->getPropertyValue($class,$name));
1065     }
1067     // Show a warning in the syslog if there is an undefined property requested.
1068     if($this->configRegistry->propertyInitializationComplete() && 
1069             "{$class}::{$name}" != 'core::config' &&  // <--- This on is never set, only in gosa.conf. 
1070             "{$class}::{$name}" != 'core::logging'){  // <--- This one may cause endless recursions in class_log.inc
1071         new log("debug","","Unconfigured property: '{$class}::{$name}'",array(),'');
1072     }
1074     // Try to find the property in the config file directly.
1075     $name= strtoupper($name);
1076     if (isset($this->current[$name])) return ($this->current[$name]);
1077     if (isset($this->data["MAIN"][$name])) return ($this->data["MAIN"][$name]);
1078     return ("");
1079   }
1082   /*! \brief Check if current configuration version matches the GOsa version
1083    *
1084    *  This function checks if the configuration file version matches the
1085    *  version of the gosa version, by comparing it with the configuration
1086    *  file version of the example gosa.conf that comes with GOsa.
1087    *  If a version mismatch occurs an error is triggered.
1088    * */
1089   function check_config_version()
1090   {
1091     /* Skip check, if we've already mentioned the mismatch 
1092      */
1093     if(session::global_is_set("LastChecked") && session::global_get("LastChecked") == $this->config_version) return;
1094   
1095     /* Remember last checked version 
1096      */
1097     session::global_set("LastChecked",$this->config_version);
1099     $current = md5(file_get_contents(CONFIG_TEMPLATE_DIR."/gosa.conf"));
1101     /* Check contributed config version and current config version.
1102      */
1103     if(($this->config_version == "NOT SET") || ($this->config_version != $current && !empty($this->config_version))){
1104       msg_dialog::display(_("Configuration"),_("The configuration file you are using is outdated. Please move the GOsa configuration file away to run the GOsa setup again."));
1105     }
1106   }
1109   /*! \brief Check if session lifetime matches session.gc_maxlifetime 
1110    *
1111    *  On debian systems the session files are deleted with
1112    *  a cronjob, which detects all files older than specified 
1113    *  in php.ini:'session.gc_maxlifetime' and removes them.
1114    *  This function checks if the gosa.conf value matches the range
1115    *  defined by session.gc_maxlifetime.
1116    *
1117    *  \return boolean TRUE or FALSE depending on weither the settings match
1118    *  or not. If SESSIONLIFETIME is not configured in GOsa it always returns
1119    *  TRUE.
1120    */
1121   function check_session_lifetime()
1122   {
1123     if(isset($this->data['MAIN']['SESSIONLIFETIME'])){
1124       $cfg_lifetime = $this->data['MAIN']['SESSIONLIFETIME'];
1125       $ini_lifetime = ini_get('session.gc_maxlifetime');
1126       $deb_system   = file_exists('/etc/debian_version');
1127       return(!($deb_system && ($ini_lifetime < $cfg_lifetime)));  
1128     }else{
1129       return(TRUE);
1130     }
1131   }
1133   /* Returns true if snapshots are enabled, and false if it is disalbed
1134      There will also be some errors psoted, if the configuration failed */
1135   function snapshotEnabled()
1136   {
1137     if($this->get_cfg_value("core","enableSnapshots") == "true"){
1139       /* Check if the snapshot_base is defined */
1140       if ($this->get_cfg_value("core","snapshotBase") == ""){
1142         /* Send message if not done already */
1143         if(!session::is_set("snapshotFailMessageSend")){
1144           session::set("snapshotFailMessageSend",TRUE);
1145           msg_dialog::display(_("Configuration error"),
1146               sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1147                       bold("snapshotBase")), ERROR_DIALOG);
1148         }
1149         return(FALSE);
1150       }
1152       /* Check if the snapshot_base is defined */
1153       if (!is_callable("gzcompress")){
1155         /* Send message if not done already */
1156         if(!session::is_set("snapshotFailMessageSend")){
1157           session::set("snapshotFailMessageSend",TRUE);
1158           msg_dialog::display(_("Configuration error"),
1159               sprintf(_("The snapshot functionality is enabled, but the required compression module is missing. Please install %s."), bold("php5-zip / php5-gzip")), ERROR_DIALOG);
1160         }
1161         return(FALSE);
1162       }
1164       /* check if there are special server configurations for snapshots */
1165       if ($this->get_cfg_value("core","snapshotURI") != ""){
1167         /* check if all required vars are available to create a new ldap connection */
1168         $missing = "";
1169         foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
1170           if($this->get_cfg_value("core",$var) == ""){
1171             $missing .= $var." ";
1173             /* Send message if not done already */
1174             if(!session::is_set("snapshotFailMessageSend")){
1175               session::set("snapshotFailMessageSend",TRUE);
1176               msg_dialog::display(_("Configuration error"),
1177                   sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1178                     bold($missing)), ERROR_DIALOG);
1179             }
1180             return(FALSE);
1181           }
1182                     }
1183             }
1184             return(TRUE);
1185     }
1186     return(FALSE);
1187   }
1191 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1192 ?>