Code

Updated setup schema check with new ldap::get_objectclasses()
[gosa.git] / include / functions_setup.inc
1 <?php
3 function check_schema_version($description, $version)
4 {
5   $desc= preg_replace("/^.* DESC\s+\(*\s*'([^']+)'\s*\)*.*$/", '\\1', $description);
7   return preg_match("/\(v$version\)/", $desc);
8 }
11 function view_schema_check($table)
12 {
13   $message="<table summary=\"\" class=\"check\">";
15   foreach ($table as $key => $values){
16     $msg = $values['msg'];
17     $message.= "<tr><td class=\"check\">$msg";
19     if($values['status']) {
20       $message.="</td><td style='text-align:center' >
21         <img src=images/true.png alt='true' /></td></tr>";
22     } else {
23       $message.="</td><td style='text-align:center' >
24         <img src=images/button_cancel.png alt='false' /></td></tr>";
25     }
26   }
27   $message.="</table>";
29   return $message;
30 }
33 function is_schema_readable($server, $admin, $password)
34 {
35   $ds= ldap_connect ($server);
36   if (!$ds) {
37     return (false);
38   }
39   ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
40   $r= ldap_bind ($ds, $admin, $password);
42   /* Get base to look for schema */
43   $sr  = @ldap_read ($ds, NULL, "objectClass=*", array("subschemaSubentry"));
44   $attr= @ldap_get_entries($ds,$sr);
45   if (!isset($attr[0]['subschemasubentry'][0])){
46     return (false);
47   }
49   $nb= $attr[0]['subschemasubentry'][0];
50   $objectclasses= array();
51   $sr= ldap_read ($ds, $nb, "objectClass=*", array("objectclasses"));
52   $attrs= ldap_get_entries($ds,$sr);
53   if (!isset($attrs[0])){
54     return (false);
55   }
56   return(true);
57
59 function schema_check($server, $admin, $password, $aff=0,$CalledByIndexPhP=false)
60 {
61   global $config;
63   $messages= array();
64   $required_classes= array(
65       "gosaObject"            => array("version" => "2.4"),
66       "gosaAccount"           => array("version" => "2.4"),
67       "gosaLockEntry"         => array("version" => "2.4"),
68       "gosaCacheEntry"        => array("version" => "2.4"),
69       "gosaDepartment"        => array("version" => "2.4"),
71       "goFaxAccount"          => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
72       "goFaxSBlock"           => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
73       "goFaxRBlock"           => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"),
75       "gosaUserTemplate"      => array("version" => "2.4", "class" => "posixAccount","file" => "nis.schema"),
76       "gosaMailAccount"       => array("version" => "2.4", "class" => "mailAccount","file" => "gosa+samba3.schema"),
77       "gosaProxyAccount"      => array("version" => "2.4", "class" => "proxyAccount","file" => "gosa+samba3.schema"),
78       "gosaApplication"       => array("version" => "2.4", "class" => "appgroup","file" => "gosa.schema"),
79       "gosaApplicationGroup"  => array("version" => "2.4", "class" => "appgroup","file" => "gosa.schema"),
81       "GOhard"                => array("version" => "2.5", "class" => "terminals","file" => "goto.schema"),
82       "gotoTerminal"          => array("version" => "2.5", "class" => "terminals","file" => "goto.schema"),
83       "goServer"              => array("version" => "2.4","class" => "server","file" => "goserver.schema"),
84       "goTerminalServer"      => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"),
85       "goShareServer"           => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"),
86       "goNtpServer"           => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"),
87       "goSyslogServer"        => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"),
88       "goLdapServer"          => array("version" => "2.4"),
89       "goCupsServer"          => array("version" => "2.4", "class" => array("posixAccount", "terminals"),),
90       "goImapServer"          => array("version" => "2.4", "class" => array("mailAccount", "mailgroup"),"file" => "gosa+samba3.schema"),
91       "goKrbServer"           => array("version" => "2.4"),
92       "goFaxServer"           => array("version" => "2.4", "class" => "gofaxAccount","file" => "gofax.schema"),
93       );
95   /* Get objectclasses */
96   $ldap = new LDAP($admin,$password, $server);
97   $objectclasses = $ldap->get_objectclasses(); 
98   if(count($objectclasses) == 0){
99     return (array(array("msg" => _("Can't get schema information from server. No schema check possible!"), "status" => FALSE)));
100   }
102   /* Walk through objectclasses and check if they are needed or not */
103   foreach ($required_classes as $key => $value){
104     if (isset($value['class'])){
105       if (!is_array($value['class'])){
106         $classes= array($value['class']);
107       } else {
108         $classes= $value['class'];
109       }
111       /* Check if we are using the class that requires */
112       foreach($classes as $class){
113         if (!isset($objectclasses[$key])){
114           $messages[$key]['msg']= sprintf(_("Optional objectclass '%s' required by plugin '%s' is not present in LDAP setup"), $key, $class);
115           $messages[$key]['status'] = FALSE;
116         } else {
117           if (!check_schema_version($objectclasses[$key], $value['version'])){
118             $messages[$key]['msg']= sprintf(_("Optional objectclass '%s' required by plugin '%s' does not have version %s"), $key, $class, $value['version']);
119             $messages[$key]['needonstartup'] = TRUE;
120             $messages[$key]['status'] =FALSE;
121           }else {
122             if(!isset($affich2[$class])){
123               $affich2[$class]['msg']   = sprintf(_("Support for '%s' enabled"), $class)."<td class=\"check\"> ".$value['file']."</td>";
124               $affich2[$class]['status']= TRUE; 
125             }
126           }
127         }
129       }
130     } else {
131       /* Required class */
132       if (!isset($objectclasses[$key])){
133         $messages[$key]['msg']= sprintf(_("Required objectclass '%s' is not present in LDAP setup"), $key);
134         $messages[$key]['status'] = FALSE;  
135       } else {
136         if (!check_schema_version($objectclasses[$key], $value['version'])){
137           $messages[$key]['msg']= sprintf(_("Required objectclass '%s' does not have version %s"), $key, $value['version']);
138           $messages[$key]['status'] = FALSE;  
139           $messages[$key]['needonstartup'] = TRUE;
140         }
141     
142       }
143     }
144   }
146   /* Check for correct samba parameters */
147   if (!isset($objectclasses['sambaSamAccount'])){
148     $messages['samba3']['msg']= _("SAMBA 3 support disabled, no schema seems to be installed");
149     $affich['samba3']['msg']= $messages['samba3']['msg']."<td class=\"check\">gosa+samba3.schema</td>";
150     $messages['samba3']['status']= FALSE;
151     $affich['samba3']['status']= FALSE;
152   }else{
153     $affich['samba3']['msg']= _("SAMBA 3 support enabled")."<td class=\"check\">gosa+samba3.schema</td>";
154     $affich['samba3']['status']= TRUE;
155   }
157   if (!isset($objectclasses['sambaAccount'])){
158     $messages['samba2']['msg']= _("SAMBA 2 support disabled, no schema seems to be installed");
159     $affich['samba2']['msg']= $messages['samba2']['msg']."<td class=\"check\">samba.schema</td>";
160     $messages['samba2']['status']= FALSE;
161     $affich['samba2']['status']= FALSE;
162   }else{
163     $affich['samba2']['msg']= _("SAMBA 2 support enabled")."<td class=\"check\">samba.schema</td>";
164     $affich['samba2']['status']= TRUE;
165   }
167   /* Check pureftp/dns/ */
168   if (!isset($objectclasses['PureFTPdUser'])){
169     $messages['pureftp']['msg']= _("Support for pureftp disabled, no schema seems to be installed");
170     $affich['pureftp']['msg']= $messages['pureftp']['msg']."<td class=\"check\">pureftpd.schema</td>";
171     $messages['pureftp']['status']= FALSE;
172     $affich['pureftp']['status']= FALSE;
173   }else{
174     $affich['pureftp']['msg']= _("Support for pureftp enabled")."<td class=\"check\">pureftpd.schema</td>";
175     $affich['pureftp']['status']= TRUE;
176   }
178   if (!isset($objectclasses['gosaWebdavAccount'])){
179     $messages['webdav']['msg']= _("Support for WebDAV disabled, no schema seems to be installed");
180     $affich['webdav']['msg']= $messages['webdav']['msg']."<td class=\"check\"></td>";
181     $messages['webdav']['status']= FALSE;
182     $affich['webdav']['status']= FALSE;
183   }else{
184     $affich['webdav']['msg']=_("Support for WebDAV enabled")."<td class=\"check\">gosa+samba3.schema</td>";
185     $affich['webdav']['status']= TRUE;
186   }
188   if (!isset($objectclasses['phpgwAccount'])){
189     $messages['phpgroupware']['msg']= _("Support for phpgroupware disabled, no schema seems to be installed");
190     $affich['phpgroupware']['msg']= $messages['phpgroupware']['msg']."<td class=\"check\">phpgwaccount.schema</td>";
191     $messages['phpgroupware']['status']= FALSE;
192     $affich['phpgroupware']['status']= FALSE;
193   }else{
194     $affich['phpgroupware']['msg']= _("Support for phpgroupware enabled")."<td class=\"check\">phpgwaccount.schema</td>";
195     $affich['phpgroupware']['status']= TRUE;
196   }
197   
198   if (!isset($objectclasses['trustAccount'])){
199     $messages['trustAccount']['msg']= _("Support for trustAccount disabled, no schema seems to be installed");
200     $affich['trustAccount']['msg']= $messages['trustAccount']['msg']."<td class=\"check\">trust.schema</td>";
201     $messages['trustAccount']['status']= FALSE;
202     $affich['trustAccount']['status']= FALSE;
203   }else{
204     $affich['trustAccount']['msg']= _("Support for trustAccount enabled")."<td class=\"check\">trust.schema</td>";
205     $affich['trustAccount']['status']= TRUE;
206   }
208   if (!isset($objectclasses['goFonAccount'])){
209     $messages['phoneaccount']['msg']= _("Support for gofon disabled, no schema seems to be installed");
210     $affich['phoneaccount']['msg']= $messages['phoneaccount']['msg']."<td class=\"check\">gofon.schema</td>";
211     $messages['phoneaccount']['status']= FALSE;
212     $affich['phoneaccount']['status']= FALSE;
213   }else{
214     $affich['phoneaccount']['msg']= _("Support for gofon enabled")."<td class=\"check\">gofon.schema</td>";
215     $affich['phoneaccount']['status']= true;
216   }
218   if (!isset($objectclasses['nagiosContact'])){
219     $messages['nagioscontact']['msg']= _("Support for nagios disabled, no schema seems to be installed");
220     $affich['nagioscontact']['msg']= $messages['nagioscontact']['msg']."<td class=\"check\">nagios.schema</td>";
221     $messages['nagioscontact']['status']= FALSE;
222     $affich['nagioscontact']['status']= FALSE;
223   }else{
224     $affich['nagioscontact']['msg']= _("Support for nagios enabled")."<td class=\"check\">nagios.schema</td>";
225     $affich['nagioscontact']['status']= true;
226   }
227   
228   if ((!isset($objectclasses['apple-user'])) || (!isset($objectclasses['mount'])) ){
229     $messages['netatalk']['msg']= _("Support for netatalk disabled, no schema seems to be installed");
230     $affich['netatalk']['msg']= $messages['netatalk']['msg']."<td class=\"check\">apple.schema</td>";
231     $messages['netatalk']['status']= FALSE;
232     $affich['netatalk']['status']= FALSE;
233   }else{
234     $affich['netatalk']['msg']= _("Support for netatalk enabled")."<td class=\"check\">apple.schema</td>";
235     $affich['netatalk']['status']= true;
236   }
237   
238   /* Fix for PHP Fehler "Undefined index: ldapconf"
239    * Ablaufverfolgung[1]: Funktion schema_check Datei: /home/hickert/gosa/include/functions_setup.inc (Zeile 230)
240    */
241   if((isset($_SESSION['ldapconf']['mail_methods']))&&(isset($_SESSION['ldapconf']))){
242         if(($_SESSION['ldapconf']['mail_methods'][$_SESSION['ldapconf']['mail']] == "kolab")&&(!$CalledByIndexPhP)){
243           if(!isset($objectclasses['kolabInetOrgPerson']))  {
244             $messages['kolab']['msg']= _("Support for Kolab disabled, no schema seems to be installed, setting mail-method to cyrus");
245             $affich['kolab']['msg']=$messages['kolab']['msg']."<td class=\"check\">kolab2.schema</td>";
246             $tmp= array_flip($_SESSION['ldapconf']['mail_methods']);
247             $_SESSION['ldapconf']['mail']=$tmp['cyrus'];
248             $messages['kolab']['status']= FALSE;
249             $affich['kolab']['status']= FALSE;
250           }else{
251             $affich['kolab']['msg']=_("Support for Kolab enabled")."<td class=\"check\">gofon.schema</td>";
252             $affich['kolab']['status']= TRUE;
253           }
254         }
255   }
256   if($aff==0){
257     return ($messages);
258   } else {
259     return(array_merge($affich,$affich2));
260   }
264 function check(&$faults, $message, $description, $test, $required= TRUE)
266   $msg= "<table summary=\"\" class='check'><tr><td class='check' style='font-size:14px;'>$message</td>
267     <td rowspan=2 style='vertical-align:middle; text-align:center;width:45px;'>";
268   if ($test){
269     $msg.= _("OK")."<br>";
270   } else {
271     if (!$required){
272       $msg.="<font color=red>"._("Ignored")."</font><br>";
273     } else {
274       $msg.="<font color=red>"._("Failed")."</font><br>";
275       $faults++;
276     }
277   }
278   $msg.= "</td></tr><tr><td class='check' style='padding-left:20px;".
279     "background-color:#F0F0F0;'>$description</td></tr></table><br>";
281   return $msg;
284 function perform_php_checks(&$faults)
286   global $check_globals;
288   $faults= 0;
289   $msg= "";
291   $msg.= "<h1>"._("PHP setup inspection")."</h1>";
293   $msg.= check (        $faults, _("Checking for PHP version (>=4.1.0)"),
294       _("PHP must be of version 4.1.0 or above for some functions and known bugs in PHP language."),
295       version_compare(phpversion(), "4.1.0")>=0);
297   $msg.= check (        $faults, _("Checking if register_globals is set to 'off'"),
298       _("register_globals is a PHP mechanism to register all global varibales to be accessible from scripts without changing the scope. This may be a security risk. GOsa will run in both modes."),
299       $check_globals == 0, FALSE);
300   
301   $msg.= check (  $faults, _("PHP session.gc_maxlifetime (>= 86400 seconds)."),
302       _("PHP uses this value for the garbage collector to delete old sessions, setting this value to one day will prevent loosing session and cookie  before they really timeout."),
303       ini_get("session.gc_maxlifetime") >= 86400,FALSE);
305   $msg.= check (        $faults, _("Checking for ldap module"),
306       _("This is the main module used by GOsa and therefore really required."),
307       is_callable('ldap_bind'));
309   $msg.= check (  $faults, _("Checking for XML functions"),
310       _("XML functions are required to parse the configuration file."),
311       is_callable('xml_parser_create'));
313   $msg.= check (        $faults, _("Checking for gettext support"),
314       _("Gettext support is required for internationalized GOsa."),
315       is_callable('bindtextdomain'));
317   $msg.= check (        $faults, _("Checking for iconv support"),
318       _("This module is used by GOsa to convert samba munged dial informations and is therefore required."),
319       is_callable('iconv'));
321   $msg.= check (        $faults, _("Checking for mhash module"),
322       _("To use SSHA encryption, you'll need this module. If you are just using crypt or md5 encryption, ignore this message. GOsa will run without it."),
323       is_callable('mhash'), FALSE);
325   $msg.= check (        $faults, _("Checking for imap module"),
326       _("The IMAP module is needed to communicate with the IMAP server. It gets status informations, creates and deletes mail users."),
327       is_callable('imap_open'));
329   $msg.= check (        $faults, _("Checking for getacl in imap"),
330       _("The getacl support is needed for shared folder permissions. The standard IMAP module is not capable of reading acl's. You need a recend PHP version for this feature."),
331       is_callable('imap_getacl'), FALSE);
333   $msg.= check (        $faults, _("Checking for mysql module"),
334       _("MySQL support is needed for reading GOfax reports from databases."),
335       is_callable('mysql_query'), FALSE);
337   $msg.= check (        $faults, _("Checking for cups module"),
338       _("In order to read available printers from IPP protocol instead of printcap files, you've to install the CUPS module."),
339       is_callable('cups_get_dest_list'), FALSE);
341   $msg.= check (        $faults, _("Checking for kadm5 module"),
342       _("Managing users in kerberos requires the kadm5 module which is downloadable via PEAR network."),
343       is_callable('kadm5_init_with_password'), FALSE);
345   $msg.= check (  $faults, _("Checking for snmp Module"),
346       _("Simple Network Management Protocol (SNMP) is required for client monitoring."),
347       is_callable('snmpget'), FALSE);
349   return ($msg);
352 function get_link($function_name) {
353   $result= "<a href='http://de.php.net/manual/en/function.";
355   /* Replace all underscores with hyphens (phpdoc convention) */
356   $function_name= str_replace("_", "-", $function_name);
358   /* Append to base URL */
359   $result.= $function_name.".php'>$function_name</a>";
361   return $result;
364 function perform_additional_function_checks(&$faults) {
365   global $check_globals;
367   $faults= 0;
368   $msg= "";
369   $functions= array();
370   
371   $functions_list= '../include/functions_list.inc';
373   /* Make sure that we can read the file */
374   if(is_readable($functions_list)) {
375     /* Open filehandle */
376     $fh= fopen($functions_list,'rb');
377     if($fh!=null) {
378       $functions= eval(fread($fh,filesize($functions_list)));
379     }
380   }
382   $msg.= "<h1>"._("PHP detailed function inspection")."</h1>";
383   /* Only print message, if function is not callable */
384   foreach($functions as $key => $fn_name) {
385     if(!is_callable($fn_name)) {
386       $msg.= check ($faults, sprintf(_("Checking for function %s"), "<b>".get_link($fn_name)."</b>"),
387         sprintf(_("The function %s is used by GOsa. There is no information if it's optional or required yet."), "<b>".get_link($fn_name)."</b>"),
388         is_callable($fn_name), false);
389     }
390   }
391   return $msg;
394 function perform_additional_checks(&$faults)
396   $ret = NULL;
397   /* Programm check */
398   $msg= "<h1>"._("Checking for some additional programms")."</h1>";
400   /* Image Magick */
401   $query= "LC_ALL=C LANG=C convert -help";
402   $output= shell_exec ($query);
403   if ($output != ""){
404     $lines= split ("\n", $output);
405     $version= preg_replace ("/^Version:.+Magick ([^\s]+).*/", "\\1", $lines[0]);
406     list($major, $minor)= split("\.", $version);
407     $msg.= check (      $faults, _("Checking for ImageMagick (>=5.4.0)"),
408         _("ImageMagick is used to convert user supplied images to fit the suggested size and the unified JPEG format."),
409         ($major > 5 || ($major == 5 && $minor >= 4)));
410   } else {
411     $msg.= check (      $faults, _("Checking imagick module for PHP"),
412         _("Imagick is used to convert user supplied images to fit the suggested size and the unified JPEG format from PHP script."), function_exists('imagick_blob2image'), TRUE);
413   }
415   /* Check for fping */
416   $query= "LC_ALL=C LANG=C fping -v 2>&1";
417   $output= shell_exec ($query);
418   $have_fping= preg_match("/^fping:/", $output);
419   $msg.= check (        $faults, _("Checking for fping utility"),
420       _("The fping utility is only used if you've got a thin client based terminal environment running."),
421       $have_fping, FALSE);
423   /* Check for smb hash generation tool */
424   $query= "mkntpwd 2>&1";
425   $output= shell_exec ($query);
426   $have_mkntpwd= preg_match("/^Usage: mkntpwd /", $output);
427   $alt = 0;
429   if (!$have_mkntpwd){
430     $query= "LC_ALL=C LANG=C perl -MCrypt::SmbHash -e 'ntlmgen \"PASSWD\", \$lm, \$nt; print \"\${lm}:\${nt}\\n\";' &>/dev/null";
431     system ($query, $ret);
432     $alt= ($ret == 0);
433   }
435   $msg.= check (        $faults, _("Checking for a way to generate LM/NT password hashes"),
436       _("In order to use SAMBA 2/3, you've to install some additional packages to generate password hashes."),
437       ($have_mkntpwd || $alt));
439   /* seesio.auto_start should be off, in order to without trouble*/
440   $session_auto_start = ini_get('session.auto_start');
441   $implicit_flush     = ini_get('implicit_flush');
442   $max_execution_time = ini_get('max_execution_time');
443   $memory_limit       = ini_get('memory_limit');
444   $expose_php         = ini_get('expose_php');
445   $magic_quotes_gpc   = ini_get('magic_quotes_gpc');
446   $register_globals   = ini_get('register_globals');
448   /* auto_register */
449   $msg.= check (  $faults, _("php.ini check -> session.auto_register"),
450       _("In Order to use GOsa without any trouble, the session.auto_register option in your php.ini must be set to 'Off'."), (!$session_auto_start['local_value']));
452   /* implicit_flush */
453   $msg.= check (  $faults, _("php.ini check -> implicit_flush"),
454       _("This option influences the Output handling. Turn this Option off, to increase performance."),
455       !$implicit_flush['local_value'],0,false);
457   /* max_execution_time */
458   if($max_execution_time['local_value'] < 30 ){
459     $max_execution_time['local_value']=false;
460   }
461   $msg.= check (  $faults, _("php.ini check -> max_execution_time"),
462       _("The Execution time should be at least 30 seconds, because some actions may consume more time."),
463       $max_execution_time['local_value'],0,false);
465   /* memory_limit */
466   if($memory_limit['local_value'] < 16 ){
467     $memory_limit['local_value']=false;
468   }
469   $msg.= check (  $faults, _("php.ini check -> memory_limit"),
470       _("GOsa needs at least 16MB of memory, less will cause unpredictable errors! Increase it for larger setups."),
471       !$implicit_flush['local_value'],0,false);
473   /* expose_php */
474   $msg.= check (  $faults, _("php.ini check -> expose_php"),
475       _("Increase the server security by setting expose_php to 'off'. PHP won't send any Information about the server you are running in this case."),
476       !$implicit_flush['local_value'],0,false);
478   /* magic_quotes_gpc */
479   $msg.= check (  $faults, _("php.ini check -> magic_quotes_gpc"),
480       _("Increase your server security by setting magic_quotes_gpc to 'on'. PHP will escape all quotes in strings in this case."),
481       $magic_quotes_gpc['local_value'],0,false);
483   return $msg;
487 function parse_contrib_conf()
490   $str                = "";
491   $used_samba_version = 0;
492   $query              = ""; 
493   $fp                 = false;
494   $output             = "";
495   $needridbase_sid    = false;
496   $pwdhash            = "";
497   $replacements       = array();
498   $ldapconf           = $_SESSION['ldapconf']; // The Installation information
499   $classes            = $_SESSION['classes'];  // Class information needed to define which features are enabled
500   $possible_plugins   = array();
502   /* Which samba version do we use? */
503   if(isset($classes['samba3'])){
504     $used_samba_version = 2;
505   } else {
506     $used_samba_version = 3;
507   }
509   /* Look for samba password generation method */
510   if(file_exists("/usr/bin/mkntpasswd")){
511     $pwdhash  = "/usr/bin/mkntpasswd";
512   } elseif (preg_match("/^Usage: mkntpwd /", shell_exec ("mkntpwd 2>&1"))){
513     $pwdhash= "mkntpwd";
514   } else {
515     $pwdhash=('perl -MCrypt::SmbHash -e "ntlmgen \"\$ARGV[0]\", \$lm, \$nt; print \"\${lm}:\${nt}\n\";" $1');
516   }
519   /* Define which variables will be replaced */
520   $replacements['{LOCATIONNAME}']  = $ldapconf['location'];
521   $replacements['{SAMBAVERSION}']  = $used_samba_version;
522   $replacements['{LDAPBASE}']      = $ldapconf['base'];
523   $replacements['{LDAPADMIN}']     = $ldapconf['admin'];
524   $replacements['{UIDBASE}']       = $ldapconf['uidbase'];
525   $replacements['{DNMODE}']        = $ldapconf['peopledn'];
526   $replacements['{LDAPHOST}']      = $ldapconf['uri'];
527   $replacements['{PASSWORD}']      = $ldapconf['password'];
528   $replacements['{CRYPT}']         = $ldapconf['arr_cryptkeys'][$ldapconf['arr_crypts']];
529   $replacements['{SID}']         = "";
530   $replacements['{RIDBASE}']     = "";
531   if($ldapconf['mail'] != "disabled"){
532     $replacements['{MAILMETHOD}']    = $ldapconf['mail_methods'][$ldapconf['mail']];
533   }   
534   $replacements['{SMBHASH}']       = $pwdhash;
535   $replacements['{GOVERNMENTMODE}']= "false"; 
536   $replacements['{kolabAccount}']  = "";
537   $replacements['{servKolab}']     = "";
538   $replacements['{errorlvl}']     = $ldapconf['errorlvl'];
540   /* This array contains all preg_replace syntax to delete all unused plugins
541      THE kEY MUST BE THE CLASSNAME so we can check it with $ldapconf['classes'] */
543   $possible_plugins['fonreport'][]   = "'\n.*<plugin.*fonreport+.*\n.*>.*\n'i";
544   $possible_plugins['phoneaccount'][]= "'\n.*<tab.*phoneAccount.*>.*\n'i";
545   $possible_plugins['logview'][]     = "'\n.*<plugin.*logview+.*\n.*>.*\n'i";
546   $possible_plugins['pureftp'][]     = "'\n.*<tab.*pureftp.*>.*\n'i";
547   $possible_plugins['webdav'][]      = "'\n.*<tab.*webdav.*>.*\n'i";
548   $possible_plugins['phpgroupware'][]= "'\n.*<tab.*phpgroupware.*>.*\n'i";
549   $possible_plugins['netatalk'][0]    = "'\n.*<plugin.*netatalk+.*\n.*>.*\n'i";
550   $possible_plugins['netatalk'][1]    = "'\n.*<tab.*netatalk.*>.*\n'i";
552   /*Header information
553      Needed to send the generated gosa.conf to the browser */
554   header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
555   header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
556   header("Cache-Control: no-cache");
557   header("Pragma: no-cache");
558   header("Cache-Control: post-check=0, pre-check=0");
559   header("Content-type: text/plain");
561   if (preg_match('/MSIE 5.5/', $_SERVER['HTTP_USER_AGENT']) ||
562       preg_match('/MSIE 6.0/', $_SERVER['HTTP_USER_AGENT'])){
563     header('Content-Disposition: filename="gosa.conf"');
564   } else {
565     header('Content-Disposition: attachment; filename="gosa.conf"');
566   }
568   if(!$fp=fopen(CONFIG_TEMPLATE_DIR."/gosa.conf","r")) {
569     echo "Can't open file ".CONFIG_TEMPLATE_DIR."/gosa.conf";
570   } else {
571     while(!feof($fp)) {
572       $str.= fread($fp,512);
573     }
575     if($ldapconf['mail_methods'][$ldapconf['mail']]=="kolab") {
576       $replacements['{kolabAccount}']  ="<tab class=\"kolabAccount\" />\n     ";
577       $replacements['{servKolab}']     ="<tab class=\"servkolab\" name=\"Kolab\" />";
578     }
580     if($used_samba_version == 2) {
581       /* Do nothing for samba 2... */
582     } else {
583       /* Create LDAP connection, to check if there's a domain
584          object defined in the LDAP schema */
585       $ldap= new LDAP($ldapconf['admin'], $ldapconf['password'], $ldapconf['uri']);
587       /* Try to find a Samba Domain Objekt */
588       $ldap->search("(objectClass=sambaDomain)");
589     
590       /* Something found ??? so we need to define ridbase an SID by ourselfs */
591       if($ldap->count()< 1) {
592         $replacements['{SID}']= "sid=\"123412-11\"";
593         $replacements['{RIDBASE}']= "ridbase=\"1000\"";  
594       } 
595     }
597     /* Data readed, types replaced, samba version detected and checked if
598        we need to add SID and RIDBASE. Check if there is an ivbbentry in
599        the LDAP tree, in this case we will set the governmentmode to true.
600        Create LDAP connection, to check if theres a domain Objekt definen
601        in the LDAP schema. */
602     if(!isset($ldap)){
603       $ldap= new LDAP($ldapconf['admin'], $ldapconf['password'], $ldapconf['uri']);
604     }
606     /* Try to find a Samba Domain Objekt */
607     $ldap->search("(objectClass=ivbbentry)");
609     /* Something found ??? so we need to define ridbase an SID by ourselfs */
610     if($ldap->count()> 0) {
611       $replacements['{GOVERNMENTMODE}']= "true";
612     }
614     /* Replace all colleted information with placeholder */
615     foreach($replacements as $key => $val) {
616       $str = preg_replace("/".$key."/",$val,$str);
617     }    
619     if($ldapconf['mail'] == "disabled"){
620       $str = str_replace("mailMethod=\"{MAILMETHOD}\"","",$str);
621     }
623     /* Remove all unused plugins */
624     foreach(array_keys($possible_plugins) as $akey) {
625       if(array_key_exists($akey,$classes)) {
626         foreach($possible_plugins[$akey] as $key=>$val) {
627           $str = preg_replace($val,"\n",$str);
628         }
629       }
630     }
631   }
633   return ((($str)));
637 /* Show setup_page 1 */
638 function show_setup_page1($withoutput = true)
640   $faults = array();
641   $smarty = get_smarty();  
642   $smarty->assign ("content", get_template_path('setup_introduction.tpl'));
643   $smarty->assign ("tests", perform_php_checks($faults));
644   $smarty->assign ("detailed_tests", perform_additional_function_checks($faults));
646   /* This var is true if anything went wrong */
647   if ($faults){
648     $smarty->assign("mode", "disabled");
649   }
651   /* This line displays the template only if (withoutput is set) */
652   if($withoutput){
653     $smarty->display (get_template_path('headers.tpl'));
654   }
656   if (isset($_SESSION['errors'])){
657     $smarty->assign("errors", $_SESSION['errors']);
658   }
660   if($withoutput){
661     $smarty->display (get_template_path('setup.tpl'));
662   }
664   return (!$faults);
668 /* Show setup_page 2 */
669 function show_setup_page2($withoutput = true)
671   $faults = array();
672   $smarty = get_smarty();
673   $smarty->assign ("content", get_template_path('setup_step2.tpl'));
674   $smarty->assign ("tests", perform_additional_checks($faults));
676   if ($faults) {
677     $smarty->assign("mode", "disabled");
678   }
679   if($withoutput){
680     $smarty->display (get_template_path('headers.tpl'));
681   }
682   if (isset($_SESSION['errors']))  {
683     $smarty->assign("errors", $_SESSION['errors']);
684   }
685   if($withoutput){
686     $smarty->display (get_template_path('setup.tpl'));
687   }
689   return (!$faults);                               
693 function show_setup_page3($withoutput = true)
695   $ds = NULL;
696   $smarty = get_smarty();
698   /* Take the Post oder the Sessioin saved data */
699   if(isset($_POST['uri'])){
700     $uri = $_POST['uri'];
701   } elseif(isset($_SESSION['ldapconf']['uri'])){
702     $uri = $_SESSION['ldapconf']['uri'];
703   }
705   /* If Page called first time, field is empty */
706   if((!isset($uri))||(empty($uri))){
707     $uri = "ldap://localhost:389";
708   }
710   /* if isset $uri save it to session */
711   if(isset($uri)) {
712     $_SESSION['ldapconf']['uri'] = $uri;
713     $smarty->assign ("uri", validate($uri));
714   }
716   /* No error till now */
717   $fault = false;
719   /* If we pushed the Button continue */
720   if(isset($_POST['continue3'])){
721     if(!isset($uri)) {
722       $fault = true;
724       /* Output the Error */
725       if($withoutput) {
726         print_red (_("You've to specify an ldap server before continuing!"));
727         $smarty->assign ("content", get_template_path('setup_step3.tpl'));
728       }
729     }
730   } elseif (!$ds = @ldap_connect (validate($uri))) {
731     $fault =true;
733     /* Output the Error */
734     if($withoutput) {
735       print_red (_("Can't connect to the specified LDAP server! Please make sure that is reachable for GOsa."));
736       $smarty->assign ("uri", validate($uri));
737       $smarty->assign ("content", get_template_path('setup_step3.tpl'));
738     }
739   } else {
740     /* Try to bind the connection */    
741     ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
743     /* if we can't bind , print error */
744     if (!$r  =  @ldap_bind ($ds)) {
745       $fault = true;
747       /* Output the Error */
748       if($withoutput) {
749         print_red (_("Can't bind to the specified LDAP server! Please make sure that it is reachable for GOsa."));
750         $smarty->assign ("content", get_template_path('setup_step3.tpl'));
751         $smarty->assign ("uri", validate($uri));
752       }
753     } else {
754       $fault = false;
755     }
756   }
758   $smarty->assign ("content", get_template_path('setup_step3.tpl'));
760   /* Load Header */
761   if($withoutput){
762     $smarty->display (get_template_path('headers.tpl'));
763   }
765   /* Set Errors to Smarty */
766   if (isset($_SESSION['errors'])) {
767     $smarty->assign("errors", $_SESSION['errors']);
768   }
770   /* Print out Template */ 
771   if($withoutput){
772     $smarty->display (get_template_path('setup.tpl'));
773   }
775   return (!$fault);                             
779 function show_setup_page4($withoutput = true)
781   $smarty= get_smarty();      
783         // ?
784   if(!isset($_SESSION['ldapconf']['base'])){
785     $_SESSION['ldapconf']['base']= $base;
786   }
788   if(!isset($_SESSION['ldapconf']['base'])){
789     $_SESSION['ldapconf']['base']= $base;
790   }
791   require_once("class_password-methods.inc");
793   $fault     = false;              
794   $uri       = $_SESSION['ldapconf']['uri'];
795   $ldapconf  = $_SESSION['ldapconf'];
796   $arr_crypts= array();
797   $temp      = "";
798   $checkvars = array("location", "admin", "password", "peopleou", "base",
799       "peopledn", "arr_crypts", "mail", "uidbase","errorlvl");
801   if(!isset($_SESSION['ldapconf']['arr_cryptkeys'])) {
802     require_once("class_password-methods.inc");
803     $tmp= passwordMethod::get_available_methods_if_not_loaded();
804     $_SESSION['ldapconf']['arr_cryptkeys']= $tmp['name'];
805   }
807   if(!isset($_SESSION['ldapconf']['mail_methods'])) {
808     $_SESSION['ldapconf']['mail_methods']=array();
809     $temp = get_available_mail_classes();
810     $_SESSION['ldapconf']['mail_methods']= $temp['name'];
811   }
813   /* If there are some empty vars in ldapconnect -
814      these values also represent out default values */
815   if(!$ds = @ldap_connect (validate($uri))){
816     $fault = true;
817     if($withoutput){
818       print_red (_("Can't connect to the specified LDAP server! Please make sure that is reachable for GOsa."));
819     }
820   } elseif(!@ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)){
821     $fault = true;
822     if($withoutput){
823       print_red (_("Can't bind to the specified LDAP server! Please make sure that it is reachable for GOsa."));
824     }
825   } elseif(!$r= @ldap_bind ($ds)){
826     $fault = true;
827     if($withoutput){
828       print_red (_("Can't bind to the specified LDAP server! Please make sure that it is reachable for GOsa."));
829     }
830   } else {
831     $sr=   @ldap_search ($ds, NULL, "objectClass=*", array("namingContexts"));
832     $attr= @ldap_get_entries($ds,$sr);
834     if((empty($attr))) {
835       $base= "dc=example,dc=net";
837       if($withoutput){
838         print_red(_("Bind to server successful, but the server seems to be completly empty, please check all information twice"));
839       }
841     } else {
842       $base= $attr[0]['dn'];
843     }
844   }
846   if(!isset($_SESSION['ldapconf']['base'])){
847     $_SESSION['ldapconf']['base']= $base;
848   }
849   if(!isset($_SESSION['ldapconf']['admin'])){
850     $_SESSION['ldapconf']['admin']= "cn=ldapadmin,".$base;
851   }
852   if(!isset($_SESSION['ldapconf']['peopleou'])){
853     $_SESSION['ldapconf']['peopleou']= "ou=people";
854   }
855   if(!isset($_SESSION['ldapconf']['groupou'])){
856     $_SESSION['ldapconf']['groupou']= "ou=groups";
857   }
858   if(!isset($_SESSION['ldapconf']['peopledn'])){
859     $_SESSION['ldapconf']['peopledn']= "cn";
860   }
861   if(!isset($_SESSION['ldapconf']['password'])){
862     $_SESSION['ldapconf']['password']= "";
863   }
864   if(!isset($_SESSION['ldapconf']['location'])){
865     $_SESSION['ldapconf']['location']= "Example";
866   }
867   if(!isset($_SESSION['ldapconf']['uidbase'])){
868     $_SESSION['ldapconf']['uidbase']= "1000";
869   }
870   if(!isset($_SESSION['ldapconf']['mail'])){
871     $_SESSION['ldapconf']['mail']= 0;
872   }
873   $tmp= array_flip($_SESSION['ldapconf']['arr_cryptkeys']);
874   if(!isset($_SESSION['ldapconf']['arr_crypts'])){
875     $_SESSION['ldapconf']['arr_crypts']   = $tmp['md5'];
876   }
878   /* check POST data */
879   if(isset($_POST['check'])) {
881     /* Check if all needed vars are submitted */
882     foreach($checkvars as $key) {
883       if($key == "peopleou"){
884         continue;
885       }
886       if($key == "groupou"){
887         continue;
888       }
890       if((isset($_POST[$key]))&&($_POST[$key]!="")) {
891         $_SESSION['ldapconf'][$key] = $_POST[$key];
892       } else {
893         if($withoutput) {
894           print_red(sprintf(_("You're missing the required attribute '%s' from this formular. Please complete!"), $key));
895         }
896         $fault = true;
897       }
898     }
899   }
901   /* Transfer base */
902   if(isset($_POST['base'])){
903     $_SESSION['ldapconf']['base']= $_POST['base'];
904   }
906   $smarty->assign("arr_cryptkeys",$_SESSION['ldapconf']['arr_cryptkeys']);
907   $smarty->assign("mail_methods", $_SESSION['ldapconf']['mail_methods']);
909   foreach($_SESSION['ldapconf'] as $key => $val) {
910     $smarty->assign($key,$val);
911   }
913   if(isset($_POST['check'])) {
914     $ldap= new LDAP($_SESSION['ldapconf']['admin'],
915         $_SESSION['ldapconf']['password'],
916         $_SESSION['ldapconf']['uri']);
918     $m= schema_check($_SESSION['ldapconf']['uri'],
919         $_SESSION['ldapconf']['admin'],
920         $_SESSION['ldapconf']['password']);
921     $_SESSION['classes']= $m;
923     if(!is_schema_readable($ldapconf['uri'],$ldapconf['admin'],$ldapconf['password'])){
924       if($withoutput){
925         print_red(_("Can't read schema informations, GOsa needs to know your schema setup. Please verify that it is readable for GOsa"));
926       }
927       $fault=true;
928     }
932     if ($ldap->error != "Success") {
933       if($withoutput) {
934         print_red(sprintf(_("Can't log into LDAP server. Reason was: %s."), $ldap->get_error()));
935       }
936       $fault = true;
937     }
938   }
940   /* Set smarty output */
941   $smarty->assign ("content", get_template_path('setup_step4.tpl'));
942   $smarty->assign ("peopledns", array("cn", "uid"));
943   if($withoutput){
944     $smarty->display (get_template_path('headers.tpl'));
945   }
946   if(isset($_SESSION['errors'])) {
947     $smarty->assign("errors", $_SESSION['errors']);
948   }
949   if($withoutput){
950     $smarty->display (get_template_path('setup.tpl'));
951   }
952   return (!$fault);
956 function show_setup_page5($withoutput=true)
958   /* Get ldapconf */
959   $ldapconf= $_SESSION['ldapconf'];
961   /* get smarty */
962   $smarty = get_smarty();
964   if(isset($_SESSION['classes'])){
965     $classes = $_SESSION['classes'];
966   }
968   $info= posix_getgrgid(posix_getgid());
969   $smarty->assign("webgroup", $info['name']);
970   $smarty->assign("path", CONFIG_DIR);
971   $message= "<table summary=\"\" class=\"check\">";
972   $m= schema_check($ldapconf['uri'], $ldapconf['admin'], $ldapconf['password'],1);
974   if($withoutput) {
975     $smarty->assign ("schemas", view_schema_check($m));
976     $smarty->assign ("content", get_template_path('setup_finish.tpl'));
977   }
979   /* Output templates... */
980   if($withoutput){
981     $smarty->display (get_template_path('headers.tpl'));
982   }
983   if (isset($_SESSION['errors'])) {
984     $smarty->assign("errors", $_SESSION['errors']);
985   }
986   if($withoutput){
987     $smarty->display (get_template_path('setup.tpl'));
988   }
990   return(true);
994 function create_user_for_setup($withoutput=true)
996   global $samba;
998   $ldapconf = $_SESSION['ldapconf'];
999   $smarty = get_smarty();
1000   
1001   $need_to_create_group = false;
1002   $need_to_create_user  = false;
1004   $str_there="";
1006   if(isset($_SESSION['classes'])){
1007     $classes= $_SESSION['classes'];
1008   }
1010   /* Everything runns perfect ...
1011      So we do a last test on this page
1012      is there a user with ACLs :all which will be able to adminsitrate GOsa
1013      We check that, if this user or group is missing we ask for creating them */
1014   $ldap= new LDAP($_SESSION['ldapconf']['admin'],    $_SESSION['ldapconf']['password'],   $_SESSION['ldapconf']['uri']);
1016   /* 
1017   Now we are testing for a group, with the rights :all 
1018   */
1019   
1020   $ldap->cd($ldapconf['base']);
1021   $ldap->search("(&(objectClass=gosaObject)(gosaSubtreeACL=:all))");
1023   $group_cnt  = $ldap->count();
1024   $data       = $ldap->fetch();
1026 //  $str_there  = "Searching for Aminitrative users <br><br>";
1028   /* 
1029   We need to create administrative user and group  because theres no group found 
1030   */
1031   if($group_cnt < 1) {
1032     
1033     /* 
1034     Set var to create user 
1035     */
1036 //    $str_there  =   "no group found<br>";
1038     $need_to_create_group = true;
1039     $need_to_create_user  = true;
1042     /* Output error */
1043     if(($withoutput)&&(!isset($_POST['new_admin']))){
1044       print_red(_("You're missing an administrative account for GOsa, you'll not be able to administrate anything!"));
1045     }
1046   } else {
1047     
1048 //    $str_there = "Group found <br>".$data['dn'];    
1050     $need_to_create_group = false;
1051  
1052     $ldap->clearResult();
1053    
1054     /* We found an Administrative Group, is there a user, too */
1055     if(isset($data['memberUid'][0])) {
1056       $str = "uid=".$data['memberUid']['0'];
1057       $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)(".$str."))");
1058       $data2   = $ldap->fetch();
1059   
1060       /* We must create a user */
1061       if (($ldap->count() < 1)||(!isset($data2))) {
1062 //        $str_there.="Missing user";
1063         
1064         $need_to_create_user = true;
1065       
1066         if(($withoutput)&&(!isset($_POST['new_admin']))){
1067           print_red(_("You're missing an administrative account for GOsa, you'll not be able to administrate anything!"));
1068         }
1069       }else {
1070 //        $str_there.="<br>User found <br>".$data2['dn'];
1071         $need_to_create_user = false;
1072       }
1073     } else {
1074       $need_to_create_user=true;
1075       if(($withoutput)&&(!isset($_POST['new_admin']))){
1076           print_red(_("You're missing an administrative account for GOsa, you'll not be able to administrate anything!"));
1077         }   
1078 //      $str_there.="<br>No User found <br>";
1079     }
1080   }
1082   if(!($need_to_create_user&&$need_to_create_group))
1083     return(true);
1085   /* We need to create a new user with group */
1086   if(isset($_POST['new_admin']))
1087   {
1088   
1089     /* Adjust password attributes according to the samba version */
1090     if (isset($classes['samba3'])) {
1091       $samba= "2";
1092       $lmPassword = "lmPassword";
1093       $ntPassword = "ntPassword";
1094     } else {
1095       $samba= "3";
1096       $lmPassword = "sambaLMPassword";
1097       $ntPassword = "sambaNtPassword";
1098     }
1100     /* Nothing submitted */
1101     if(((empty($_POST['admin_name']))||(empty($_POST['admin_pass'])))) {
1102       return(true);
1103     }
1105     if($need_to_create_user) {
1106       /* We have the order to create an Admin */
1107       /* Define the user we are going to create */
1108       $dn= "cn=".$_POST['admin_name'].",".$ldapconf['peopleou'].",".$ldapconf['base'];
1109       $arr['objectClass'][0] ="person";
1110       $arr['objectClass'][1] ="organizationalPerson";
1111       $arr['objectClass'][2] ="inetOrgPerson";
1112       $arr['objectClass'][3] ="gosaAccount";
1113       $arr['uid']            = $_POST['admin_name'];
1114       $arr['cn']             = $_POST['admin_name'];
1115       $arr['sn']             = $_POST['admin_name'];
1116       $arr['givenName']      = "GOsa main administrator";
1117       $arr[$lmPassword]      = "10974C6EFC0AEE1917306D272A9441BB";
1118       $arr[$ntPassword]      = "38F3951141D0F71A039CFA9D1EC06378";
1119       $arr['userPassword']   = crypt_single($_POST['admin_pass'],"md5");
1120     
1122       if(!$ldap->dn_exists($dn)){ 
1123         $ldap->cd($dn); 
1124         $ldap->create_missing_trees($dn);
1125         $ldap->cd($dn);
1126         $ldap->add($arr);
1127         if($ldap->error!="Success"){
1128           print_red($ldap->error);
1129           print_red("Can't create user, and / or Group, possibly this problem  depends on an empty LDAP server. Check your configuration and try again!");
1130         }
1131       }    
1132     }
1134     /* There's already a group for administrator, so we only need to add the user */
1135     if(!$need_to_create_group) {
1136       if(!isset($data['memberUid'])) {
1137         $arrr['memberUid']= $_POST['admin_name'];
1138       } else {
1139         $data['memberUid'][$data['memberUid']['count']]=$_POST['admin_name'];
1140         $arrr['memberUid'] = $data['memberUid'];
1141         unset($arrr['memberUid']['count']);
1142   
1143         $tmp = array_reverse($arrr['memberUid']);    
1144         foreach($tmp as $tt){
1145           $tmp2[]=$tt;
1146         }
1147         $arrr['memberUid']= $tmp2;
1148 //        $str_there="Group found<br>".$data['dn'];
1149       }
1151       $ldap->cd($data['dn']);
1152       $ldap->modify($arrr);
1154     } else {
1155       $dn                    = "cn=administrators,".$ldapconf['groupou'].",".$ldapconf['base'];
1156       $arrr['objectClass'][0]= "gosaObject";
1157       $arrr['objectClass'][1]= "posixGroup";
1158       $arrr['gosaSubtreeACL']= ":all";
1159       $arrr['cn']            = "administrators";
1160       $arrr['gidNumber']     = "999";
1161       $arrr['memberUid']     = $_POST['admin_name'];
1163       $ldap->cd($dn);
1164       $ldap->create_missing_trees($dn);
1165       $ldap->cd($dn);
1167       $ldap->add($arrr);
1168     }
1169     return(true);
1170   } else {
1172     if((!isset($create_user))||(!($create_user))) {
1173       $smarty->assign ("content", get_template_path('setup_useradmin.tpl'));
1174       $smarty->assign("exists",true);
1175     } else {
1176       $smarty->assign ("content", get_template_path('setup_useradmin.tpl'));
1177       $smarty->assign("exists",false);
1178     }
1180   }
1182   /* Smarty output */ 
1183   if($withoutput){
1184     $smarty->display (get_template_path('headers.tpl'));
1185   }
1186   if (isset($_SESSION['errors'])) {
1187     $smarty->assign("errors", $_SESSION['errors']);
1188   }
1189   $smarty->assign("str_there",$str_there);
1190   if($withoutput){
1191     $smarty->display (get_template_path('setup.tpl'));
1192   }
1193   return(false);
1197 /* Returns the classnames auf the mail classes */
1198 function get_available_mail_classes()
1200   $dir = opendir( "../include");
1201   $methods = array();
1202   $suffix = "class_mail-methods-";
1203   $lensuf = strlen($suffix);
1204   $prefix = ".inc";
1205   $lenpre = strlen($prefix);
1207   $i = 0;
1208   while (($file = readdir($dir)) !== false){
1210     if(stristr($file,$suffix)) {
1211       $lenfile = strlen($file);
1212       $methods['name'][$i] = substr($file,$lensuf,($lenfile-$lensuf)-$lenpre);
1213       $methods['file'][$i] = $file;
1214       $methods[$i]['file'] = $file;
1215       $methods[$i]['name'] = substr($file,$lensuf,($lenfile-$lensuf)-$lenpre);
1216       $i++;
1217     }
1219   }
1221   return($methods);
1224 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1225 ?>