Code

Added funtion to retrieve a rpc handle
[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     }
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   function getRpcHandle()
299   {
300       $server  =  $this->get_cfg_value('core','gosaRpcServer');
301       $user    =  $this->get_cfg_value('core','gosaRpcUser');
302       $passwd  =  $this->get_cfg_value('core','gosaRpcPassword');
304       $handle = new jsonRPC($server);
305       $handle->login($user, $password);
307       //Fixme  Add checks here - login successful aso.
308       return($handle);
309   }
312   /*! \brief Get a LDAP link object
313    *
314    * This function can be used to get an ldap object, which in turn can
315    * be used to query the LDAP. See the LDAP class for more information
316    * on how to use it.
317    *
318    * Example usage:
319    * \code
320    * $ldap = $this->config->get_ldap_link();
321    * \endcode
322    *
323    * \param boolean sizelimit Weither to impose a sizelimit on the LDAP object or not.
324    * Defaults to false. If set to true, the size limit in the configuration
325    * file will be used to set the option LDAP_OPT_SIZELIMIT.
326    * \return ldapMultiplexer object
327    */
328   function get_ldap_link($sizelimit= FALSE)
329   {
330     if($this->ldap === NULL || !is_resource($this->ldap->cid)){
332       /* Build new connection */
333       $this->ldap= ldap_init ($this->current['SERVER'], $this->current['BASE'],
334           $this->current['ADMINDN'], $this->get_credentials($this->current['ADMINPASSWORD']));
336       /* Check for connection */
337       if (is_null($this->ldap) || (is_int($this->ldap) && $this->ldap == 0)){
338         $smarty= get_smarty();
339         msg_dialog::display(_("LDAP error"), _("Cannot bind to LDAP!"), FATAL_ERROR_DIALOG);
340         exit();
341       }
343       /* Move referrals */
344       if (!isset($this->current['REFERRAL'])){
345         $this->ldap->referrals= array();
346       } else {
347         $this->ldap->referrals= $this->current['REFERRAL'];
348       }
350       if (!session::global_is_set('size_limit')){
351         session::global_set('size_limit', $this->get_cfg_value('core', 'ldapSizelimit'));
352         session::global_set('size_ignore', $this->boolValueIsTrue('core', 'ldapSizeIgnore'));
353       }
354     }
356     $obj  = new ldapMultiplexer($this->ldap);
357     if ($sizelimit){
358       $obj->set_size_limit(session::global_get('size_limit'));
359     } else {
360       $obj->set_size_limit(0);
361     }
362     return($obj);
363   }
365   /*! \brief Set the current location
366    *  
367    *  \param string name the name of the location
368    */
369   function set_current($name)
370   {
371     $this->current= $this->data['LOCATIONS'][$name];
373     if (isset($this->current['INITIAL_BASE'])){
374       session::global_set('CurrentMainBase',$this->current['INITIAL_BASE']);
375     }
376   
377     /* Sort referrals, if present */
378     if (isset ($this->current['REFERRAL'])){
379       $bases= array();
380       $servers= array();
381       foreach ($this->current['REFERRAL'] as $ref){
382         $server= preg_replace('%^(.*://[^/]+)/.*$%', '\\1', $ref['URI']);
383         $base= preg_replace('%^.*://[^/]+/(.*)$%', '\\1', $ref['URI']);
384         $bases[$base]= strlen($base);
385         $servers[$base]= $server;
386       }
387       asort($bases);
388       reset($bases);
389     }
391     /* SERVER not defined? Load the one with the shortest base */
392     if (!isset($this->current['SERVER'])){
393       $this->current['SERVER']= $servers[key($bases)];
394     }
396     /* BASE not defined? Load the one with the shortest base */
397     if (!isset($this->current['BASE'])){
398       $this->current['BASE']= key($bases);
399     }
401     /* Convert BASE to have escaped special characters */
402     $this->current['BASE']= @LDAP::convert($this->current['BASE']);
404     /* Parse LDAP referral informations */
405     if (!isset($this->current['ADMINDN']) || !isset($this->current['ADMINPASSWORD'])){
406       $url= $this->current['SERVER'];
407       $referral= $this->current['REFERRAL'][$url];
408       $this->current['ADMINDN']= $referral['ADMINDN'];
409       $this->current['ADMINPASSWORD']= $referral['ADMINPASSWORD'];
410     }
412     /* Load server informations */
413     $this->load_servers();
414   }
417   /*! \brief Load server information from config/LDAP
418    *
419    *  This function searches the LDAP for servers (e.g. goImapServer, goMailServer etc.)
420    *  and stores information about them $this->data['SERVERS']. In the case of mailservers
421    *  the main section of the configuration file is searched, too.
422    */
423   function load_servers ()
424   {
425     /* Only perform actions if current is set */
426     if ($this->current === NULL){
427       return;
428     }
430     /* Fill imap servers */
431     $ldap= $this->get_ldap_link();
432     $ldap->cd ($this->current['BASE']);
434     /* Search mailMethod konfiguration in main section too 
435      */
436     $tmp = $this->get_cfg_value("core","mailMethod");
437     if ($tmp){
438       $ldap->search ("(objectClass=goMailServer)", array('cn'));
439       $this->data['SERVERS']['IMAP']= array();
440       while ($attrs= $ldap->fetch()){
441         $name= $attrs['cn'][0];
442         $this->data['SERVERS']['IMAP'][$name]= 
443           array( 
444               "server_dn"   => $attrs['dn'],
445               "connect"     => "",
446               "admin"       => "",
447               "password"    => "",
448               "sieve_server"=> "",
449               "sieve_option"=> "",
450               "sieve_port"  => "");
451       }
452     } else {
453       $ldap->search ("(&(objectClass=goImapServer)(goImapSieveServer=*))", 
454                     array('goImapName', 'goImapConnect', 'goImapAdmin', 'goImapPassword',
455             'goImapSieveServer', 'goImapSievePort'));
457       $this->data['SERVERS']['IMAP']= array();
459       while ($attrs= $ldap->fetch()){
461         /* Check if the given goImapSieveServer is in the new style "{cn:port/option}"
462            or the old style just "cn".
463          */
464         if(preg_match("/\{/",$attrs['goImapSieveServer'][0])){
465           $sieve_server = preg_replace("/^\{([^:]*).*$/","\\1",$attrs['goImapSieveServer'][0]);
466           $sieve_option = preg_replace("/^[^:]*[^\/]*+\/(.*)\}$/","\\1",$attrs['goImapSieveServer'][0]);
467         }else{
468           $sieve_server = $attrs['goImapSieveServer'][0];
469           $sieve_option = "";
470         }
472         $pwd            = $attrs['goImapPassword'][0];
473         $imap_admin     = $attrs['goImapAdmin'][0];
474         $imap_connect   = $attrs['goImapConnect'][0];
475         $imap_server    = $attrs['goImapName'][0];
476         $sieve_port     = $attrs['goImapSievePort'][0];
477         
478         $this->data['SERVERS']['IMAP'][$imap_server]= 
479             array( 
480             "server_dn"   => $attrs['dn'],
481             "connect"     => $imap_connect,
482             "admin"       => $imap_admin,
483             "password"    => $pwd,
484             "sieve_server"=> $sieve_server,
485             "sieve_option"=> $sieve_option,
486             "sieve_port"  => $sieve_port);
487       }
488     }
490     /* Get kerberos server. FIXME: only one is supported currently */
491     $ldap->cd ($this->current['BASE']);
492     $ldap->search ("(&(goKrbRealm=*)(goKrbAdmin=*)(objectClass=goKrbServer))");
493     if ($ldap->count()){
494       $attrs= $ldap->fetch();
495       $this->data['SERVERS']['KERBEROS']= array( 'SERVER' => $attrs['cn'][0],
496           'REALM' => $attrs['goKrbRealm'][0],
497           'ADMIN' => $attrs['goKrbAdmin'][0]);
498     }
500     /* Get cups server. FIXME: only one is supported currently */
501     $ldap->cd ($this->current['BASE']);
502     $ldap->search ("(objectClass=goCupsServer)");
503     if ($ldap->count()){
504       $attrs= $ldap->fetch();
505       $this->data['SERVERS']['CUPS']= $attrs['cn'][0];  
506     }
508     /* Get fax server. FIXME: only one is supported currently */
509     $ldap->cd ($this->current['BASE']);
510     $ldap->search ("(objectClass=goFaxServer)");
511     if ($ldap->count()){
512       $attrs= $ldap->fetch();
513       $this->data['SERVERS']['FAX']= array( 'SERVER' => $attrs['cn'][0],
514           'LOGIN' => $attrs['goFaxAdmin'][0],
515           'PASSWORD' => $attrs['goFaxPassword'][0]);
516     }
519     /* Get asterisk servers */
520     $ldap->cd ($this->current['BASE']);
521     $ldap->search ("(objectClass=goFonServer)");
522     $this->data['SERVERS']['FON']= array();
523     if ($ldap->count()){
524       while ($attrs= $ldap->fetch()){
526         /* Add 0 entry for development */
527         if(count($this->data['SERVERS']['FON']) == 0){
528           $this->data['SERVERS']['FON'][0]= array(
529               'DN'      => $attrs['dn'],
530               'SERVER'  => $attrs['cn'][0],
531               'LOGIN'   => $attrs['goFonAdmin'][0],
532               'PASSWORD'  => $attrs['goFonPassword'][0],
533               'DB'    => "gophone",
534               'SIP_TABLE'   => "sip_users",
535               'EXT_TABLE'   => "extensions",
536               'VOICE_TABLE' => "voicemail_users",
537               'QUEUE_TABLE' => "queues",
538               'QUEUE_MEMBER_TABLE'  => "queue_members");
539         }
541         /* Add entry with 'dn' as index */
542         $this->data['SERVERS']['FON'][$attrs['dn']]= array(
543             'DN'      => $attrs['dn'],
544             'SERVER'  => $attrs['cn'][0],
545             'LOGIN'   => $attrs['goFonAdmin'][0],
546             'PASSWORD'  => $attrs['goFonPassword'][0],
547             'DB'    => "gophone",
548             'SIP_TABLE'   => "sip_users",
549             'EXT_TABLE'   => "extensions",
550             'VOICE_TABLE' => "voicemail_users",
551             'QUEUE_TABLE' => "queues",
552             'QUEUE_MEMBER_TABLE'  => "queue_members");
553       }
554     }
557     /* Get glpi server */
558     $ldap->cd ($this->current['BASE']);
559     $ldap->search ("(&(objectClass=goGlpiServer)(cn=*)(goGlpiAdmin=*)(goGlpiDatabase=*))",array("cn","goGlpiPassword","goGlpiAdmin","goGlpiDatabase"));
560     if ($ldap->count()){
561       $attrs= $ldap->fetch();
562       if(!isset($attrs['goGlpiPassword'])){
563         $attrs['goGlpiPassword'][0] ="";
564       }
565       $this->data['SERVERS']['GLPI']= array( 
566           'SERVER'      => $attrs['cn'][0],
567           'LOGIN'       => $attrs['goGlpiAdmin'][0],
568           'PASSWORD'    => $attrs['goGlpiPassword'][0],
569           'DB'          => $attrs['goGlpiDatabase'][0]);
570     }
573     /* Get logdb server */
574     $ldap->cd ($this->current['BASE']);
575     $ldap->search ("(objectClass=goLogDBServer)");
576     if ($ldap->count()){
577       $attrs= $ldap->fetch();
578       if(!isset($attrs['gosaLogDB'][0])){
579         $attrs['gosaLogDB'][0] = "gomon";
580       }
581       $this->data['SERVERS']['LOG']= array( 'SERVER' => $attrs['cn'][0],
582           'LOGIN' => $attrs['goLogAdmin'][0],
583           'DB' => $attrs['gosaLogDB'][0],
584           'PASSWORD' => $attrs['goLogPassword'][0]);
585     }
588     /* GOsa logging databases */
589     $ldap->cd ($this->current['BASE']);
590     $ldap->search ("(objectClass=gosaLogServer)");
591     if ($ldap->count()){
592       while($attrs= $ldap->fetch()){
593       $this->data['SERVERS']['LOGGING'][$attrs['cn'][0]]= 
594           array(
595           'DN'    => $attrs['dn'],
596           'USER'  => $attrs['goLogDBUser'][0],
597           'DB'    => $attrs['goLogDB'][0],
598           'PWD'   => $attrs['goLogDBPassword'][0]);
599       }
600     }
603     /* Get NFS server lists */
604     $tmp= array("default");
605     $tmp2= array("default");
606     $ldap->cd ($this->current['BASE']);
607     $ldap->search ("(&(objectClass=goShareServer)(goExportEntry=*))");
608     while ($attrs= $ldap->fetch()){
609       for ($i= 0; $i<$attrs["goExportEntry"]["count"]; $i++){
610         if(preg_match('/^[^|]+\|[^|]+\|NFS\|.*$/', $attrs["goExportEntry"][$i])){
611           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
612           $tmp[]= $attrs["cn"][0].":$path";
613         }
614         if(preg_match('/^[^|]+\|[^|]+\|NBD\|.*$/', $attrs["goExportEntry"][$i])){
615           $path= preg_replace ("/^[^|]+\|[^|]+\|[^|]+\|[^|]+\|([^|]+).*$/", '\1', $attrs["goExportEntry"][$i]);
616           $tmp2[]= $attrs["cn"][0].":$path";
617         }
618       }
619     }
620     $this->data['SERVERS']['NFS']= $tmp;
621     $this->data['SERVERS']['NBD']= $tmp2;
623     /* Load Terminalservers */
624     $ldap->cd ($this->current['BASE']);
625     $ldap->search ("(objectClass=goTerminalServer)",array("cn","gotoSessionType"));
626     $this->data['SERVERS']['TERMINAL']= array();
627     $this->data['SERVERS']['TERMINAL'][]= "default";
628     $this->data['SERVERS']['TERMINAL_SESSION_TYPES'] = array();
631     while ($attrs= $ldap->fetch()){
632       $this->data['SERVERS']['TERMINAL'][]= $attrs["cn"][0];
633       if(isset( $attrs["gotoSessionType"]['count'])){
634         for($i =0 ; $i < $attrs["gotoSessionType"]['count'] ; $i++){
635           $this->data['SERVERS']['TERMINAL_SESSION_TYPES'][$attrs["cn"][0]][] = $attrs["gotoSessionType"][$i]; 
636         }
637       }
638     }
640     /* Ldap Server 
641      */
642     $this->data['SERVERS']['LDAP']= array();
643     $ldap->cd ($this->current['BASE']);
644     $ldap->search ("(&(objectClass=goLdapServer)(goLdapBase=*))");
645     while ($attrs= $ldap->fetch()){
646       $this->data['SERVERS']['LDAP'][$attrs['dn']] = $attrs;
647     }
649     /* Get misc server lists */
650     $this->data['SERVERS']['SYSLOG']= array("default");
651     $this->data['SERVERS']['NTP']= array("default");
652     $ldap->cd ($this->current['BASE']);
653     $ldap->search ("(objectClass=goNtpServer)");
654     while ($attrs= $ldap->fetch()){
655       $this->data['SERVERS']['NTP'][]= $attrs["cn"][0];
656     }
657     $ldap->cd ($this->current['BASE']);
658     $ldap->search ("(objectClass=goSyslogServer)");
659     while ($attrs= $ldap->fetch()){
660       $this->data['SERVERS']['SYSLOG'][]= $attrs["cn"][0];
661     }
663     /* Get samba servers from LDAP, in case of samba3 */
664     $this->data['SERVERS']['SAMBA']= array();
665     $ldap->cd ($this->current['BASE']);
666     $ldap->search ("(objectClass=sambaDomain)");
667     while ($attrs= $ldap->fetch()){
668       $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]= array( "SID" =>"","RIDBASE" =>"");
669       if(isset($attrs["sambaSID"][0])){
670         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["SID"]  = $attrs["sambaSID"][0];
671       }
672       if(isset($attrs["sambaAlgorithmicRidBase"][0])){
673         $this->data['SERVERS']['SAMBA'][$attrs['sambaDomainName'][0]]["RIDBASE"] = $attrs["sambaAlgorithmicRidBase"][0];
674       }
675     }
677     /* If no samba servers are found, look for configured sid/ridbase */
678     if (count($this->data['SERVERS']['SAMBA']) == 0){
679       if (!isset($this->current["SAMBASID"]) || !isset($this->current["SAMBARIDBASE"])){
680         msg_dialog::display(_("Configuration error"), _("sambaSID and/or sambaRidBase missing in the configuration!"), ERROR_DIALOG);
681       } else {
682         $this->data['SERVERS']['SAMBA']['DEFAULT']= array(
683             "SID" => $this->current["SAMBASID"],
684             "RIDBASE" => $this->current["SAMBARIDBASE"]);
685       }
686     }
687     
688   }
691   function get_departments($ignore_dn= "")
692   {
693     global $config;
695     /* Initialize result hash */
696     $result= array();
697     $administrative= array();
698     $result['/']= $this->current['BASE'];
699     $this->tdepartments= array();
701     /* Get all department types from department Management, to be able detect the department type.
702         -It is possible that differnty department types have the same name, 
703          in this case we have to mark the department name to be able to differentiate.
704           (e.g l=Name  or   o=Name)
705      */    
706     $types = departmentManagement::get_support_departments();
707     
708     /* Create a list of attributes to fetch */
709     $ldap_values = array("objectClass","gosaUnitTag", "description");
710     $filter = "";
711     foreach($types as $type){
712       $ldap_values[] = $type['ATTR'];
713       $filter .= "(objectClass=".$type['OC'].")";
714     }
715     $filter = "(&(objectClass=gosaDepartment)(|".$filter."))";
717     /* Get list of department objects */
718     $ldap= $this->get_ldap_link();
719     $ldap->cd ($this->current['BASE']);
720     $ldap->search ($filter, $ldap_values);
721     while ($attrs= $ldap->fetch()){
723       /* Detect department type */
724       $type_data = array();
725       foreach($types as $t => $data){
726         if(in_array($data['OC'],$attrs['objectClass'])){
727           $type_data = $data;
728           break;
729         }
730       }
732       /* Unknown department type -> skip */
733       if(!count($type_data)) continue;
735       $dn= $ldap->getDN();
736       $this->tdepartments[$dn]= "";
737       $this->department_info[$dn]= array("img" => $type_data['IMG'],
738                                          "description" => isset($attrs['description'][0])?$attrs['description'][0]:"",
739                                          "name" => $attrs[$type_data['ATTR']][0]);
741       /* Save administrative departments */
742       if (in_array_ics("gosaAdministrativeUnit", $attrs['objectClass']) &&
743           isset($attrs['gosaUnitTag'][0])){
744         $administrative[$dn]= $attrs['gosaUnitTag'][0];
745         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
746       }
747     
748       if (in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass']) &&
749           isset($attrs['gosaUnitTag'][0])){
750         $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
751       }
752     
753       if ($dn == $ignore_dn){
754         continue;
755       }
756       $c_dn = convert_department_dn($dn)." (".$type_data['ATTR'].")";
758       /* Only assign non-root departments */
759       if ($dn != $result['/']){
760         $result[$c_dn]= $dn;
761       }
762     }
764     $this->adepartments= $administrative;
765     $this->departments= $result;
766   }
769   function make_idepartments($max_size= 28)
770   {
771     global $config;
772     $base = $config->current['BASE'];
773                 $qbase = preg_quote($base, '/');
774     $utags= isset($config->current['HONOURUNITTAGS']) && preg_match('/true/i', $config->current['HONOURUNITTAGS']);
776     $arr = array();
777     $ui= get_userinfo();
779     $this->idepartments= array();
781     /* Create multidimensional array, with all departments. */
782     foreach ($this->departments as $key => $val){
784       /* When using strict_units, filter non relevant parts */
785       if ($utags){
786         if ($ui->gosaUnitTag != '' && isset($this->tdepartments[$val]) &&
787             $this->tdepartments[$val] != $ui->gosaUnitTag){
789                                                 #TODO: link with strict*
790                                                 #continue;
791         }
792       }
794       /* Split dn into single department pieces */
795       $elements = array_reverse(explode(',',preg_replace("/$qbase$/",'',$val)));                
797       /* Add last ou element of current dn to our array */
798       $last = &$arr;
799       foreach($elements as $key => $ele){
801         /* skip empty */
802         if(empty($ele)) continue;
804         /* Extract department name */           
805         $elestr = trim(preg_replace('/^[^=]*+=/','', $ele),',');
806         $nameA  = trim(preg_replace('/=.*$/','', $ele),',');
807         if($nameA != 'ou'){
808           $nameA = " ($nameA)";
809         }else{
810           $nameA = '';
811         }
812     
813         /* Add to array */      
814         if($key == (count($elements)-1)){
815           $last[$elestr.$nameA]['ENTRY'] = $val;
816         }
818         /* Set next array appending position */
819         $last = &$last[$elestr.$nameA]['SUB'];
820       }
821     }
824     /* Add base entry */
825     $ret['/']['ENTRY']  = $base;
826     $ret['/']['SUB']    = $arr;
827     $this->idepartments= $this->generateDepartmentArray($ret,-1,$max_size);
828   }
831   /* Creates display friendly output from make_idepartments */
832   function generateDepartmentArray($arr,$depth = -1,$max_size = 256)
833   {
834     $ret = array();
835     $depth ++;
837     /* Walk through array */    
838     ksort($arr);
839     foreach($arr as $name => $entries){
841       /* If this department is the last in the current tree position 
842        * remove it, to avoid generating output for it */
843       if(count($entries['SUB'])==0){
844         unset($entries['SUB']);
845       }
847       /* Fix name, if it contains a replace tag */
848       $name= preg_replace('/\\\\,/', ',', LDAP::fix($name));
850       /* Check if current name is too long, then cut it */
851       if(mb_strlen($name, 'UTF-8')> $max_size){
852         $name = mb_substr($name,0,($max_size-3), 'UTF-8')." ...";
853       }
855       /* Append the name to the list */ 
856       if(isset($entries['ENTRY'])){
857         $a = "";
858         for($i = 0 ; $i < $depth ; $i ++){
859           $a.=".";
860         }
861         $ret[$entries['ENTRY']]=$a."&nbsp;".$name;
862       } 
864       /* recursive add of subdepartments */
865       if(isset($entries['SUB'])){
866         $ret = array_merge($ret,$this->generateDepartmentArray($entries['SUB'],$depth,$max_size));
867       }
868     }
870     return($ret);
871   }
873   /*! \brief Get all available shares defined in the current LDAP
874    *
875    *  This function returns all available Shares defined in this ldap
876    *  
877    *  \param boolean listboxEntry If set to TRUE, only name and path are
878    *  attached to the array. If FALSE, the whole entry will be parsed an atached to the result.
879    *  \return array
880    */
881   function getShareList($listboxEntry = false)
882   {
883     $tmp = get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))","server",get_ou("servgeneric", "serverRDN"),
884         $this->current['BASE'],array("goExportEntry","cn"), GL_NONE);
885     $return =array();
886     foreach($tmp as $entry){
888       if(isset($entry['goExportEntry']['count'])){
889         unset($entry['goExportEntry']['count']);
890       }
891       if(isset($entry['goExportEntry'])){
892         foreach($entry['goExportEntry'] as $export){
893           $shareAttrs = explode("|",$export);
894           if($listboxEntry) {
895             $return[$shareAttrs[0]."|".$entry['cn'][0]] = $shareAttrs[0]." - ".$entry['cn'][0];
896           }else{
897             $return[$shareAttrs[0]."|".$entry['cn'][0]]['server']       = $entry['cn'][0];
898             $return[$shareAttrs[0]."|".$entry['cn'][0]]['name']         = $shareAttrs[0];
899             $return[$shareAttrs[0]."|".$entry['cn'][0]]['description']  = $shareAttrs[1];
900             $return[$shareAttrs[0]."|".$entry['cn'][0]]['type']         = $shareAttrs[2];
901             $return[$shareAttrs[0]."|".$entry['cn'][0]]['charset']      = $shareAttrs[3];
902             $return[$shareAttrs[0]."|".$entry['cn'][0]]['path']         = $shareAttrs[4];
903             $return[$shareAttrs[0]."|".$entry['cn'][0]]['option']       = $shareAttrs[5];
904           }
905         }
906       }
907     }
908     return($return);
909   }
912   /*! \brief Return al available share servers
913    *
914    * This function returns all available ShareServers.
915    *
916    * \return array
917    * */
918   function getShareServerList()
919   {
920     global $config;
921     $return = array();
922     $ui = get_userinfo();
923     $base = $config->current['BASE'];
924     $res= get_sub_list("(&(objectClass=goShareServer)(goExportEntry=*))", "server",
925           get_ou("servgeneric", "serverRDN"), $base,array("goExportEntry","cn"),GL_NONE | GL_NO_ACL_CHECK);
927     foreach($res as $entry){
928         
929         $acl = $ui->get_permissions($entry['dn'],"server","");
930         if(isset($entry['goExportEntry']['count'])){
931           unset($entry['goExportEntry']['count']);
932         }
933         foreach($entry['goExportEntry'] as $share){
934           $a_share = explode("|",$share);
935           $sharename = $a_share[0];
936           $data= array();
937           $data['NAME']   = $sharename;
938           $data['ACL']    = $acl;
939           $data['SERVER'] = $entry['cn']['0'];
940           $data['SHARE']  = $sharename;
941           $data['DISPLAY']= $entry['cn'][0]." [".$sharename."]";
942           $return[$entry['cn'][0]."|".$sharename] = $data;
943         }
944     }
945     return($return);
946   }
949   /*! \brief Checks if there's a bool property set in the configuration.
950    *
951    *  The function checks, weither the specified bool value is set to a true
952    *  value in the configuration file. 
953    *
954    *  Example usage:
955    *  \code
956    *  if ($this->config->boolValueIsTrue("core", "copyPaste")) {
957    *    echo "Copy Paste Handling is enabled";
958    *  }
959    *  \endcode
960    *
961    *  \param string 'class' The properties class. e.g. 'core','user','sudo',...
962    *  \param string 'value' Key in the given section, which is subject to check
963    *
964    *
965    * */
966   function boolValueIsTrue($class, $name)
967   {
968     return(preg_match("/true/i", $this->get_cfg_value($class,$name)));
969   }
972   function __search(&$arr, $name, $return)
973   {
974     $return= strtoupper($return);
975     if (is_array($arr)){
976       foreach ($arr as &$a){
977         if (isset($a['CLASS']) && strcasecmp($name, $a['CLASS']) == 0){
978           return(isset($a[$return])?$a[$return]:"");
979         } else {
980           $res= $this->__search ($a, $name, $return);
981           if ($res != ""){
982             return $res;
983           }
984         }
985       }
986     }
987     return ("");
988   }
991   /*! Outdated - try to use pluginEnabled, boolValueIsTrue or get_cfg_value instead. 
992    *
993    *  (Search for a configuration setting in different categories
994    *
995    *  Searches for the value of a given key in the configuration data.
996    *  Optionally the list of categories to search (tabs, main, locations) can
997    *  be specified. The first value that matches is returned.
998    *
999    *  Example usage:
1000    *  \code
1001    *  $postcmd = $this->config->search(get_class($this), "POSTCOMMAND", array("menu", "tabs"));
1002    *  \endcode
1003    *  ) 
1004    *
1005    * */
1006   function search($class, $value, $categories= "")
1007   {
1008     if (is_array($categories)){
1009       foreach ($categories as $category){
1010         $res= $this->__search($this->data[strtoupper($category)], $class, $value);
1011         if ($res != ""){
1012           return $res;
1013         }
1014       }
1015     } else {
1016       if ($categories == "") {
1017         return $this->__search($this->data, $class, $value);
1018       } else {
1019         return $this->__search($this->data[strtoupper($categories)], $class, $value);
1020       }
1021     } 
1023     return ("");
1024   }
1026    
1027   /*! \brief          Check whether a plugin is activated or not 
1028    */ 
1029   function pluginEnabled($class){
1030       $tmp = $this->search($class, "CLASS",array('menu','tabs'));
1031       return(!empty($tmp));
1032   }
1035   /*! \brief Get a configuration value from the config
1036    *
1037    *  This returns a configuration value from the config. It either
1038    *  uses the data of the current location ($this->current),
1039    *  if it contains the value (e.g. current['BASE']) or otherwise
1040    *  uses the data from the main configuration section.
1041    *
1042    *  If no value is found and an optional default has been specified,
1043    *  then the default is returned.
1044    *
1045    *  \param string 'name' the configuration key (case-insensitive)
1046    *  \param string 'default' a default that is returned, if no value is found
1047    *
1048    *
1049    */
1050   function get_cfg_value($class,$name, $default= NULL) 
1051   {
1052     // The default parameter is deprecated 
1053     if($default != NULL){
1054 #        trigger_error("Third parameter 'default' is deprecated for function 'get_cfg_value'!");
1055     }
1057     // Return the matching property value if it exists.
1058     if($this->configRegistry->propertyExists($class,$name)){
1059         return($this->configRegistry->getPropertyValue($class,$name));
1060     }
1062     // Show a warning in the syslog if there is an undefined property requested.
1063     syslog(1,"Unconfigured property: {$class}::{$name}");    
1065     // Try to find the property in the config file directly.
1066     $name= strtoupper($name);
1067     if (isset($this->current[$name])) return ($this->current[$name]);
1068     if (isset($this->data["MAIN"][$name])) return ($this->data["MAIN"][$name]);
1069     return ("");
1070   }
1073   /*! \brief Check if current configuration version matches the GOsa version
1074    *
1075    *  This function checks if the configuration file version matches the
1076    *  version of the gosa version, by comparing it with the configuration
1077    *  file version of the example gosa.conf that comes with GOsa.
1078    *  If a version mismatch occurs an error is triggered.
1079    * */
1080   function check_config_version()
1081   {
1082     /* Skip check, if we've already mentioned the mismatch 
1083      */
1084     if(session::global_is_set("LastChecked") && session::global_get("LastChecked") == $this->config_version) return;
1085   
1086     /* Remember last checked version 
1087      */
1088     session::global_set("LastChecked",$this->config_version);
1090     $current = md5(file_get_contents(CONFIG_TEMPLATE_DIR."/gosa.conf"));
1092     /* Check contributed config version and current config version.
1093      */
1094     if(($this->config_version == "NOT SET") || ($this->config_version != $current && !empty($this->config_version))){
1095       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."));
1096     }
1097   }
1100   /*! \brief Check if session lifetime matches session.gc_maxlifetime 
1101    *
1102    *  On debian systems the session files are deleted with
1103    *  a cronjob, which detects all files older than specified 
1104    *  in php.ini:'session.gc_maxlifetime' and removes them.
1105    *  This function checks if the gosa.conf value matches the range
1106    *  defined by session.gc_maxlifetime.
1107    *
1108    *  \return boolean TRUE or FALSE depending on weither the settings match
1109    *  or not. If SESSIONLIFETIME is not configured in GOsa it always returns
1110    *  TRUE.
1111    */
1112   function check_session_lifetime()
1113   {
1114     if(isset($this->data['MAIN']['SESSIONLIFETIME'])){
1115       $cfg_lifetime = $this->data['MAIN']['SESSIONLIFETIME'];
1116       $ini_lifetime = ini_get('session.gc_maxlifetime');
1117       $deb_system   = file_exists('/etc/debian_version');
1118       return(!($deb_system && ($ini_lifetime < $cfg_lifetime)));  
1119     }else{
1120       return(TRUE);
1121     }
1122   }
1124   /* Returns true if snapshots are enabled, and false if it is disalbed
1125      There will also be some errors psoted, if the configuration failed */
1126   function snapshotEnabled()
1127   {
1128     if($this->get_cfg_value("core","enableSnapshots") == "true"){
1130       /* Check if the snapshot_base is defined */
1131       if ($this->get_cfg_value("core","snapshotBase") == ""){
1133         /* Send message if not done already */
1134         if(!session::is_set("snapshotFailMessageSend")){
1135           session::set("snapshotFailMessageSend",TRUE);
1136           msg_dialog::display(_("Configuration error"),
1137               sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1138                       bold("snapshotBase")), ERROR_DIALOG);
1139         }
1140         return(FALSE);
1141       }
1143       /* Check if the snapshot_base is defined */
1144       if (!is_callable("gzcompress")){
1146         /* Send message if not done already */
1147         if(!session::is_set("snapshotFailMessageSend")){
1148           session::set("snapshotFailMessageSend",TRUE);
1149           msg_dialog::display(_("Configuration error"),
1150               sprintf(_("The snapshot functionality is enabled, but the required compression module is missing. Please install %s."), bold("php5-zip / php5-gzip")), ERROR_DIALOG);
1151         }
1152         return(FALSE);
1153       }
1155       /* check if there are special server configurations for snapshots */
1156       if ($this->get_cfg_value("core","snapshotURI") != ""){
1158         /* check if all required vars are available to create a new ldap connection */
1159         $missing = "";
1160         foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
1161           if($this->get_cfg_value("core",$var) == ""){
1162             $missing .= $var." ";
1164             /* Send message if not done already */
1165             if(!session::is_set("snapshotFailMessageSend")){
1166               session::set("snapshotFailMessageSend",TRUE);
1167               msg_dialog::display(_("Configuration error"),
1168                   sprintf(_("The snapshot functionality is enabled, but the required variable %s is not set."),
1169                     bold($missing)), ERROR_DIALOG);
1170             }
1171             return(FALSE);
1172           }
1173                     }
1174             }
1175             return(TRUE);
1176     }
1177     return(FALSE);
1178   }
1182 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1183 ?>