Code

Updated configRegistry
[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   public $configRegistry = NULL;
69   /*! \brief Class constructor of the config class
70    *  
71    *  \param string 'filename' path to the configuration file
72    *  \param string 'basedir' base directory
73    *
74    * */
75   function config($filename, $basedir= "")
76   {
77     $this->parser = xml_parser_create();
78     $this->basedir= $basedir;
80     xml_set_object($this->parser, $this);
81     xml_set_element_handler($this->parser, "tag_open", "tag_close");
83     /* Parse config file directly? */
84     if ($filename != ""){
85       $this->parse($filename);
86     }
88     // Load configuration registry
89     $this->configRegistry = new configRegistry($this);
90   }
93   /*! \brief Check and reload the configuration
94    * 
95    * This function checks if the configuration has changed, since it was
96    * read the last time and reloads it. It uses the file mtime to check
97    * weither the file changed or not.
98    *
99    * */ 
100   function check_and_reload()
101   {
102     global $ui;
104     /* Check if class_location.inc has changed, this is the case 
105         if we have installed or removed plugins. 
106      */
107     if(session::global_is_set("class_location.inc:timestamp")){
108       $tmp = stat("../include/class_location.inc");
109       if($tmp['mtime'] != session::global_get("class_location.inc:timestamp")){
110         session::global_un_set("plist");
111       }
112     }
113     $tmp = stat("../include/class_location.inc");
114     session::global_set("class_location.inc:timestamp",$tmp['mtime']);
116     if($this->filename != "" && filemtime($this->filename) != $this->last_modified){
118       $this->config_found= FALSE;
119       $this->tags= array();
120       $this->level= 0;
121       $this->gpc= 0;
122       $this->section= "";
123       $this->currentLocation= "";
125       $this->parser = xml_parser_create();
126       xml_set_object($this->parser, $this);
127       xml_set_element_handler($this->parser, "tag_open", "tag_close");
128       $this->parse($this->filename);
129       $this->set_current($this->current['NAME']);
130     }
131   }  
134   /*! \brief Parse the given configuration file 
135    *
136    *  Parses the configuration file and displays errors if there
137    *  is something wrong with it.
138    *
139    *  \param string 'filename' The filename of the configuration file.
140    * */
142   function parse($filename)
143   {
144     $this->data = array(
145         "TABS"      => array(), 
146         "LOCATIONS" => array(), 
147         "MAIN"      => array(), 
148         "MENU"      => array(), 
149         "SERVICE"   => array());
151     $this->last_modified = filemtime($filename);
152     $this->filename = $filename;
153     $fh= fopen($filename, "r"); 
154     $xmldata= fread($fh, 100000);
155     fclose($fh);
156     if(!xml_parse($this->parser, chop($xmldata))){
157       $msg = sprintf(_("XML error in gosa.conf: %s at line %d"),
158             bold(xml_error_string(xml_get_error_code($this->parser))),
159             bold(xml_get_current_line_number($this->parser)));
160       msg_dialog::display(_("Configuration error"), $msg, FATAL_ERROR_DIALOG);
161       exit;
162     }
164     // Default schemacheck to "true"
165     if(!isset($this->data['MAIN']['SCHEMACHECK'])){
166       $this->data['MAIN']['SCHEMACHECK'] = "true";
167     }
168   }
170   function tag_open($parser, $tag, $attrs)
171   {
172     /* Save last and current tag for reference */
173     $this->tags[$this->level]= $tag;
174     $this->level++;
176     /* Trigger on CONF section */
177     if ($tag == 'CONF'){
178       $this->config_found= TRUE;
179       if(isset($attrs['CONFIGVERSION'])){
180         $this->config_version = $attrs['CONFIGVERSION'];
181       }
182     }
184     /* Return if we're not in config section */
185     if (!$this->config_found){
186       return;
187     }
189     /* yes/no to true/false and upper case TRUE to true and so on*/
190     foreach($attrs as $name => $value){
191       if(preg_match("/^(true|yes)$/i",$value)){
192         $attrs[$name] = "true";
193       }elseif(preg_match("/^(false|no)$/i",$value)){
194         $attrs[$name] = "false";
195       } 
196     }
198     /* Look through attributes */
199     switch ($this->tags[$this->level-1]){
202       /* Handle tab section */
203       case 'TAB':       $name= $this->tags[$this->level-2];
205                   /* Create new array? */
206                   if (!isset($this->data['TABS'][$name])){
207                     $this->data['TABS'][$name]= array();
208                   }
210                   /* Add elements */
211                   $this->data['TABS'][$name][]= $attrs;
212                   break;
214                   /* Handle location */
215       case 'LOCATION':
216                   if ($this->tags[$this->level-2] == 'MAIN'){
217                     $name= $attrs['NAME'];
218                     $name = preg_replace("/[<>\"']/","",$name);
219                     $attrs['NAME'] = $name;
220                     $this->currentLocation= $name;
222                     /* Add location elements */
223                     $this->data['LOCATIONS'][$name]= $attrs;
224                   }
225                   break;
227                   /* Handle referral tags */
228       case 'REFERRAL':
229                   if ($this->tags[$this->level-2] == 'LOCATION'){
230                     $url= $attrs['URI'];
231                     $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
233                     /* Add location elements */
234                     if (!isset($this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'])){
235                       $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL']= array();
236                     }
238                     $this->data['LOCATIONS'][$this->currentLocation]['REFERRAL'][$server]= $attrs;
239                   }
240                   break;
242                   /* Load main parameters */
243       case 'MAIN':
244                   $this->data['MAIN']= array_merge ($this->data['MAIN'], $attrs);
245                   break;
247                   /* Load menu */
248       case 'SECTION':
249                   if ($this->tags[$this->level-2] == 'MENU'){
250                     $this->section= $attrs['NAME'];
251                     $this->data['MENU'][$this->section]= array(); ;
252                   }
253                   break;
255       case 'PATHMENU':
256                   $this->data['PATHMENU']= array(); ;
257                   break;
259                   /* Inser plugins */
260       case 'PLUGIN':
261                   if ($this->tags[$this->level-3] == 'MENU' &&
262                       $this->tags[$this->level-2] == 'SECTION'){
264                     $this->data['MENU'][$this->section][$this->gpc++]= $attrs;
265                   }
266                   if ($this->tags[$this->level-2] == 'PATHMENU'){
267                     $this->data['PATHMENU'][$this->gpc++]= $attrs;
268                   }
269                   if ($this->tags[$this->level-2] == 'SERVICEMENU'){
270                     $this->data['SERVICE'][$attrs['CLASS']]= $attrs;
271                   }
272                   break;
273     }
274   }
276   function tag_close($parser, $tag)
277   {
278     /* Close config section */
279     if ($tag == 'CONF'){
280       $this->config_found= FALSE;
281     }
282     $this->level--;
283   }
286   function get_credentials($creds)
287   {
288     if (isset($_SERVER['HTTP_GOSA_KEY'])){
289       if (!session::global_is_set('HTTP_GOSA_KEY_CACHE')){
290         session::global_set('HTTP_GOSA_KEY_CACHE',array());
291       }
292       $cache = session::global_get('HTTP_GOSA_KEY_CACHE');
293       if(!isset($cache[$creds])){
294         $cache[$creds] = cred_decrypt($creds, $_SERVER['HTTP_GOSA_KEY']);
295         session::global_set('HTTP_GOSA_KEY_CACHE',$cache);
296       }
297       return ($cache[$creds]);
298     }
299     return ($creds);
300   }
303   /*! \brief Get a LDAP link object
304    *
305    * This function can be used to get an ldap object, which in turn can
306    * be used to query the LDAP. See the LDAP class for more information
307    * on how to use it.
308    *
309    * Example usage:
310    * \code
311    * $ldap = $this->config->get_ldap_link();
312    * \endcode
313    *
314    * \param boolean sizelimit Weither to impose a sizelimit on the LDAP object or not.
315    * Defaults to false. If set to true, the size limit in the configuration
316    * file will be used to set the option LDAP_OPT_SIZELIMIT.
317    * \return ldapMultiplexer object
318    */
319   function get_ldap_link($sizelimit= FALSE)
320   {
321     if($this->ldap === NULL || !is_resource($this->ldap->cid)){
323       /* Build new connection */
324       $this->ldap= ldap_init ($this->current['SERVER'], $this->current['BASE'],
325           $this->current['ADMINDN'], $this->get_credentials($this->current['ADMINPASSWORD']));
327       /* Check for connection */
328       if (is_null($this->ldap) || (is_int($this->ldap) && $this->ldap == 0)){
329         $smarty= get_smarty();
330         msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP!"), FATAL_ERROR_DIALOG);
331         exit();
332       }
334       /* Move referrals */
335       if (!isset($this->current['REFERRAL'])){
336         $this->ldap->referrals= array();
337       } else {
338         $this->ldap->referrals= $this->current['REFERRAL'];
339       }
341       if (!session::global_is_set('size_limit')){
342         session::global_set('size_limit',$this->current['LDAPSIZELIMIT']);
343         session::global_set('size_ignore',$this->current['LDAPSIZEIGNORE']);
344       }
345     }
347     $obj  = new ldapMultiplexer($this->ldap);
348     if ($sizelimit){
349       $obj->set_size_limit(session::global_get('size_limit'));
350     } else {
351       $obj->set_size_limit(0);
352     }
353     return($obj);
354   }
356   /*! \brief Set the current location
357    *  
358    *  \param string name the name of the location
359    */
360   function set_current($name)
361   {
362     $this->current= $this->data['LOCATIONS'][$name];
364     if (!isset($this->current['USERRDN'])){
365       $this->current['USERRDN']= "ou=people";
366     }
367     if (!isset($this->current['GROUPRDN'])){
368       $this->current['GROUPS']= "ou=groups";
369     }
371     if (isset($this->current['INITIAL_BASE'])){
372       session::global_set('CurrentMainBase',$this->current['INITIAL_BASE']);
373     }
374   
375     /* Remove possibly added ',' from end of group and people ou */
376     $this->current['GROUPS'] = preg_replace("/,*$/","",$this->current['GROUPRDN']);
377     $this->current['USERRDN'] = preg_replace("/,*$/","",$this->current['USERRDN']);
379     if (!isset($this->current['SAMBAMACHINEACCOUNTRDN'])){
380       $this->current['SAMBAMACHINEACCOUNTRDN']= "ou=winstations,ou=systems";
381     }
382     if (!isset($this->current['ACCOUNTPRIMARYATTRIBUTE'])){
383       $this->current['ACCOUNTPRIMARYATTRIBUTE']= "cn";
384     }
385     if (!isset($this->current['MINID'])){
386       $this->current['MINID']= 100;
387     }
388     if (!isset($this->current['LDAPSIZELIMIT'])){
389       $this->current['LDAPSIZELIMIT']= 200;
390     }
391     if (!isset($this->current['SIZEINGORE'])){
392       $this->current['LDAPSIZEIGNORE']= TRUE;
393     } else {
394       if (preg_match("/true/i", $this->current['LDAPSIZEIGNORE'])){
395         $this->current['LDAPSIZEIGNORE']= TRUE;
396       } else {
397         $this->current['LDAPSIZEIGNORE']= FALSE;
398       }
399     }
401     /* Sort referrals, if present */
402     if (isset ($this->current['REFERRAL'])){
403       $bases= array();
404       $servers= array();
405       foreach ($this->current['REFERRAL'] as $ref){
406         $server= preg_replace('%^(.*://[^/]+)/.*$%', '\\1', $ref['URI']);
407         $base= preg_replace('%^.*://[^/]+/(.*)$%', '\\1', $ref['URI']);
408         $bases[$base]= strlen($base);
409         $servers[$base]= $server;
410       }
411       asort($bases);
412       reset($bases);
413     }
415     /* SERVER not defined? Load the one with the shortest base */
416     if (!isset($this->current['SERVER'])){
417       $this->current['SERVER']= $servers[key($bases)];
418     }
420     /* BASE not defined? Load the one with the shortest base */
421     if (!isset($this->current['BASE'])){
422       $this->current['BASE']= key($bases);
423     }
425     /* Convert BASE to have escaped special characters */
426     $this->current['BASE']= @LDAP::convert($this->current['BASE']);
428     /* Parse LDAP referral informations */
429     if (!isset($this->current['ADMINDN']) || !isset($this->current['ADMINPASSWORD'])){
430       $url= $this->current['SERVER'];
431       $referral= $this->current['REFERRAL'][$url];
432       $this->current['ADMINDN']= $referral['ADMINDN'];
433       $this->current['ADMINPASSWORD']= $referral['ADMINPASSWORD'];
434     }
436     /* Load server informations */
437     $this->load_servers();
438   }
441   /*! \brief Load server information from config/LDAP
442    *
443    *  This function searches the LDAP for servers (e.g. goImapServer, goMailServer etc.)
444    *  and stores information about them $this->data['SERVERS']. In the case of mailservers
445    *  the main section of the configuration file is searched, too.
446    */
447   function load_servers ()
448   {
449     /* Only perform actions if current is set */
450     if ($this->current === NULL){
451       return;
452     }
454     /* Fill imap servers */
455     $ldap= $this->get_ldap_link();
456     $ldap->cd ($this->current['BASE']);
458     /* Search mailMethod konfiguration in main section too 
459      */
460     $this->current['MAILMETHOD'] = $this->get_cfg_value("mailMethod","");
461     if (!isset($this->current['MAILMETHOD'])){
462       $this->current['MAILMETHOD']= "";
463     }
464     if ($this->current['MAILMETHOD'] == ""){
465       $ldap->search ("(objectClass=goMailServer)", array('cn'));
466       $this->data['SERVERS']['IMAP']= array();
467       while ($attrs= $ldap->fetch()){
468         $name= $attrs['cn'][0];
469         $this->data['SERVERS']['IMAP'][$name]= 
470           array( 
471               "server_dn"   => $attrs['dn'],
472               "connect"     => "",
473               "admin"       => "",
474               "password"    => "",
475               "sieve_server"=> "",
476               "sieve_option"=> "",
477               "sieve_port"  => "");
478       }
479     } else {
480       $ldap->search ("(&(objectClass=goImapServer)(goImapSieveServer=*))", 
481                     array('goImapName', 'goImapConnect', 'goImapAdmin', 'goImapPassword',
482             'goImapSieveServer', 'goImapSievePort'));
484       $this->data['SERVERS']['IMAP']= array();
486       while ($attrs= $ldap->fetch()){
488         /* Check if the given goImapSieveServer is in the new style "{cn:port/option}"
489            or the old style just "cn".
490          */
491         if(preg_match("/\{/",$attrs['goImapSieveServer'][0])){
492           $sieve_server = preg_replace("/^\{([^:]*).*$/","\\1",$attrs['goImapSieveServer'][0]);
493           $sieve_option = preg_replace("/^[^:]*[^\/]*+\/(.*)\}$/","\\1",$attrs['goImapSieveServer'][0]);
494         }else{
495           $sieve_server = $attrs['goImapSieveServer'][0];
496           $sieve_option = "";
497         }
499         $pwd            = $attrs['goImapPassword'][0];
500         $imap_admin     = $attrs['goImapAdmin'][0];
501         $imap_connect   = $attrs['goImapConnect'][0];
502         $imap_server    = $attrs['goImapName'][0];
503         $sieve_port     = $attrs['goImapSievePort'][0];
504         
505         $this->data['SERVERS']['IMAP'][$imap_server]= 
506             array( 
507             "server_dn"   => $attrs['dn'],
508             "connect"     => $imap_connect,
509             "admin"       => $imap_admin,
510             "password"    => $pwd,
511             "sieve_server"=> $sieve_server,
512             "sieve_option"=> $sieve_option,
513             "sieve_port"  => $sieve_port);
514       }
515     }
517     /* Get kerberos server. FIXME: only one is supported currently */
518     $ldap->cd ($this->current['BASE']);
519     $ldap->search ("(&(goKrbRealm=*)(goKrbAdmin=*)(objectClass=goKrbServer))");
520     if ($ldap->count()){
521       $attrs= $ldap->fetch();
522       $this->data['SERVERS']['KERBEROS']= array( 'SERVER' => $attrs['cn'][0],
523           'REALM' => $attrs['goKrbRealm'][0],
524           'ADMIN' => $attrs['goKrbAdmin'][0]);
525     }
527     /* Get cups server. FIXME: only one is supported currently */
528     $ldap->cd ($this->current['BASE']);
529     $ldap->search ("(objectClass=goCupsServer)");
530     if ($ldap->count()){
531       $attrs= $ldap->fetch();
532       $this->data['SERVERS']['CUPS']= $attrs['cn'][0];  
533     }
535     /* Get fax server. FIXME: only one is supported currently */
536     $ldap->cd ($this->current['BASE']);
537     $ldap->search ("(objectClass=goFaxServer)");
538     if ($ldap->count()){
539       $attrs= $ldap->fetch();
540       $this->data['SERVERS']['FAX']= array( 'SERVER' => $attrs['cn'][0],
541           'LOGIN' => $attrs['goFaxAdmin'][0],
542           'PASSWORD' => $attrs['goFaxPassword'][0]);
543     }
546     /* Get asterisk servers */
547     $ldap->cd ($this->current['BASE']);
548     $ldap->search ("(objectClass=goFonServer)");
549     $this->data['SERVERS']['FON']= array();
550     if ($ldap->count()){
551       while ($attrs= $ldap->fetch()){
553         /* Add 0 entry for development */
554         if(count($this->data['SERVERS']['FON']) == 0){
555           $this->data['SERVERS']['FON'][0]= array(
556               'DN'      => $attrs['dn'],
557               'SERVER'  => $attrs['cn'][0],
558               'LOGIN'   => $attrs['goFonAdmin'][0],
559               'PASSWORD'  => $attrs['goFonPassword'][0],
560               'DB'    => "gophone",
561               'SIP_TABLE'   => "sip_users",
562               'EXT_TABLE'   => "extensions",
563               'VOICE_TABLE' => "voicemail_users",
564               'QUEUE_TABLE' => "queues",
565               'QUEUE_MEMBER_TABLE'  => "queue_members");
566         }
568         /* Add entry with 'dn' as index */
569         $this->data['SERVERS']['FON'][$attrs['dn']]= array(
570             'DN'      => $attrs['dn'],
571             'SERVER'  => $attrs['cn'][0],
572             'LOGIN'   => $attrs['goFonAdmin'][0],
573             'PASSWORD'  => $attrs['goFonPassword'][0],
574             'DB'    => "gophone",
575             'SIP_TABLE'   => "sip_users",
576             'EXT_TABLE'   => "extensions",
577             'VOICE_TABLE' => "voicemail_users",
578             'QUEUE_TABLE' => "queues",
579             'QUEUE_MEMBER_TABLE'  => "queue_members");
580       }
581     }
584     /* Get glpi server */
585     $ldap->cd ($this->current['BASE']);
586     $ldap->search ("(&(objectClass=goGlpiServer)(cn=*)(goGlpiAdmin=*)(goGlpiDatabase=*))",array("cn","goGlpiPassword","goGlpiAdmin","goGlpiDatabase"));
587     if ($ldap->count()){
588       $attrs= $ldap->fetch();
589       if(!isset($attrs['goGlpiPassword'])){
590         $attrs['goGlpiPassword'][0] ="";
591       }
592       $this->data['SERVERS']['GLPI']= array( 
593           'SERVER'      => $attrs['cn'][0],
594           'LOGIN'       => $attrs['goGlpiAdmin'][0],
595           'PASSWORD'    => $attrs['goGlpiPassword'][0],
596           'DB'          => $attrs['goGlpiDatabase'][0]);
597     }
600     /* Get logdb server */
601     $ldap->cd ($this->current['BASE']);
602     $ldap->search ("(objectClass=goLogDBServer)");
603     if ($ldap->count()){
604       $attrs= $ldap->fetch();
605       if(!isset($attrs['gosaLogDB'][0])){
606         $attrs['gosaLogDB'][0] = "gomon";
607       }
608       $this->data['SERVERS']['LOG']= array( 'SERVER' => $attrs['cn'][0],
609           'LOGIN' => $attrs['goLogAdmin'][0],
610           'DB' => $attrs['gosaLogDB'][0],
611           'PASSWORD' => $attrs['goLogPassword'][0]);
612     }
615     /* GOsa logging databases */
616     $ldap->cd ($this->current['BASE']);
617     $ldap->search ("(objectClass=gosaLogServer)");
618     if ($ldap->count()){
619       while($attrs= $ldap->fetch()){
620       $this->data['SERVERS']['LOGGING'][$attrs['cn'][0]]= 
621           array(
622           'DN'    => $attrs['dn'],
623           'USER'  => $attrs['goLogDBUser'][0],
624           'DB'    => $attrs['goLogDB'][0],
625           'PWD'   => $attrs['goLogDBPassword'][0]);
626       }
627     }
630     /* Get NFS server lists */
631     $tmp= array("default");
632     $tmp2= array("default");
633     $ldap->cd ($this->current['BASE']);
634     $ldap->search ("(&(objectClass=goShareServer)(goExportEntry=*))");
635     while ($attrs= $ldap->fetch()){
636       for ($i= 0; $i<$attrs["goExportEntry"]["count"]; $i++){
637         if(preg_match('/^[^|]+\|[^|]+\|NFS\|.*$/', $attrs["goExportEntry"][$i])){
638           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
639           $tmp[]= $attrs["cn"][0].":$path";
640         }
641         if(preg_match('/^[^|]+\|[^|]+\|NBD\|.*$/', $attrs["goExportEntry"][$i])){
642           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
643           $tmp2[]= $attrs["cn"][0].":$path";
644         }
645       }
646     }
647     $this->data['SERVERS']['NFS']= $tmp;
648     $this->data['SERVERS']['NBD']= $tmp2;
650     /* Load Terminalservers */
651     $ldap->cd ($this->current['BASE']);
652     $ldap->search ("(objectClass=goTerminalServer)",array("cn","gotoSessionType"));
653     $this->data['SERVERS']['TERMINAL']= array();
654     $this->data['SERVERS']['TERMINAL'][]= "default";
655     $this->data['SERVERS']['TERMINAL_SESSION_TYPES'] = array();
658     while ($attrs= $ldap->fetch()){
659       $this->data['SERVERS']['TERMINAL'][]= $attrs["cn"][0];
660       if(isset( $attrs["gotoSessionType"]['count'])){
661         for($i =0 ; $i < $attrs["gotoSessionType"]['count'] ; $i++){
662           $this->data['SERVERS']['TERMINAL_SESSION_TYPES'][$attrs["cn"][0]][] = $attrs["gotoSessionType"][$i]; 
663         }
664       }
665     }
667     /* Ldap Server 
668      */
669     $this->data['SERVERS']['LDAP']= array();
670     $ldap->cd ($this->current['BASE']);
671     $ldap->search ("(&(objectClass=goLdapServer)(goLdapBase=*))");
672     while ($attrs= $ldap->fetch()){
673       $this->data['SERVERS']['LDAP'][$attrs['dn']] = $attrs;
674     }
676     /* Get misc server lists */
677     $this->data['SERVERS']['SYSLOG']= array("default");
678     $this->data['SERVERS']['NTP']= array("default");
679     $ldap->cd ($this->current['BASE']);
680     $ldap->search ("(objectClass=goNtpServer)");
681     while ($attrs= $ldap->fetch()){
682       $this->data['SERVERS']['NTP'][]= $attrs["cn"][0];
683     }
684     $ldap->cd ($this->current['BASE']);
685     $ldap->search ("(objectClass=goSyslogServer)");
686     while ($attrs= $ldap->fetch()){
687       $this->data['SERVERS']['SYSLOG'][]= $attrs["cn"][0];
688     }
690     /* Get samba servers from LDAP, in case of samba3 */
691     $this->data['SERVERS']['SAMBA']= array();
692     $ldap->cd ($this->current['BASE']);
693     $ldap->search ("(objectClass=sambaDomain)");
694     while ($attrs= $ldap->fetch()){
695       $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]= array( "SID" =>"","RIDBASE" =>"");
696       if(isset($attrs["sambaSID"][0])){
697         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["SID"]  = $attrs["sambaSID"][0];
698       }
699       if(isset($attrs["sambaAlgorithmicRidBase"][0])){
700         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["RIDBASE"] = $attrs["sambaAlgorithmicRidBase"][0];
701       }
702     }
704     /* If no samba servers are found, look for configured sid/ridbase */
705     if (count($this->data['SERVERS']['SAMBA']) == 0){
706       if (!isset($this->current["SAMBASID"]) || !isset($this->current["SAMBARIDBASE"])){
707         msg_dialog::display(_("Configuration error"), _("sambaSID and/or sambaRidBase missing in the configuration!"), ERROR_DIALOG);
708       } else {
709         $this->data['SERVERS']['SAMBA']['DEFAULT']= array(
710             "SID" => $this->current["SAMBASID"],
711             "RIDBASE" => $this->current["SAMBARIDBASE"]);
712       }
713     }
714     
715   }
718   function get_departments($ignore_dn= "")
719   {
720     global $config;
722     /* Initialize result hash */
723     $result= array();
724     $administrative= array();
725     $result['/']= $this->current['BASE'];
726     $this->tdepartments= array();
728     /* Get all department types from department Management, to be able detect the department type.
729         -It is possible that differnty department types have the same name, 
730          in this case we have to mark the department name to be able to differentiate.
731           (e.g l=Name  or   o=Name)
732      */    
733     $types = departmentManagement::get_support_departments();
734     
735     /* Create a list of attributes to fetch */
736     $ldap_values = array("objectClass","gosaUnitTag", "description");
737     $filter = "";
738     foreach($types as $type){
739       $ldap_values[] = $type['ATTR'];
740       $filter .= "(objectClass=".$type['OC'].")";
741     }
742     $filter = "(&(objectClass=gosaDepartment)(|".$filter."))";
744     /* Get list of department objects */
745     $ldap= $this->get_ldap_link();
746     $ldap->cd ($this->current['BASE']);
747     $ldap->search ($filter, $ldap_values);
748     while ($attrs= $ldap->fetch()){
750       /* Detect department type */
751       $type_data = array();
752       foreach($types as $t => $data){
753         if(in_array($data['OC'],$attrs['objectClass'])){
754           $type_data = $data;
755           break;
756         }
757       }
759       /* Unknown department type -> skip */
760       if(!count($type_data)) continue;
762       $dn= $ldap->getDN();
763       $this->tdepartments[$dn]= "";
764       $this->department_info[$dn]= array("img" => $type_data['IMG'],
765                                          "description" => isset($attrs['description'][0])?$attrs['description'][0]:"",
766                                          "name" => $attrs[$type_data['ATTR']][0]);
768       /* Save administrative departments */
769       if (in_array_ics("gosaAdministrativeUnit", $attrs['objectClass']) &&
770           isset($attrs['gosaUnitTag'][0])){
771         $administrative[$dn]= $attrs['gosaUnitTag'][0];
772         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
773       }
774     
775       if (in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass']) &&
776           isset($attrs['gosaUnitTag'][0])){
777         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
778       }
779     
780       if ($dn == $ignore_dn){
781         continue;
782       }
783       $c_dn = convert_department_dn($dn)." (".$type_data['ATTR'].")";
785       /* Only assign non-root departments */
786       if ($dn != $result['/']){
787         $result[$c_dn]= $dn;
788       }
789     }
791     $this->adepartments= $administrative;
792     $this->departments= $result;
793   }
796   function make_idepartments($max_size= 28)
797   {
798     global $config;
799     $base = $config->current['BASE'];
800                 $qbase = preg_quote($base, '/');
801     $utags= isset($config->current['HONOURUNITTAGS']) && preg_match('/true/i', $config->current['HONOURUNITTAGS']);
803     $arr = array();
804     $ui= get_userinfo();
806     $this->idepartments= array();
808     /* Create multidimensional array, with all departments. */
809     foreach ($this->departments as $key => $val){
811       /* When using strict_units, filter non relevant parts */
812       if ($utags){
813         if ($ui->gosaUnitTag != '' && isset($this->tdepartments[$val]) &&
814             $this->tdepartments[$val] != $ui->gosaUnitTag){
816                                                 #TODO: link with strict*
817                                                 #continue;
818         }
819       }
821       /* Split dn into single department pieces */
822       $elements = array_reverse(explode(',',preg_replace("/$qbase$/",'',$val)));                
824       /* Add last ou element of current dn to our array */
825       $last = &$arr;
826       foreach($elements as $key => $ele){
828         /* skip empty */
829         if(empty($ele)) continue;
831         /* Extract department name */           
832         $elestr = trim(preg_replace('/^[^=]*+=/','', $ele),',');
833         $nameA  = trim(preg_replace('/=.*$/','', $ele),',');
834         if($nameA != 'ou'){
835           $nameA = " ($nameA)";
836         }else{
837           $nameA = '';
838         }
839     
840         /* Add to array */      
841         if($key == (count($elements)-1)){
842           $last[$elestr.$nameA]['ENTRY'] = $val;
843         }
845         /* Set next array appending position */
846         $last = &$last[$elestr.$nameA]['SUB'];
847       }
848     }
851     /* Add base entry */
852     $ret['/']['ENTRY']  = $base;
853     $ret['/']['SUB']    = $arr;
854     $this->idepartments= $this->generateDepartmentArray($ret,-1,$max_size);
855   }
858   /* Creates display friendly output from make_idepartments */
859   function generateDepartmentArray($arr,$depth = -1,$max_size = 256)
860   {
861     $ret = array();
862     $depth ++;
864     /* Walk through array */    
865     ksort($arr);
866     foreach($arr as $name => $entries){
868       /* If this department is the last in the current tree position 
869        * remove it, to avoid generating output for it */
870       if(count($entries['SUB'])==0){
871         unset($entries['SUB']);
872       }
874       /* Fix name, if it contains a replace tag */
875       $name= preg_replace('/\\\\,/', ',', LDAP::fix($name));
877       /* Check if current name is too long, then cut it */
878       if(mb_strlen($name, 'UTF-8')> $max_size){
879         $name = mb_substr($name,0,($max_size-3), 'UTF-8')." ...";
880       }
882       /* Append the name to the list */ 
883       if(isset($entries['ENTRY'])){
884         $a = "";
885         for($i = 0 ; $i < $depth ; $i ++){
886           $a.=".";
887         }
888         $ret[$entries['ENTRY']]=$a."&nbsp;".$name;
889       } 
891       /* recursive add of subdepartments */
892       if(isset($entries['SUB'])){
893         $ret = array_merge($ret,$this->generateDepartmentArray($entries['SUB'],$depth,$max_size));
894       }
895     }
897     return($ret);
898   }
900   /*! \brief Get all available shares defined in the current LDAP
901    *
902    *  This function returns all available Shares defined in this ldap
903    *  
904    *  \param boolean listboxEntry If set to TRUE, only name and path are
905    *  attached to the array. If FALSE, the whole entry will be parsed an atached to the result.
906    *  \return array
907    */
908   function getShareList($listboxEntry = false)
909   {
910     $tmp = get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))","server",get_ou("serverRDN"),
911         $this->current['BASE'],array("goExportEntry","cn"), GL_NONE);
912     $return =array();
913     foreach($tmp as $entry){
915       if(isset($entry['goExportEntry']['count'])){
916         unset($entry['goExportEntry']['count']);
917       }
918       if(isset($entry['goExportEntry'])){
919         foreach($entry['goExportEntry'] as $export){
920           $shareAttrs = explode("|",$export);
921           if($listboxEntry) {
922             $return[$shareAttrs[0]."|".$entry['cn'][0]] = $shareAttrs[0]." - ".$entry['cn'][0];
923           }else{
924             $return[$shareAttrs[0]."|".$entry['cn'][0]]['server']       = $entry['cn'][0];
925             $return[$shareAttrs[0]."|".$entry['cn'][0]]['name']         = $shareAttrs[0];
926             $return[$shareAttrs[0]."|".$entry['cn'][0]]['description']  = $shareAttrs[1];
927             $return[$shareAttrs[0]."|".$entry['cn'][0]]['type']         = $shareAttrs[2];
928             $return[$shareAttrs[0]."|".$entry['cn'][0]]['charset']      = $shareAttrs[3];
929             $return[$shareAttrs[0]."|".$entry['cn'][0]]['path']         = $shareAttrs[4];
930             $return[$shareAttrs[0]."|".$entry['cn'][0]]['option']       = $shareAttrs[5];
931           }
932         }
933       }
934     }
935     return($return);
936   }
939   /*! \brief Return al available share servers
940    *
941    * This function returns all available ShareServers.
942    *
943    * \return array
944    * */
945   function getShareServerList()
946   {
947     global $config;
948     $return = array();
949     $ui = get_userinfo();
950     $base = $config->current['BASE'];
951     $res= get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))", "server",
952           get_ou("serverRDN"), $base,array("goExportEntry","cn"),GL_NONE | GL_NO_ACL_CHECK);
954     foreach($res as $entry){
955         
956         $acl = $ui->get_permissions($entry['dn'],"server","");
957         if(isset($entry['goExportEntry']['count'])){
958           unset($entry['goExportEntry']['count']);
959         }
960         foreach($entry['goExportEntry'] as $share){
961           $a_share = explode("|",$share);
962           $sharename = $a_share[0];
963           $data= array();
964           $data['NAME']   = $sharename;
965           $data['ACL']    = $acl;
966           $data['SERVER'] = $entry['cn']['0'];
967           $data['SHARE']  = $sharename;
968           $data['DISPLAY']= $entry['cn'][0]." [".$sharename."]";
969           $return[$entry['cn'][0]."|".$sharename] = $data;
970         }
971     }
972     return($return);
973   }
976   /*! \brief Check if there's the specified bool value set in the configuration
977    *
978    *  The function checks, weither the specified bool value is set to a true
979    *  value in the configuration file. Considered true are either true or yes,
980    *  case-insensitive.
981    *
982    *  Example usage:
983    *  \code
984    *  if ($this->config->boolValueIsTrue("main", "copyPaste")) {
985    *    echo "Copy Paste Handling is enabled";
986    *  }
987    *  \endcode
988    *
989    *  \param string 'section' Section in the configuration file.
990    *  \param string 'value' Key in the given section, which is subject to check
991    *
992    *
993    * */
994   function boolValueIsTrue($section, $value)
995   {
996     $section= strtoupper($section);
997     $value= strtoupper($value);
998     if (isset($this->data[$section][$value])){
999     
1000       $data= $this->data[$section][$value];
1001       if (preg_match("/^true$/i", $data) || preg_match("/yes/i", $data)){
1002         return TRUE;
1003       }
1005     }
1007     return FALSE;
1008   }
1011   function __search(&$arr, $name, $return)
1012   {
1013     $return= strtoupper($return);
1014     if (is_array($arr)){
1015       foreach ($arr as &$a){
1016         if (isset($a['CLASS']) && strcasecmp($name, $a['CLASS']) == 0){
1017           return(isset($a[$return])?$a[$return]:"");
1018         } else {
1019           $res= $this->__search ($a, $name, $return);
1020           if ($res != ""){
1021             return $res;
1022           }
1023         }
1024       }
1025     }
1026     return ("");
1027   }
1030   /*! Search for a configuration setting in different categories
1031    *
1032    *  Searches for the value of a given key in the configuration data.
1033    *  Optionally the list of categories to search (tabs, main, locations) can
1034    *  be specified. The first value that matches is returned.
1035    *
1036    *  Example usage:
1037    *  \code
1038    *  $postcmd = $this->config->search(get_class($this), "POSTCOMMAND", array("menu", "tabs"));
1039    *  \endcode
1040    *
1041    * */
1042   function search($class, $value, $categories= "")
1043   {
1044     if (is_array($categories)){
1045       foreach ($categories as $category){
1046         $res= $this->__search($this->data[strtoupper($category)], $class, $value);
1047         if ($res != ""){
1048           return $res;
1049         }
1050       }
1051     } else {
1052       if ($categories == "") {
1053         return $this->__search($this->data, $class, $value);
1054       } else {
1055         return $this->__search($this->data[strtoupper($categories)], $class, $value);
1056       }
1057     } 
1059     return ("");
1060   }
1063   /*! \brief Get a configuration value from the config
1064    *
1065    *  This returns a configuration value from the config. It either
1066    *  uses the data of the current location ($this->current),
1067    *  if it contains the value (e.g. current['BASE']) or otherwise
1068    *  uses the data from the main configuration section.
1069    *
1070    *  If no value is found and an optional default has been specified,
1071    *  then the default is returned.
1072    *
1073    *  \param string 'name' the configuration key (case-insensitive)
1074    *  \param string 'default' a default that is returned, if no value is found
1075    *
1076    *
1077    */
1078   function get_cfg_value($name, $default= "") 
1079   {
1081     if($this->configRegistry->propertyExists('core',$name)){
1082         return($this->configRegistry->getPropertyValue('core',$name));
1083     }
1085     $name= strtoupper($name);
1087     /* Check if we have a current value for $name */
1088     if (isset($this->current[$name])){
1089       return ($this->current[$name]);
1090     }
1092     /* Check if we have a global value for $name */
1093     if (isset($this->data["MAIN"][$name])){
1094       return ($this->data["MAIN"][$name]);
1095     }
1097     return ($default);
1098   }
1101   /*! \brief Check if current configuration version matches the GOsa version
1102    *
1103    *  This function checks if the configuration file version matches the
1104    *  version of the gosa version, by comparing it with the configuration
1105    *  file version of the example gosa.conf that comes with GOsa.
1106    *  If a version mismatch occurs an error is triggered.
1107    * */
1108   function check_config_version()
1109   {
1110     /* Skip check, if we've already mentioned the mismatch 
1111      */
1112     if(session::global_is_set("LastChecked") && session::global_get("LastChecked") == $this->config_version) return;
1113   
1114     /* Remember last checked version 
1115      */
1116     session::global_set("LastChecked",$this->config_version);
1118     $current = md5(file_get_contents(CONFIG_TEMPLATE_DIR."/gosa.conf"));
1120     /* Check contributed config version and current config version.
1121      */
1122     if(($this->config_version == "NOT SET") || ($this->config_version != $current && !empty($this->config_version))){
1123       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."));
1124     }
1125   }
1128   /*! \brief Check if session lifetime matches session.gc_maxlifetime 
1129    *
1130    *  On debian systems the session files are deleted with
1131    *  a cronjob, which detects all files older than specified 
1132    *  in php.ini:'session.gc_maxlifetime' and removes them.
1133    *  This function checks if the gosa.conf value matches the range
1134    *  defined by session.gc_maxlifetime.
1135    *
1136    *  \return boolean TRUE or FALSE depending on weither the settings match
1137    *  or not. If SESSIONLIFETIME is not configured in GOsa it always returns
1138    *  TRUE.
1139    */
1140   function check_session_lifetime()
1141   {
1142     if(isset($this->data['MAIN']['SESSIONLIFETIME'])){
1143       $cfg_lifetime = $this->data['MAIN']['SESSIONLIFETIME'];
1144       $ini_lifetime = ini_get('session.gc_maxlifetime');
1145       $deb_system   = file_exists('/etc/debian_version');
1146       return(!($deb_system && ($ini_lifetime < $cfg_lifetime)));  
1147     }else{
1148       return(TRUE);
1149     }
1150   }
1152   /* Returns true if snapshots are enabled, and false if it is disalbed
1153      There will also be some errors psoted, if the configuration failed */
1154   function snapshotEnabled()
1155   {
1156     if($this->get_cfg_value("enableSnapshots") == "true"){
1158       /* Check if the snapshot_base is defined */
1159       if ($this->get_cfg_value("snapshotBase") == ""){
1161         /* Send message if not done already */
1162         if(!session::is_set("snapshotFailMessageSend")){
1163           session::set("snapshotFailMessageSend",TRUE);
1164           msg_dialog::display(_("Configuration error"),
1165               sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1166                       bold("snapshotBase")), ERROR_DIALOG);
1167         }
1168         return(FALSE);
1169       }
1171       /* Check if the snapshot_base is defined */
1172       if (!is_callable("gzcompress")){
1174         /* Send message if not done already */
1175         if(!session::is_set("snapshotFailMessageSend")){
1176           session::set("snapshotFailMessageSend",TRUE);
1177           msg_dialog::display(_("Configuration error"),
1178               sprintf(_("The snapshot functionality is enabled, but the required compression module is missing. Please install %s."), bold("php5-zip / php5-gzip")), ERROR_DIALOG);
1179         }
1180         return(FALSE);
1181       }
1183       /* check if there are special server configurations for snapshots */
1184       if ($this->get_cfg_value("snapshotURI") != ""){
1186         /* check if all required vars are available to create a new ldap connection */
1187         $missing = "";
1188         foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
1189           if($this->get_cfg_value($var) == ""){
1190             $missing .= $var." ";
1192             /* Send message if not done already */
1193             if(!session::is_set("snapshotFailMessageSend")){
1194               session::set("snapshotFailMessageSend",TRUE);
1195               msg_dialog::display(_("Configuration error"),
1196                   sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1197                     bold($missing)), ERROR_DIALOG);
1198             }
1199             return(FALSE);
1200           }
1201                     }
1202             }
1203             return(TRUE);
1204     }
1205     return(FALSE);
1206   }
1210 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1211 ?>