Code

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