Code

Only display cehck button if needed
[gosa.git] / gosa-core / setup / class_setupStep_Migrate.inc
1 <?php
3 /*
4    This code is part of GOsa (https://gosa.gonicus.de)
5    Copyright (C) 2007 Fabian Hickert
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
25 class Step_Migrate extends setup_step
26 {
27     var $header_image   = "images/setup/migrate.png";
28     var $checks         = array();
30     /* Create Acl attributes */
31     var $acl_create_dialog  = FALSE;
32     var $acl_create_selected= ""; // Currently selected element, that should receive admin rights 
33     var $acl_create_changes = ""; // Contains ldif information about changes 
34     var $acl_create_confirmed= FALSE;
36     /* Checks initialised ? */
37     var $checks_initialised = FALSE;
39     /* Root object classes */
40     var $rootOC_migrate_dialog = FALSE;
41     var $rootOC_details = array();
42     var $b_displayCheckbutton = TRUE;
44     function Step_Migrate()
45     {
46         $this->update_strings(); 
47     }
49     function update_strings()
50     {
51         $this->s_title      = _("LDAP inspection");
52         $this->s_title_long = _("LDAP inspection");
53         $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
54     }
56     function initialize_checks()
57     {
58         $this->checks = array();
59         $this->checks['root']['TITLE']     = _("Checking for root object");
60         $this->checks['root']['STATUS']    = FALSE;
61         $this->checks['root']['STATUS_MSG']= "";
62         $this->checks['root']['ERROR_MSG'] = "";
63         $this->checkBase();
65         $this->checks['rootOC']['TITLE']     = _("Inspecting object classes in root object");
66         $this->checks['rootOC']['STATUS']    = FALSE;
67         $this->checks['rootOC']['STATUS_MSG']= "";
68         $this->checks['rootOC']['ERROR_MSG'] = "";
69         $this->checkBaseOC();
71         $this->checks['permissions']['TITLE']     = _("Checking permission for LDAP database");
72         $this->checks['permissions']['STATUS']    = FALSE;
73         $this->checks['permissions']['STATUS_MSG']= "";
74         $this->checks['permissions']['ERROR_MSG'] = "";
75         $this->check_ldap_permissions();
77         $this->migrate_users = array();
78         $this->checks['acls']['TITLE']     = _("Checking for super administrator");
79         $this->checks['acls']['STATUS']    = FALSE;
80         $this->checks['acls']['STATUS_MSG']= "";
81         $this->checks['acls']['ERROR_MSG'] = "";
82         $this->check_administrativeAccount();
83     }
86     /* Check ldap accessibility 
87      * Create and remove a dummy object, 
88      *  to ensure that we have the necessary permissions
89      */
90     function check_ldap_permissions()
91     {
92         /* Establish ldap connection */
93         $cv = $this->parent->captured_values;
94         $ldap_l = new LDAP($cv['admin'],
95                 $cv['password'],
96                 $cv['connection'],
97                 FALSE,
98                 $cv['tls']);
100         $ldap = new ldapMultiplexer($ldap_l);
102         /* Create dummy entry 
103          */
104         $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
105         $dn       = "ou=".$name.",".$cv['base'];
106         $testEntry= array();
107         $testEntry['objectClass'][]= "top";
108         $testEntry['objectClass'][]= "organizationalUnit";
109         $testEntry['objectClass'][]= "gosaDepartment";
110         $testEntry['description']= "Created by GOsa setup, this object can be removed.";
111         $testEntry['ou']  = $name;
113         /* check if simple ldap cat will be successful 
114          */
115         $res = $ldap->cat($cv['base']);  
116         if(!$res){
117             $this->checks['permissions']['STATUS']    = FALSE;
118             $this->checks['permissions']['STATUS_MSG']= _("LDAP query failed");
119             $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
120             return(false);
121         }
123         /* Try to create dummy object 
124          */ 
125         $ldap->cd ($dn);
126         $res = $ldap->add($testEntry);
127         $ldap->cat($dn);
128         if(!$ldap->count()){
129             new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
131             $this->checks['permissions']['STATUS']    = FALSE;
132             $this->checks['permissions']['STATUS_MSG']= _("Failed");
133             $this->checks['permissions']['ERROR_MSG'] = 
134                 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
135             return(false);
136         }
138         /* Try to remove created entry 
139          */
140         $res = $ldap->rmDir($dn);
141         $ldap->cat($dn);
142         if($ldap->count()){
143             new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
144             $this->checks['permissions']['STATUS']    = FALSE;
145             $this->checks['permissions']['STATUS_MSG']= _("Failed");
146             $this->checks['permissions']['ERROR_MSG'] = 
147                 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
148             return(false);
149         }
151         /* Create & remove of dummy object was successful */
152         $this->checks['permissions']['STATUS']    = TRUE;
153         $this->checks['permissions']['STATUS_MSG']= _("Ok");
154         $this->checks['permissions']['ERROR_MSG'] = "";
155         return(true);
156     } 
161     /* Check Acls if there is at least one object with acls defined 
162      */
163     function check_administrativeAccount()
164     {
165         /* Reset settings 
166          */ 
167         $GOsa_26_found = FALSE;
168         $this->migrate_users = array();
169         $this->acl_migrate_dialog = FALSE;
170         $this->migrate_acl_base_entry  = "";
172         /* Establish ldap connection */
173         $cv = $this->parent->captured_values;
174         $ldap_l = new LDAP($cv['admin'],
175                 $cv['password'],
176                 $cv['connection'],
177                 FALSE,
178                 $cv['tls']);
180         $ldap = new ldapMultiplexer($ldap_l);
181         $ldap->cd($cv['base']);
182         $res = $ldap->cat($cv['base']);
184         if(!$res){
185             $this->checks['acls']['STATUS']    = FALSE;
186             $this->checks['acls']['STATUS_MSG']= _("LDAP query failed");
187             $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
188         }else{
189             $GOsa_26_found = false; // GOsa 2.6 Account found
190             $GOsa_25_found = false; // GOsa 2.5 Account found, allow migration
192             $username = "";
193             $attrs = $ldap->fetch();
195             /* Collect a list of available GOsa users and groups 
196              */
197             $users = array();
198             $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
199                     "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
200             while($user_attrs = $ldap->fetch()){
201                 $users[$user_attrs['dn']] = $user_attrs['uid'][0];
202                 $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
203             }
204             $groups = array();
205             $ldap->search("objectClass=posixGroup",array("cn","dn"));
206             while($group_attrs = $ldap->fetch()){
207                 $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
208             }
210             /* Check if a valid GOsa 2.6 admin exists 
211                -> gosaAclEntry for an existing and accessible user.
212              */
213             $valid_users = "";
214             $valid_groups = "";
215             if(isset($attrs['gosaAclEntry'])){
216                 $acls = $attrs['gosaAclEntry'];
217                 for($i = 0 ; $i < $acls['count'] ; $i++){
218                     $acl = $acls[$i];
219                     $tmp = explode(":",$acl);
221                     if($tmp[1] == "psub"){
222                         $members = explode(",",$tmp[2]);
223                         foreach($members as $member){
224                             $member = base64_decode($member);
225                             if(isset($users[$member])){
226                                 if(preg_match("/all\/all;cmdrw/i",$tmp[3])){
227                                     $valid_users .= $users[$member].", ";
228                                     $GOsa_26_found  = TRUE;
229                                 }
230                             }
231                             if(isset($groups[$member])){
232                                 if(preg_match("/all\/all;cmdrw/i",$tmp[3])){
233                                     $ldap->cat($member);
234                                     $group_attrs = $ldap->fetch();
235                                     $val_users = "";
236                                     if(isset($group_attrs['memberUid'])){
237                                         for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
238                                             if(isset($rusers[$group_attrs['memberUid'][$e]])){
239                                                 $val_users .= $group_attrs['memberUid'][$e].", ";
240                                             }
241                                         }
242                                     }
243                                     if(!empty($val_users)){
244                                         $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
245                                         $GOsa_26_found  = TRUE;
246                                     }
247                                 }
248                             }
249                         }
250                     }elseif($tmp[1] == "role"){
252                         /* Check if acl owner is a valid GOsa user account */
253                         $ldap->cat(base64_decode($tmp[2]),array("gosaAclTemplate"));
254                         $ret = $ldap->fetch();
256                         if(isset($ret['gosaAclTemplate'])){
257                             $cnt = $ret['gosaAclTemplate']['count'];
258                             for($e = 0 ; $e < $cnt ; $e++){
260                                 $a_str = $ret['gosaAclTemplate'][$e];
261                                 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all\/all;cmdrw$/",$a_str)){
263                                     $members = explode(",",$tmp[3]);
264                                     foreach($members as $member){
265                                         $member = base64_decode($member);
267                                         if(isset($users[$member])){
268                                             $valid_users .= $users[$member].", ";
269                                             $GOsa_26_found  = TRUE;
270                                         }
271                                         if(isset($groups[$member])){
272                                             $ldap->cat($member);
273                                             $group_attrs = $ldap->fetch();
274                                             $val_users = "";
275                                             if(isset($group_attrs['memberUid'])){
276                                                 for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
277                                                     if(isset($rusers[$group_attrs['memberUid'][$e]])){
278                                                         $val_users .= $group_attrs['memberUid'][$e].", ";
279                                                     }
280                                                 }
281                                             }
282                                             if(!empty($val_users)){
283                                                 $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
284                                                 $GOsa_26_found  = TRUE;
285                                             }
286                                         }
287                                     }
288                                 }
289                             }
290                         }
291                     }
292                 }
293             }
295             /* Try to find an old GOsa 2.5 administrative account that may be migrated 
296              */
297             if(!$GOsa_26_found){
298                 $valid_users = "";
299                 $valid_groups = "";
300                 $ldap->cd($cv['base']);
301                 $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
302                 while($p_group = $ldap->fetch()){
303                     $val_users = "";
304                     for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
305                         $user = $p_group['memberUid'][$e];
306                         if(isset($rusers[$user])){
307                             $val_users .= $user.", ";
308                         }  
309                     }
310                     if(!empty($val_users)){
311                         $valid_groups .= $groups[$p_group['dn']]."(<i>".trim($val_users,", ")."</i>), ";
312                         $GOsa_25_found  = TRUE;
313                     }
314                 }
315             }
318             /* Print out results 
319              */
320             if($GOsa_25_found){
321                 $str = "";
322                 if(!empty($valid_groups)){
323                     $str.= "<i>".sprintf(_("GOsa 2.5 administrative accounts found: %s"),trim($valid_groups,", "))."</i><br>";
324                 }
325                 $this->checks['acls']['STATUS']    = FALSE;
326                 $this->checks['acls']['STATUS_MSG']= _("Failed");
327                 $this->checks['acls']['ERROR_MSG'] = $str;
328                 $this->checks['acls']['ERROR_MSG'].= _("There is no valid GOsa 2.6 administrator account inside your LDAP.")."&nbsp;";
329                 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='migrate_acls'>"._("Migrate")."</button>";
330                 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='create_acls'>"._("Create")."</button>";
331             }elseif($GOsa_26_found){
332                 $str = "";
333                 if(!empty($valid_users)){
334                     $str.= "<b>"._("Users")."</b>:&nbsp;".trim($valid_users,", ")."<br>";
335                 }
336                 if(!empty($valid_groups)){
337                     $str.= "<b>"._("Groups")."</b>:&nbsp;".trim($valid_groups,", ")."<br>";
338                 }
339                 $this->checks['acls']['STATUS']    = TRUE;
340                 $this->checks['acls']['STATUS_MSG']= _("Ok");
341                 $this->checks['acls']['ERROR_MSG'] = $str;
342             }else{
343                 $this->checks['acls']['STATUS']    = FALSE;
344                 $this->checks['acls']['STATUS_MSG']= _("Failed");
345                 $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")."&nbsp;";
346                 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='create_acls'>"._("Create")."</button>";
347             }
348         }
350         // Reload base OC
351         $this->checkBaseOC();
352         return($GOsa_26_found);
353     }
357     function create_admin($only_ldif = FALSE)
358     {
359         /* Reset '' */
360         $this->acl_create_changes="";
362         /* Object that should receive admin acls */
363         $dn = $this->acl_create_selected;
365         /* Get collected configuration settings */
366         $cv = $this->parent->captured_values;
368         /* On first call check for rid/sid base */
369         $ldap_l = new LDAP($cv['admin'],
370                 $cv['password'],
371                 $cv['connection'],
372                 FALSE,
373                 $cv['tls']);
375         $ldap = new ldapMultiplexer($ldap_l);
377         /* Get current base attributes */
378         $ldap->cd($cv['base']);
379         $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
380         $attrs = $ldap->fetch();
382         /* Add acls for the selcted user to the base */
383         $attrs_new = array();
384         $attrs_new['objectClass'] = array("gosaACL");
386         for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
387             if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
388                 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
389             }
390         }
392         $acl = "0:psub:".base64_encode($dn).":all/all;cmdrw";    
393         $attrs_new['gosaAclEntry'][] = $acl;
394         if(isset($attrs['gosaAclEntry'])){
395             for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
397                 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
398                 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
400                 $data = ($prio+1).$rest;
401                 $attrs_new['gosaAclEntry'][] = $data;
402             }
403         }
405         if($only_ldif){
406             $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
407             $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
408             $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
409             $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
410         }else{
412             $ldap->cd($cv['base']);
413             if(!$ldap->modify($attrs_new)){
414                 msg_dialog::display(_("Migration error"), sprintf(_("Cannot add ACL for user '%s':")."<br><br><i>%s</i>", LDAP::fix($dn), $ldap->get_error()), ERROR_DIALOG);
415                 return(FALSE);
416             }else{
417                 return(TRUE);
418             }
419         }
420     }
423     function create_admin_user()
424     {
425         $pw1 = $pw2 = "";
426         $uid = "";
428         /* On first call check for rid/sid base */
429         $cv = $this->parent->captured_values;
430         $ldap_l = new LDAP($cv['admin'],
431                 $cv['password'],
432                 $cv['connection'],
433                 FALSE,
434                 $cv['tls']);
436         $ldap = new ldapMultiplexer($ldap_l);
438         if(isset($_POST['new_user_uid'])){
439             $uid = $_POST['new_user_uid'];
440         }
441         if(isset($_POST['new_user_password'])){
442             $pw1 = $_POST['new_user_password'];
443         }
444         if(isset($_POST['new_user_password2'])){
445             $pw2 = $_POST['new_user_password2'];
446         }
449         $ldap->cd($cv['base']);
450         $ldap->search("(uid=".$uid.")");
451         if($ldap->count()){
452             msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
453             return false;
454         }
456         if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
457             msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
458             return false;
459         }
461         if(!tests::is_uid($uid) || empty($uid)){
462             msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
463             return false;
464         }
467         /* Get current base attributes */
468         $ldap->cd($cv['base']);
470         $people_ou = "ou=people,"; // Thats the property default.
471         $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
473         $hash = $hash = passwordMethod::make_hash($pw2, 'crypt/md5');
475         $new_user=array();
476         $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
477         $new_user['givenName']  = "System";
478         $new_user['sn']  = "Administrator";
479         $new_user['cn']  = "System Administrator-".$uid;
480         $new_user['uid'] = $uid;
481         $new_user['userPassword'] = $hash;
483         $ldap->cd($cv['base']);
485         $ldap->cat($dn,array("dn"));
486         if($ldap->count()){
487             msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
488             return(FALSE);  
489         }
491         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
492         $ldap->cd($dn);  
493         $res = $ldap->add($new_user);
494         $this->acl_create_selected = $dn;
495         $this->create_admin();
497         if(!$res){
498             msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
499             return(FALSE);
500         }
502         $this->acl_create_dialog=FALSE;        
503         $this->check_administrativeAccount();
504         return(TRUE);
505     }
508     function execute()
509     {
510         /* Initialise checks if this is the first call */
511         if(!$this->checks_initialised || isset($_POST['test'])){
512             $this->initialize_checks();
513             $this->checks_initialised = TRUE;
514         }
517         /*************
518          * Root object check  
519          *************/
521         if(isset($_POST['retry_root_create'])){
523             $state = $this->checks['root']['STATUS'];
524             $this->checkBase(FALSE);
525             if($state != $this->checks['root']['STATUS']){
526                 $this->initialize_checks();
527             }
528         }
530         /*************
531          * Root object class check  
532          *************/
534         if(isset($_POST['root_add_objectclasses'])){
535             $this->rootOC_migrate_dialog = TRUE;
536             $this->dialog = TRUE;
537         }
538         if(isset($_POST['rootOC_dialog_cancel'])){
539             $this->rootOC_migrate_dialog = FALSE;
540             $this->dialog = FALSE;
541         }
542         if(isset($_POST['rootOC_migrate_start'])){
543             if($this->checkBaseOC(FALSE)){
544                 $this->checkBaseOC(); // Update overview info
545                 $this->dialog = FALSE;
546                 $this->rootOC_migrate_dialog = FALSE;
547             }
548         }
549         if($this->rootOC_migrate_dialog){
550             $smarty = get_smarty();
551             $smarty->assign("details",$this->rootOC_details);
552             $smarty->assign("method","rootOC_migrate_dialog");
553             return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
554         }
556         /*************
557          * Administrative Account -- Migrate/Create 
558          *************/
560         if(isset($_POST['retry_acls'])){
561             $this->check_administrativeAccount();
562         }
564         /* Dialog handling */
565         if(isset($_POST['create_acls'])){
566             $this->acl_create_dialog = TRUE;
567             $this->dialog = TRUE;
568         }
570         if(isset($_POST['migrate_acls'])){
571             $this->acl_migrate_dialog = TRUE;
572             $this->dialog = TRUE;
573         }
575         if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
576             $this->acl_create_dialog = FALSE;
577             $this->acl_migrate_dialog = FALSE;
578             $this->dialog = FALSE;
579             $this->show_details = FALSE;
580         }
582         /* Account creation */
583         if(isset($_POST['create_acls_create'])){
584             $this->create_admin(TRUE);
585         }
587         if(isset($_POST['create_admin_user'])){
588             if($this->create_admin_user()){
589                 $this->dialog = FALSE;
590                 $this->show_details = FALSE;
591             }
592         }
594         /* Add admin acls for the selected users to the ldap base.
595          */
596         if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
598             /* Update ldap and reload check infos 
599              */
600             $this->migrate_selected_admin_users();
601             $this->dialog = FALSE;
602             $this->acl_migrate_dialog = FALSE;
604         }elseif($this->acl_migrate_dialog){
606             /* Display admin migration dialog.
607              */
608             $this->migrate_users();
609             $smarty = get_smarty();
611             /* Do we have to display the changes
612              */
613             $details = isset($_POST['details']) && $_POST['details'];
614             if(isset($_POST['migrate_acls_show_changes'])){
615                 $details = TRUE;
616             }elseif(isset($_POST['migrate_acls_hide_changes'])){
617                 $details = FALSE;
618             }
620             $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
621             $smarty->assign("details", $details);
622             $smarty->assign("method","migrate_acls");
623             $smarty->assign("migrateable_users",$this->migrate_users);
624             return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
625         }
627         if($this->acl_create_dialog){
628             $smarty = get_smarty();
629             $uid = "admin";
630             if(isset($_POST['new_user_uid'])){
631                 $uid = $_POST['new_user_uid'];
632             }
633             $smarty->assign("new_user_uid",$uid);
634             $smarty->assign("new_user_password",@$_POST['new_user_password']);
635             $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
636             $smarty->assign("method","create_acls");
637             $smarty->assign("acl_create_selected",$this->acl_create_selected);
638             $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
639             return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
640         }
643         $smarty = get_smarty();
644         $smarty->assign("checks",$this->checks);
645         $smarty->assign("method","default");
646         return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
647     }
650     function save_object()
651     {
652         $this->is_completed= TRUE;
655         /* Get "create acl" dialog posts */
656         if($this->acl_create_dialog){
658             if(isset($_POST['create_acls_create_abort'])){
659                 $this->acl_create_selected = "";
660             }
661         }
663     }
666     /* Check if the root object exists.
667      * If the parameter just_check is true, then just check if the 
668      *  root object is missing and update the info messages.
669      * If the Parameter is false, try to create a new root object.
670      */
671     function checkBase($just_check = TRUE)
672     {
673         /* Establish ldap connection */
674         $cv = $this->parent->captured_values;
675         $ldap_l = new LDAP($cv['admin'],
676                 $cv['password'],
677                 $cv['connection'],
678                 FALSE,
679                 $cv['tls']);
681         $ldap = new ldapMultiplexer($ldap_l);
683         /* Check if root object exists */
684         $ldap->cd($cv['base']);
685         $ldap->set_size_limit(1);
686         $res = $ldap->search("(objectClass=*)");
687         $ldap->set_size_limit(0);
688         $err = ldap_errno($ldap->cid); 
690         if( !$res || 
691                 $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
692                 $err == 0x40) {  # LDAP_NAMING_VIOLATION
694             /* Root object doesn't exists 
695              */
696             if($just_check){
697                 $this->checks['root']['STATUS']    = FALSE;
698                 $this->checks['root']['STATUS_MSG']= _("Failed");
699                 $this->checks['root']['ERROR_MSG'] =  _("The LDAP root object is missing. It is required to use your LDAP service.").'&nbsp;';
700                 $this->checks['root']['ERROR_MSG'].=  "<button type='submit' name='retry_root_create'>"._("Try to create root object")."</button>";
701                 return(FALSE);
702             }else{
704                 /* Add root object */ 
705                 $ldap->cd($cv['base']);
706                 $res = $ldap->create_missing_trees($cv['base']);
708                 /* If adding failed, tell the user */
709                 if(!$res){
710                     $this->checks['root']['STATUS']    = FALSE;
711                     $this->checks['root']['STATUS_MSG']= _("Failed");
712                     $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
713                     $this->checks['root']['ERROR_MSG'].= "&nbsp;<button type='submit' name='retry_root_create'>"._("Try to create root object")."</button>";
714                     return($res);;
715                 }
716             }
717         }
719         /* Create & remove of dummy object was successful */
720         $this->checks['root']['STATUS']    = TRUE;
721         $this->checks['root']['STATUS_MSG']= _("Ok");
722     }
725     /* Check if the root object includes the required object classes, e.g. gosaDepartment is required for ACLs.
726      * If the parameter just_check is true, then just check for the OCs. 
727      * If the Parameter is false, try to add the required object classes.
728      */
729     function checkBaseOC($just_check = TRUE)
730     {
731         /* Establish ldap connection */
732         $cv = $this->parent->captured_values;
733         $ldap_l = new LDAP($cv['admin'],
734                 $cv['password'],
735                 $cv['connection'],
736                 FALSE,
737                 $cv['tls']);
739         $ldap = new ldapMultiplexer($ldap_l);
741         /* Check if root object exists */
742         $ldap->cd($cv['base']);
743         $ldap->cat($cv['base']);
744         if(!$ldap->count()){
745             $this->checks['rootOC']['STATUS']    = FALSE;
746             $this->checks['rootOC']['STATUS_MSG']= _("LDAP query failed");
747             $this->checks['rootOC']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
748             return;
749         }
751         $attrs = $ldap->fetch();
753         /* Root object doesn't exists 
754          */
755         if(!in_array("gosaDepartment",$attrs['objectClass'])){
756             if($just_check){
758                 $this->rootOC_details = array();        
759                 $mods = array();
761                 /* Get list of possible container objects, to be able to detect naming 
762                  *  attributes and missing attribute types.
763                  */
764                 if(!class_available("departmentManagement")){
765                     $this->checks['rootOC']['STATUS']    = FALSE;
766                     $this->checks['rootOC']['STATUS_MSG']= _("Failed");
767                     $this->checks['rootOC']['ERROR_MSG'] = sprintf(_("Missing GOsa object class '%s'!"),"departmentManagement").
768                         "&nbsp;"._("Please check your installation.");
769                     return;
770                 }
772                 /* Try to detect base class type, e.g. is it a dcObject.
773                  */
774                 $dep_types = departmentManagement::get_support_departments();
775                 $dep_type ="";
776                 foreach($dep_types as $dep_name => $dep_class){
777                     if(in_array($dep_class['CLASS'], $attrs['objectClass'])){
778                         $dep_type = $dep_name;
779                         break;
780                     }
781                 }
783                 /* If no known base class was detect, abort with message
784                  */     
785                 if(empty($dep_type)){
786                     $this->checks['rootOC']['STATUS']    = FALSE;
787                     $this->checks['rootOC']['STATUS_MSG']= _("Failed");
788                     $this->checks['rootOC']['ERROR_MSG'] = 
789                         sprintf(_("Cannot handle the structural object type of your root object. Please try to add the object class '%s' manually."),"gosaDepartment");
790                     return;
791                 }
793                 /* Create 'current' and 'target' object properties, to be able to display 
794                  *  a set of modifications required to create a valid GOsa department.
795                  */     
796                 $str = "dn: ".$cv['base']."\n";
797                 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
798                     $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
799                 }
800                 $this->rootOC_details['current'] = $str;
802                 /* Create target infos 
803                  */
804                 $str = "dn: ".$cv['base']."\n";
805                 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
806                     $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
807                     $mods['objectClass'][] = $attrs['objectClass'][$i];
808                 }
809                 $mods['objectClass'][] = "gosaDepartment";
810                 $str .= "<b>objectClass: gosaDepartment</b>\n";
812                 /* Append attribute 'ou', it is required by gosaDepartment
813                  */
814                 if(!isset($attrs['ou'])){
815                     $val = "GOsa";
816                     if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
817                         $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
818                     }
819                     $str .= "<b>ou: ".$val."</b>\n";
820                     $mods['ou'] =$val;
821                 }
823                 /*Append description, it is required by gosaDepartment too.
824                  */
825                 if(!isset($attrs['description'])){
826                     $val = "GOsa";
827                     if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
828                         $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
829                     }
830                     $str .= "<b>description: ".$val."</b>\n";
831                     $mods['description'] = $val;
832                 }
833                 $this->rootOC_details['target'] = $str;
834                 $this->rootOC_details['mods'] = $mods;
836                 /*  Add button that allows to open the migration details
837                  */
838                 $this->checks['rootOC']['STATUS']    = FALSE;
839                 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
840                 $this->checks['rootOC']['ERROR_MSG'] = "&nbsp;<button type='submit' 
841                     name='root_add_objectclasses'>"._("Migrate")."</button>";
843                 return(FALSE);
844             }else{
846                 /* Add root object */ 
847                 $ldap->cd($cv['base']);
848                 if(isset($this->rootOC_details['mods'])){
849                     $res  = $ldap->modify($this->rootOC_details['mods']);       
850                     if(!$res){
851                         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $cv['base'], LDAP_MOD, get_class()));
852                     }
853                     $this->checkBaseOC();
854                     $this->check_administrativeAccount();
855                     return($res);
856                 }else{
857                     trigger_error("No modifications to make... ");
858                 }
859             }
860             return(TRUE);
861         }
863         /* Create & remove of dummy object was successful */
864         $this->checks['rootOC']['STATUS']    = TRUE;
865         $this->checks['rootOC']['STATUS_MSG']= _("Ok");
866         $this->checks['rootOC']['ERROR_MSG'] = "";
867     }
870     /* Return ldif information for a 
871      * given attribute array 
872      */
873     function array_to_ldif($atts)
874     {
875         $ret = "";
876         unset($atts['count']);
877         unset($atts['dn']);
878         foreach($atts as $name => $value){
879             if(is_numeric($name)) {
880                 continue;
881             }
882             if(is_array($value)){
883                 unset($value['count']);
884                 foreach($value as $a_val){
885                     $ret .= $name.": ". $a_val."\n";
886                 }
887             }else{
888                 $ret .= $name.": ". $value."\n";
889             }
890         }
891         return(preg_replace("/\n$/","",$ret));
892     }
896 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
897 ?>