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 }
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];
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 }
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();
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[$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 }
770 if (in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass']) &&
771 isset($attrs['gosaUnitTag'][0])){
772 $this->tdepartments[$dn]= $attrs['gosaUnitTag'][0];
773 }
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 }
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." ".$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){
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])){
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;
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 }
1197 }
1199 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1200 ?>