Code

Cleaned up pluglist a bit.
[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             xml_error_string(xml_get_error_code($this->parser)),
154             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                   /* Inser plugins */
251       case 'PLUGIN':
252                   if ($this->tags[$this->level-3] == 'MENU' &&
253                       $this->tags[$this->level-2] == 'SECTION'){
255                     $this->data['MENU'][$this->section][$this->gpc++]= $attrs;
256                   }
257                   if ($this->tags[$this->level-2] == 'SERVICEMENU'){
258                     $this->data['SERVICE'][$attrs['CLASS']]= $attrs;
259                   }
260                   break;
261     }
262   }
264   function tag_close($parser, $tag)
265   {
266     /* Close config section */
267     if ($tag == 'CONF'){
268       $this->config_found= FALSE;
269     }
270     $this->level--;
271   }
274   function get_credentials($creds)
275   {
276     if (isset($_SERVER['HTTP_GOSA_KEY'])){
277       if (!session::global_is_set('HTTP_GOSA_KEY_CACHE')){
278         session::global_set('HTTP_GOSA_KEY_CACHE',array());
279       }
280       $cache = session::global_get('HTTP_GOSA_KEY_CACHE');
281       if(!isset($cache[$creds])){
282         $cache[$creds] = cred_decrypt($creds, $_SERVER['HTTP_GOSA_KEY']);
283         session::global_set('HTTP_GOSA_KEY_CACHE',$cache);
284       }
285       return ($cache[$creds]);
286     }
287     return ($creds);
288   }
291   /*! \brief Get a LDAP link object
292    *
293    * This function can be used to get an ldap object, which in turn can
294    * be used to query the LDAP. See the LDAP class for more information
295    * on how to use it.
296    *
297    * Example usage:
298    * \code
299    * $ldap = $this->config->get_ldap_link();
300    * \endcode
301    *
302    * \param boolean sizelimit Weither to impose a sizelimit on the LDAP object or not.
303    * Defaults to false. If set to true, the size limit in the configuration
304    * file will be used to set the option LDAP_OPT_SIZELIMIT.
305    * \return ldapMultiplexer object
306    */
307   function get_ldap_link($sizelimit= FALSE)
308   {
309     if($this->ldap === NULL || !is_resource($this->ldap->cid)){
311       /* Build new connection */
312       $this->ldap= ldap_init ($this->current['SERVER'], $this->current['BASE'],
313           $this->current['ADMINDN'], $this->get_credentials($this->current['ADMINPASSWORD']));
315       /* Check for connection */
316       if (is_null($this->ldap) || (is_int($this->ldap) && $this->ldap == 0)){
317         $smarty= get_smarty();
318         msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP. Please contact the system administrator."), FATAL_ERROR_DIALOG);
319         exit();
320       }
322       /* Move referrals */
323       if (!isset($this->current['REFERRAL'])){
324         $this->ldap->referrals= array();
325       } else {
326         $this->ldap->referrals= $this->current['REFERRAL'];
327       }
329       if (!session::global_is_set('size_limit')){
330         session::global_set('size_limit',$this->current['LDAPSIZELIMIT']);
331         session::global_set('size_ignore',$this->current['LDAPSIZEIGNORE']);
332       }
333     }
335     $obj  = new ldapMultiplexer($this->ldap);
336     if ($sizelimit){
337       $obj->set_size_limit(session::global_get('size_limit'));
338     } else {
339       $obj->set_size_limit(0);
340     }
341     return($obj);
342   }
344   /*! \brief Set the current location
345    *  
346    *  \param string name the name of the location
347    */
348   function set_current($name)
349   {
350     $this->current= $this->data['LOCATIONS'][$name];
352     if (!isset($this->current['USERRDN'])){
353       $this->current['USERRDN']= "ou=people";
354     }
355     if (!isset($this->current['GROUPRDN'])){
356       $this->current['GROUPS']= "ou=groups";
357     }
359     if (isset($this->current['INITIAL_BASE'])){
360       session::global_set('CurrentMainBase',$this->current['INITIAL_BASE']);
361     }
362   
363     /* Remove possibly added ',' from end of group and people ou */
364     $this->current['GROUPS'] = preg_replace("/,*$/","",$this->current['GROUPRDN']);
365     $this->current['USERRDN'] = preg_replace("/,*$/","",$this->current['USERRDN']);
367     if (!isset($this->current['SAMBAMACHINEACCOUNTRDN'])){
368       $this->current['SAMBAMACHINEACCOUNTRDN']= "ou=winstations,ou=systems";
369     }
370     if (!isset($this->current['ACCOUNTPRIMARYATTRIBUTE'])){
371       $this->current['ACCOUNTPRIMARYATTRIBUTE']= "cn";
372     }
373     if (!isset($this->current['MINID'])){
374       $this->current['MINID']= 100;
375     }
376     if (!isset($this->current['LDAPSIZELIMIT'])){
377       $this->current['LDAPSIZELIMIT']= 200;
378     }
379     if (!isset($this->current['SIZEINGORE'])){
380       $this->current['LDAPSIZEIGNORE']= TRUE;
381     } else {
382       if (preg_match("/true/i", $this->current['LDAPSIZEIGNORE'])){
383         $this->current['LDAPSIZEIGNORE']= TRUE;
384       } else {
385         $this->current['LDAPSIZEIGNORE']= FALSE;
386       }
387     }
389     /* Sort referrals, if present */
390     if (isset ($this->current['REFERRAL'])){
391       $bases= array();
392       $servers= array();
393       foreach ($this->current['REFERRAL'] as $ref){
394         $server= preg_replace('%^(.*://[^/]+)/.*$%', '\\1', $ref['URI']);
395         $base= preg_replace('%^.*://[^/]+/(.*)$%', '\\1', $ref['URI']);
396         $bases[$base]= strlen($base);
397         $servers[$base]= $server;
398       }
399       asort($bases);
400       reset($bases);
401     }
403     /* SERVER not defined? Load the one with the shortest base */
404     if (!isset($this->current['SERVER'])){
405       $this->current['SERVER']= $servers[key($bases)];
406     }
408     /* BASE not defined? Load the one with the shortest base */
409     if (!isset($this->current['BASE'])){
410       $this->current['BASE']= key($bases);
411     }
413     /* Convert BASE to have escaped special characters */
414     $this->current['BASE']= @LDAP::convert($this->current['BASE']);
416     /* Parse LDAP referral informations */
417     if (!isset($this->current['ADMINDN']) || !isset($this->current['ADMINPASSWORD'])){
418       $url= $this->current['SERVER'];
419       $referral= $this->current['REFERRAL'][$url];
420       $this->current['ADMINDN']= $referral['ADMINDN'];
421       $this->current['ADMINPASSWORD']= $referral['ADMINPASSWORD'];
422     }
424     /* Load server informations */
425     $this->load_servers();
426   }
429   /*! \brief Load server information from config/LDAP
430    *
431    *  This function searches the LDAP for servers (e.g. goImapServer, goMailServer etc.)
432    *  and stores information about them $this->data['SERVERS']. In the case of mailservers
433    *  the main section of the configuration file is searched, too.
434    */
435   function load_servers ()
436   {
437     /* Only perform actions if current is set */
438     if ($this->current === NULL){
439       return;
440     }
442     /* Fill imap servers */
443     $ldap= $this->get_ldap_link();
444     $ldap->cd ($this->current['BASE']);
446     /* Search mailMethod konfiguration in main section too 
447      */
448     $this->current['MAILMETHOD'] = $this->get_cfg_value("mailMethod","");
449     if (!isset($this->current['MAILMETHOD'])){
450       $this->current['MAILMETHOD']= "";
451     }
452     if ($this->current['MAILMETHOD'] == ""){
453       $ldap->search ("(objectClass=goMailServer)", array('cn'));
454       $this->data['SERVERS']['IMAP']= array();
455       while ($attrs= $ldap->fetch()){
456         $name= $attrs['cn'][0];
457         $this->data['SERVERS']['IMAP'][$name]= 
458           array( 
459               "server_dn"   => $attrs['dn'],
460               "connect"     => "",
461               "admin"       => "",
462               "password"    => "",
463               "sieve_server"=> "",
464               "sieve_option"=> "",
465               "sieve_port"  => "");
466       }
467     } else {
468       $ldap->search ("(&(objectClass=goImapServer)(goImapSieveServer=*))", 
469                     array('goImapName', 'goImapConnect', 'goImapAdmin', 'goImapPassword',
470             'goImapSieveServer', 'goImapSievePort'));
472       $this->data['SERVERS']['IMAP']= array();
474       while ($attrs= $ldap->fetch()){
476         /* Check if the given goImapSieveServer is in the new style "{cn:port/option}"
477            or the old style just "cn".
478          */
479         if(preg_match("/\{/",$attrs['goImapSieveServer'][0])){
480           $sieve_server = preg_replace("/^\{([^:]*).*$/","\\1",$attrs['goImapSieveServer'][0]);
481           $sieve_option = preg_replace("/^[^:]*[^\/]*+\/(.*)\}$/","\\1",$attrs['goImapSieveServer'][0]);
482         }else{
483           $sieve_server = $attrs['goImapSieveServer'][0];
484           $sieve_option = "";
485         }
487         $pwd            = $attrs['goImapPassword'][0];
488         $imap_admin     = $attrs['goImapAdmin'][0];
489         $imap_connect   = $attrs['goImapConnect'][0];
490         $imap_server    = $attrs['goImapName'][0];
491         $sieve_port     = $attrs['goImapSievePort'][0];
492         
493         $this->data['SERVERS']['IMAP'][$imap_server]= 
494             array( 
495             "server_dn"   => $attrs['dn'],
496             "connect"     => $imap_connect,
497             "admin"       => $imap_admin,
498             "password"    => $pwd,
499             "sieve_server"=> $sieve_server,
500             "sieve_option"=> $sieve_option,
501             "sieve_port"  => $sieve_port);
502       }
503     }
505     /* Get kerberos server. FIXME: only one is supported currently */
506     $ldap->cd ($this->current['BASE']);
507     $ldap->search ("(&(goKrbRealm=*)(goKrbAdmin=*)(objectClass=goKrbServer))");
508     if ($ldap->count()){
509       $attrs= $ldap->fetch();
510       $this->data['SERVERS']['KERBEROS']= array( 'SERVER' => $attrs['cn'][0],
511           'REALM' => $attrs['goKrbRealm'][0],
512           'ADMIN' => $attrs['goKrbAdmin'][0]);
513     }
515     /* Get cups server. FIXME: only one is supported currently */
516     $ldap->cd ($this->current['BASE']);
517     $ldap->search ("(objectClass=goCupsServer)");
518     if ($ldap->count()){
519       $attrs= $ldap->fetch();
520       $this->data['SERVERS']['CUPS']= $attrs['cn'][0];  
521     }
523     /* Get fax server. FIXME: only one is supported currently */
524     $ldap->cd ($this->current['BASE']);
525     $ldap->search ("(objectClass=goFaxServer)");
526     if ($ldap->count()){
527       $attrs= $ldap->fetch();
528       $this->data['SERVERS']['FAX']= array( 'SERVER' => $attrs['cn'][0],
529           'LOGIN' => $attrs['goFaxAdmin'][0],
530           'PASSWORD' => $attrs['goFaxPassword'][0]);
531     }
534     /* Get asterisk servers */
535     $ldap->cd ($this->current['BASE']);
536     $ldap->search ("(objectClass=goFonServer)");
537     $this->data['SERVERS']['FON']= array();
538     if ($ldap->count()){
539       while ($attrs= $ldap->fetch()){
541         /* Add 0 entry for development */
542         if(count($this->data['SERVERS']['FON']) == 0){
543           $this->data['SERVERS']['FON'][0]= array(
544               'DN'      => $attrs['dn'],
545               'SERVER'  => $attrs['cn'][0],
546               'LOGIN'   => $attrs['goFonAdmin'][0],
547               'PASSWORD'  => $attrs['goFonPassword'][0],
548               'DB'    => "gophone",
549               'SIP_TABLE'   => "sip_users",
550               'EXT_TABLE'   => "extensions",
551               'VOICE_TABLE' => "voicemail_users",
552               'QUEUE_TABLE' => "queues",
553               'QUEUE_MEMBER_TABLE'  => "queue_members");
554         }
556         /* Add entry with 'dn' as index */
557         $this->data['SERVERS']['FON'][$attrs['dn']]= array(
558             'DN'      => $attrs['dn'],
559             'SERVER'  => $attrs['cn'][0],
560             'LOGIN'   => $attrs['goFonAdmin'][0],
561             'PASSWORD'  => $attrs['goFonPassword'][0],
562             'DB'    => "gophone",
563             'SIP_TABLE'   => "sip_users",
564             'EXT_TABLE'   => "extensions",
565             'VOICE_TABLE' => "voicemail_users",
566             'QUEUE_TABLE' => "queues",
567             'QUEUE_MEMBER_TABLE'  => "queue_members");
568       }
569     }
572     /* Get glpi server */
573     $ldap->cd ($this->current['BASE']);
574     $ldap->search ("(&(objectClass=goGlpiServer)(cn=*)(goGlpiAdmin=*)(goGlpiDatabase=*))",array("cn","goGlpiPassword","goGlpiAdmin","goGlpiDatabase"));
575     if ($ldap->count()){
576       $attrs= $ldap->fetch();
577       if(!isset($attrs['goGlpiPassword'])){
578         $attrs['goGlpiPassword'][0] ="";
579       }
580       $this->data['SERVERS']['GLPI']= array( 
581           'SERVER'      => $attrs['cn'][0],
582           'LOGIN'       => $attrs['goGlpiAdmin'][0],
583           'PASSWORD'    => $attrs['goGlpiPassword'][0],
584           'DB'          => $attrs['goGlpiDatabase'][0]);
585     }
588     /* Get logdb server */
589     $ldap->cd ($this->current['BASE']);
590     $ldap->search ("(objectClass=goLogDBServer)");
591     if ($ldap->count()){
592       $attrs= $ldap->fetch();
593       if(!isset($attrs['gosaLogDB'][0])){
594         $attrs['gosaLogDB'][0] = "gomon";
595       }
596       $this->data['SERVERS']['LOG']= array( 'SERVER' => $attrs['cn'][0],
597           'LOGIN' => $attrs['goLogAdmin'][0],
598           'DB' => $attrs['gosaLogDB'][0],
599           'PASSWORD' => $attrs['goLogPassword'][0]);
600     }
603     /* GOsa logging databases */
604     $ldap->cd ($this->current['BASE']);
605     $ldap->search ("(objectClass=gosaLogServer)");
606     if ($ldap->count()){
607       while($attrs= $ldap->fetch()){
608       $this->data['SERVERS']['LOGGING'][$attrs['cn'][0]]= 
609           array(
610           'DN'    => $attrs['dn'],
611           'USER'  => $attrs['goLogDBUser'][0],
612           'DB'    => $attrs['goLogDB'][0],
613           'PWD'   => $attrs['goLogDBPassword'][0]);
614       }
615     }
618     /* Get NFS server lists */
619     $tmp= array("default");
620     $tmp2= array("default");
621     $ldap->cd ($this->current['BASE']);
622     $ldap->search ("(&(objectClass=goShareServer)(goExportEntry=*))");
623     while ($attrs= $ldap->fetch()){
624       for ($i= 0; $i<$attrs["goExportEntry"]["count"]; $i++){
625         if(preg_match('/^[^|]+\|[^|]+\|NFS\|.*$/', $attrs["goExportEntry"][$i])){
626           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
627           $tmp[]= $attrs["cn"][0].":$path";
628         }
629         if(preg_match('/^[^|]+\|[^|]+\|NBD\|.*$/', $attrs["goExportEntry"][$i])){
630           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
631           $tmp2[]= $attrs["cn"][0].":$path";
632         }
633       }
634     }
635     $this->data['SERVERS']['NFS']= $tmp;
636     $this->data['SERVERS']['NBD']= $tmp2;
638     /* Load Terminalservers */
639     $ldap->cd ($this->current['BASE']);
640     $ldap->search ("(objectClass=goTerminalServer)",array("cn","gotoSessionType"));
641     $this->data['SERVERS']['TERMINAL']= array();
642     $this->data['SERVERS']['TERMINAL'][]= "default";
643     $this->data['SERVERS']['TERMINAL_SESSION_TYPES'] = array();
646     while ($attrs= $ldap->fetch()){
647       $this->data['SERVERS']['TERMINAL'][]= $attrs["cn"][0];
648       if(isset( $attrs["gotoSessionType"]['count'])){
649         for($i =0 ; $i < $attrs["gotoSessionType"]['count'] ; $i++){
650           $this->data['SERVERS']['TERMINAL_SESSION_TYPES'][$attrs["cn"][0]][] = $attrs["gotoSessionType"][$i]; 
651         }
652       }
653     }
655     /* Ldap Server 
656      */
657     $this->data['SERVERS']['LDAP']= array();
658     $ldap->cd ($this->current['BASE']);
659     $ldap->search ("(&(objectClass=goLdapServer)(goLdapBase=*))");
660     while ($attrs= $ldap->fetch()){
661       $this->data['SERVERS']['LDAP'][$attrs['dn']] = $attrs;
662     }
664     /* Get misc server lists */
665     $this->data['SERVERS']['SYSLOG']= array("default");
666     $this->data['SERVERS']['NTP']= array("default");
667     $ldap->cd ($this->current['BASE']);
668     $ldap->search ("(objectClass=goNtpServer)");
669     while ($attrs= $ldap->fetch()){
670       $this->data['SERVERS']['NTP'][]= $attrs["cn"][0];
671     }
672     $ldap->cd ($this->current['BASE']);
673     $ldap->search ("(objectClass=goSyslogServer)");
674     while ($attrs= $ldap->fetch()){
675       $this->data['SERVERS']['SYSLOG'][]= $attrs["cn"][0];
676     }
678     /* Get samba servers from LDAP, in case of samba3 */
679     $this->data['SERVERS']['SAMBA']= array();
680     $ldap->cd ($this->current['BASE']);
681     $ldap->search ("(objectClass=sambaDomain)");
682     while ($attrs= $ldap->fetch()){
683       $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]= array( "SID" =>"","RIDBASE" =>"");
684       if(isset($attrs["sambaSID"][0])){
685         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["SID"]  = $attrs["sambaSID"][0];
686       }
687       if(isset($attrs["sambaAlgorithmicRidBase"][0])){
688         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["RIDBASE"] = $attrs["sambaAlgorithmicRidBase"][0];
689       }
690     }
692     /* If no samba servers are found, look for configured sid/ridbase */
693     if (count($this->data['SERVERS']['SAMBA']) == 0){
694       if (!isset($this->current["SAMBASID"]) || !isset($this->current["SAMBARIDBASE"])){
695         msg_dialog::display(_("Configuration error"), _("sambaSID and/or sambaRidBase missing in the configuration!"), ERROR_DIALOG);
696       } else {
697         $this->data['SERVERS']['SAMBA']['DEFAULT']= array(
698             "SID" => $this->current["SAMBASID"],
699             "RIDBASE" => $this->current["SAMBARIDBASE"]);
700       }
701     }
702     
703   }
706   function get_departments($ignore_dn= "")
707   {
708     global $config;
710     /* Initialize result hash */
711     $result= array();
712     $administrative= array();
713     $result['/']= $this->current['BASE'];
714     $this->tdepartments= array();
716     /* Get all department types from department Management, to be able detect the department type.
717         -It is possible that differnty department types have the same name, 
718          in this case we have to mark the department name to be able to differentiate.
719           (e.g l=Name  or   o=Name)
720      */    
721     $types = departmentManagement::get_support_departments();
722     
723     /* Create a list of attributes to fetch */
724     $ldap_values = array("objectClass","gosaUnitTag", "description");
725     $filter = "";
726     foreach($types as $type){
727       $ldap_values[] = $type['ATTR'];
728       $filter .= "(objectClass=".$type['OC'].")";
729     }
730     $filter = "(&(objectClass=gosaDepartment)(|".$filter."))";
732     /* Get list of department objects */
733     $ldap= $this->get_ldap_link();
734     $ldap->cd ($this->current['BASE']);
735     $ldap->search ($filter, $ldap_values);
736     while ($attrs= $ldap->fetch()){
738       /* Detect department type */
739       $type_data = array();
740       foreach($types as $t => $data){
741         if(in_array($data['OC'],$attrs['objectClass'])){
742           $type_data = $data;
743           break;
744         }
745       }
747       /* Unknown department type -> skip */
748       if(!count($type_data)) continue;
750       $dn= $ldap->getDN();
751       $this->tdepartments[$dn]= "";
752       $this->department_info[$dn]= array("img" => $type_data['IMG'],
753                                          "description" => isset($attrs['description'][0])?$attrs['description'][0]:"",
754                                          "name" => $attrs[$type_data['ATTR']][0]);
756       /* Save administrative departments */
757       if (in_array_ics("gosaAdministrativeUnit", $attrs['objectClass']) &&
758           isset($attrs['gosaUnitTag'][0])){
759         $administrative[$dn]= $attrs['gosaUnitTag'][0];
760         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
761       }
762     
763       if (in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass']) &&
764           isset($attrs['gosaUnitTag'][0])){
765         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
766       }
767     
768       if ($dn == $ignore_dn){
769         continue;
770       }
771       $c_dn = convert_department_dn($dn)." (".$type_data['ATTR'].")";
773       /* Only assign non-root departments */
774       if ($dn != $result['/']){
775         $result[$c_dn]= $dn;
776       }
777     }
779     $this->adepartments= $administrative;
780     $this->departments= $result;
781   }
784   function make_idepartments($max_size= 28)
785   {
786     global $config;
787     $base = $config->current['BASE'];
788                 $qbase = preg_quote($base, '/');
789     $utags= isset($config->current['HONOURUNITTAGS']) && preg_match('/true/i', $config->current['HONOURUNITTAGS']);
791     $arr = array();
792     $ui= get_userinfo();
794     $this->idepartments= array();
796     /* Create multidimensional array, with all departments. */
797     foreach ($this->departments as $key => $val){
799       /* When using strict_units, filter non relevant parts */
800       if ($utags){
801         if ($ui->gosaUnitTag != '' && isset($this->tdepartments[$val]) &&
802             $this->tdepartments[$val] != $ui->gosaUnitTag){
804                                                 #TODO: link with strict*
805                                                 #continue;
806         }
807       }
809       /* Split dn into single department pieces */
810       $elements = array_reverse(explode(',',preg_replace("/$qbase$/",'',$val)));                
812       /* Add last ou element of current dn to our array */
813       $last = &$arr;
814       foreach($elements as $key => $ele){
816         /* skip empty */
817         if(empty($ele)) continue;
819         /* Extract department name */           
820         $elestr = trim(preg_replace('/^[^=]*+=/','', $ele),',');
821         $nameA  = trim(preg_replace('/=.*$/','', $ele),',');
822         if($nameA != 'ou'){
823           $nameA = " ($nameA)";
824         }else{
825           $nameA = '';
826         }
827     
828         /* Add to array */      
829         if($key == (count($elements)-1)){
830           $last[$elestr.$nameA]['ENTRY'] = $val;
831         }
833         /* Set next array appending position */
834         $last = &$last[$elestr.$nameA]['SUB'];
835       }
836     }
839     /* Add base entry */
840     $ret['/']['ENTRY']  = $base;
841     $ret['/']['SUB']    = $arr;
842     $this->idepartments= $this->generateDepartmentArray($ret,-1,$max_size);
843   }
846   /* Creates display friendly output from make_idepartments */
847   function generateDepartmentArray($arr,$depth = -1,$max_size = 256)
848   {
849     $ret = array();
850     $depth ++;
852     /* Walk through array */    
853     ksort($arr);
854     foreach($arr as $name => $entries){
856       /* If this department is the last in the current tree position 
857        * remove it, to avoid generating output for it */
858       if(count($entries['SUB'])==0){
859         unset($entries['SUB']);
860       }
862       /* Fix name, if it contains a replace tag */
863       $name= preg_replace('/\\\\,/', ',', LDAP::fix($name));
865       /* Check if current name is too long, then cut it */
866       if(mb_strlen($name, 'UTF-8')> $max_size){
867         $name = mb_substr($name,0,($max_size-3), 'UTF-8')." ...";
868       }
870       /* Append the name to the list */ 
871       if(isset($entries['ENTRY'])){
872         $a = "";
873         for($i = 0 ; $i < $depth ; $i ++){
874           $a.=".";
875         }
876         $ret[$entries['ENTRY']]=$a."&nbsp;".$name;
877       } 
879       /* recursive add of subdepartments */
880       if(isset($entries['SUB'])){
881         $ret = array_merge($ret,$this->generateDepartmentArray($entries['SUB'],$depth,$max_size));
882       }
883     }
885     return($ret);
886   }
888   /*! \brief Get all available shares defined in the current LDAP
889    *
890    *  This function returns all available Shares defined in this ldap
891    *  
892    *  \param boolean listboxEntry If set to TRUE, only name and path are
893    *  attached to the array. If FALSE, the whole entry will be parsed an atached to the result.
894    *  \return array
895    */
896   function getShareList($listboxEntry = false)
897   {
898     $tmp = get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))","server",get_ou("serverRDN"),
899         $this->current['BASE'],array("goExportEntry","cn"), GL_NONE);
900     $return =array();
901     foreach($tmp as $entry){
903       if(isset($entry['goExportEntry']['count'])){
904         unset($entry['goExportEntry']['count']);
905       }
906       if(isset($entry['goExportEntry'])){
907         foreach($entry['goExportEntry'] as $export){
908           $shareAttrs = explode("|",$export);
909           if($listboxEntry) {
910             $return[$shareAttrs[0]."|".$entry['cn'][0]] = $shareAttrs[0]." - ".$entry['cn'][0];
911           }else{
912             $return[$shareAttrs[0]."|".$entry['cn'][0]]['server']       = $entry['cn'][0];
913             $return[$shareAttrs[0]."|".$entry['cn'][0]]['name']         = $shareAttrs[0];
914             $return[$shareAttrs[0]."|".$entry['cn'][0]]['description']  = $shareAttrs[1];
915             $return[$shareAttrs[0]."|".$entry['cn'][0]]['type']         = $shareAttrs[2];
916             $return[$shareAttrs[0]."|".$entry['cn'][0]]['charset']      = $shareAttrs[3];
917             $return[$shareAttrs[0]."|".$entry['cn'][0]]['path']         = $shareAttrs[4];
918             $return[$shareAttrs[0]."|".$entry['cn'][0]]['option']       = $shareAttrs[5];
919           }
920         }
921       }
922     }
923     return($return);
924   }
927   /*! \brief Return al available share servers
928    *
929    * This function returns all available ShareServers.
930    *
931    * \return array
932    * */
933   function getShareServerList()
934   {
935     global $config;
936     $return = array();
937     $ui = get_userinfo();
938     $base = $config->current['BASE'];
939     $res= get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))", "server",
940           get_ou("serverRDN"), $base,array("goExportEntry","cn"),GL_NONE | GL_NO_ACL_CHECK);
942     foreach($res as $entry){
943         
944         $acl = $ui->get_permissions($entry['dn'],"server","");
945         if(isset($entry['goExportEntry']['count'])){
946           unset($entry['goExportEntry']['count']);
947         }
948         foreach($entry['goExportEntry'] as $share){
949           $a_share = explode("|",$share);
950           $sharename = $a_share[0];
951           $data= array();
952           $data['NAME']   = $sharename;
953           $data['ACL']    = $acl;
954           $data['SERVER'] = $entry['cn']['0'];
955           $data['SHARE']  = $sharename;
956           $data['DISPLAY']= $entry['cn'][0]." [".$sharename."]";
957           $return[$entry['cn'][0]."|".$sharename] = $data;
958         }
959     }
960     return($return);
961   }
964   /*! \brief Check if there's the specified bool value set in the configuration
965    *
966    *  The function checks, weither the specified bool value is set to a true
967    *  value in the configuration file. Considered true are either true or yes,
968    *  case-insensitive.
969    *
970    *  Example usage:
971    *  \code
972    *  if ($this->config->boolValueIsTrue("main", "copyPaste")) {
973    *    echo "Copy Paste Handling is enabled";
974    *  }
975    *  \endcode
976    *
977    *  \param string 'section' Section in the configuration file.
978    *  \param string 'value' Key in the given section, which is subject to check
979    *
980    *
981    * */
982   function boolValueIsTrue($section, $value)
983   {
984     $section= strtoupper($section);
985     $value= strtoupper($value);
986     if (isset($this->data[$section][$value])){
987     
988       $data= $this->data[$section][$value];
989       if (preg_match("/^true$/i", $data) || preg_match("/yes/i", $data)){
990         return TRUE;
991       }
993     }
995     return FALSE;
996   }
999   function __search(&$arr, $name, $return)
1000   {
1001     $return= strtoupper($return);
1002     if (is_array($arr)){
1003       foreach ($arr as &$a){
1004         if (isset($a['CLASS']) && strcasecmp($name, $a['CLASS']) == 0){
1005           return(isset($a[$return])?$a[$return]:"");
1006         } else {
1007           $res= $this->__search ($a, $name, $return);
1008           if ($res != ""){
1009             return $res;
1010           }
1011         }
1012       }
1013     }
1014     return ("");
1015   }
1018   /*! Search for a configuration setting in different categories
1019    *
1020    *  Searches for the value of a given key in the configuration data.
1021    *  Optionally the list of categories to search (tabs, main, locations) can
1022    *  be specified. The first value that matches is returned.
1023    *
1024    *  Example usage:
1025    *  \code
1026    *  $postcmd = $this->config->search(get_class($this), "POSTCOMMAND", array("menu", "tabs"));
1027    *  \endcode
1028    *
1029    * */
1030   function search($class, $value, $categories= "")
1031   {
1032     if (is_array($categories)){
1033       foreach ($categories as $category){
1034         $res= $this->__search($this->data[strtoupper($category)], $class, $value);
1035         if ($res != ""){
1036           return $res;
1037         }
1038       }
1039     } else {
1040       if ($categories == "") {
1041         return $this->__search($this->data, $class, $value);
1042       } else {
1043         return $this->__search($this->data[strtoupper($categories)], $class, $value);
1044       }
1045     } 
1047     return ("");
1048   }
1051   /*! \brief Get a configuration value from the config
1052    *
1053    *  This returns a configuration value from the config. It either
1054    *  uses the data of the current location ($this->current),
1055    *  if it contains the value (e.g. current['BASE']) or otherwise
1056    *  uses the data from the main configuration section.
1057    *
1058    *  If no value is found and an optional default has been specified,
1059    *  then the default is returned.
1060    *
1061    *  \param string 'name' the configuration key (case-insensitive)
1062    *  \param string 'default' a default that is returned, if no value is found
1063    *
1064    *
1065    */
1066   function get_cfg_value($name, $default= "") {
1067     $name= strtoupper($name);
1069     /* Check if we have a current value for $name */
1070     if (isset($this->current[$name])){
1071       return ($this->current[$name]);
1072     }
1074     /* Check if we have a global value for $name */
1075     if (isset($this->data["MAIN"][$name])){
1076       return ($this->data["MAIN"][$name]);
1077     }
1079     return ($default);
1080   }
1083   /*! \brief Check if current configuration version matches the GOsa version
1084    *
1085    *  This function checks if the configuration file version matches the
1086    *  version of the gosa version, by comparing it with the configuration
1087    *  file version of the example gosa.conf that comes with GOsa.
1088    *  If a version mismatch occurs an error is triggered.
1089    * */
1090   function check_config_version()
1091   {
1092     /* Skip check, if we've already mentioned the mismatch 
1093      */
1094     if(session::global_is_set("LastChecked") && session::global_get("LastChecked") == $this->config_version) return;
1095   
1096     /* Remember last checked version 
1097      */
1098     session::global_set("LastChecked",$this->config_version);
1100     $current = md5(file_get_contents(CONFIG_TEMPLATE_DIR."/gosa.conf"));
1102     /* Check contributed config version and current config version.
1103      */
1104     if(($this->config_version == "NOT SET") || ($this->config_version != $current && !empty($this->config_version))){
1105       msg_dialog::display(_("Configuration"),_("The configuration file you are using seems to be outdated. Please move the GOsa configuration file away to run the GOsa setup again."));
1106     }
1107   }
1110   /*! \brief Check if session lifetime matches session.gc_maxlifetime 
1111    *
1112    *  On debian systems the session files are deleted with
1113    *  a cronjob, which detects all files older than specified 
1114    *  in php.ini:'session.gc_maxlifetime' and removes them.
1115    *  This function checks if the gosa.conf value matches the range
1116    *  defined by session.gc_maxlifetime.
1117    *
1118    *  \return boolean TRUE or FALSE depending on weither the settings match
1119    *  or not. If SESSIONLIFETIME is not configured in GOsa it always returns
1120    *  TRUE.
1121    */
1122   function check_session_lifetime()
1123   {
1124     if(isset($this->data['MAIN']['SESSIONLIFETIME'])){
1125       $cfg_lifetime = $this->data['MAIN']['SESSIONLIFETIME'];
1126       $ini_lifetime = ini_get('session.gc_maxlifetime');
1127       $deb_system   = file_exists('/etc/debian_version');
1128       return(!($deb_system && ($ini_lifetime < $cfg_lifetime)));  
1129     }else{
1130       return(TRUE);
1131     }
1132   }
1134   /* Returns true if snapshots are enabled, and false if it is disalbed
1135      There will also be some errors psoted, if the configuration failed */
1136   function snapshotEnabled()
1137   {
1138     if($this->get_cfg_value("enableSnapshots") == "true"){
1140       /* Check if the snapshot_base is defined */
1141       if ($this->get_cfg_value("snapshotBase") == ""){
1143         /* Send message if not done already */
1144         if(!session::is_set("snapshotFailMessageSend")){
1145           session::set("snapshotFailMessageSend",TRUE);
1146           msg_dialog::display(_("Configuration error"),
1147               sprintf(_("The snapshot functionality is enabled, but the required variable '%s' is not set."),
1148                       "snapshotBase"), ERROR_DIALOG);
1149         }
1150         return(FALSE);
1151       }
1153       /* Check if the snapshot_base is defined */
1154       if (!is_callable("gzcompress")){
1156         /* Send message if not done already */
1157         if(!session::is_set("snapshotFailMessageSend")){
1158           session::set("snapshotFailMessageSend",TRUE);
1159           msg_dialog::display(_("Configuration error"),
1160               sprintf(_("The snapshot functionality is enabled, but the required compression module is missing. Please install '%s'."),"php5-zip / php5-gzip"), ERROR_DIALOG);
1161         }
1162         return(FALSE);
1163       }
1165       /* check if there are special server configurations for snapshots */
1166       if ($this->get_cfg_value("snapshotURI") != ""){
1168         /* check if all required vars are available to create a new ldap connection */
1169         $missing = "";
1170         foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
1171           if($this->get_cfg_value($var) == ""){
1172             $missing .= $var." ";
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 variable '%s' is not set."),
1179                     $missing), ERROR_DIALOG);
1180             }
1181             return(FALSE);
1182           }
1183                     }
1184             }
1185             return(TRUE);
1186     }
1187     return(FALSE);
1188   }
1192 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1193 ?>