Code

c6f4cc8f2f72b7fe2a3146b2d1c895a5589740f7
[gosa.git] / 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  */
24 /****************
25  * FUNCTIONS 
27 Step_Migrate                - Constructor.
28 update_strings              - Used to update the displayed step informations.
29 initialize_checks           - Initialize migration steps.
30 check_ldap_permissions      - Check if the used admin account has full access to the ldap database.
31 check_gosaAccounts          - Check if there are users without the required objectClasses.
32 migrate_gosaAccounts        - Migrate selected users to GOsa user accounts.
33 check_organizationalUnits   - Check if there are departments, that are not visible for GOsa
34 migrate_organizationalUnits - Migrate selected departments 
35 check_administrativeAccount - Check if there is at least one acl entry available                  
36 checkBase                   - Check if there is a root object available 
38 get_user_list               - Get list of available users
39 get_group_list              - Get list of groups
40   
41 create_admin                
42 create_admin_user           
44 execute                     - Generate html output of this plugin
45 save_object                 - Save posts 
46 array_to_ldif               - Create ldif output of an ldap result array 
47  
48  ****************/
52 class Step_Migrate extends setup_step
53 {
54   var $languages      = array();
55   var $attributes     = array();
56   var $header_image   = "images/monitoring.png";
57   var $checks         = array();
59   /* Department migration attributes */
60   var $dep_migration_dialog = FALSE;
61   var $deps_to_migrate      = array();
63   /* Department migration attributes */
64   var $users_migration_dialog= FALSE;
65   var $users_to_migrate      = array();
67   /* Create Acl attributes */
68   var $acl_create_dialog  = FALSE;
69   var $acl_create_type    = "group";
70   var $acl_create_selected= ""; // Currently selected element, that should receive admin rights 
71   var $acl_create_changes = ""; // Contains ldif information about changes 
72   var $acl_create_confirmed= FALSE;
74   /* Checks initialised ? */
75   var $checks_initialised = FALSE;
77   /* Users outside to people ou */
78   var $outside_users        = array();
79   var $outside_users_dialog = FALSE;
81   /* Users outside to groups ou */
82   var $outside_groups        = array();
83   var $outside_groups_dialog = FALSE;
85   /* Win-Workstations outside to reserved ou */
86   var $outside_winstations        = array();
87   var $outside_winstations_dialog = FALSE;
89   /* check for multiple use of same uidNumber */
90   var $check_uidNumbers        = array();
91   var $check_uidNumbers_dialog = FALSE;
93   /* check for multiple use of same gidNumber */
94   var $check_gidNumbers        = array();
95   var $check_gidNumbers_dialog = FALSE;
98   function Step_Migrate()
99   {
100     $this->update_strings(); 
101   }
103   function update_strings()
104   {
105     $this->s_title      = _("LDAP inspection");
106     $this->s_title_long = _("LDAP inspection");
107     $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
108   }
110   function initialize_checks()
111   {
112     $this->checks = array();
113     $this->checks['root']['TITLE']     = _("Checking for root object");
114     $this->checks['root']['STATUS']    = FALSE;
115     $this->checks['root']['STATUS_MSG']= "";
116     $this->checks['root']['ERROR_MSG'] = "";
117     $this->checkBase();
119     $this->checks['permissions']['TITLE']     = _("Checking permissions on ldap database");
120     $this->checks['permissions']['STATUS']    = FALSE;
121     $this->checks['permissions']['STATUS_MSG']= "";
122     $this->checks['permissions']['ERROR_MSG'] = "";
123     $this->check_ldap_permissions();
125     $this->checks['deps_visible']['TITLE']     = _("Checking for invisible deparmtments");
126     $this->checks['deps_visible']['STATUS']    = FALSE;
127     $this->checks['deps_visible']['STATUS_MSG']= "";
128     $this->checks['deps_visible']['ERROR_MSG'] = "";
129     $this->check_organizationalUnits();
131     $this->checks['users_visible']['TITLE']     = _("Checking for invisible user");
132     $this->checks['users_visible']['STATUS']    = FALSE;
133     $this->checks['users_visible']['STATUS_MSG']= "";
134     $this->checks['users_visible']['ERROR_MSG'] = "";
135     $this->check_gosaAccounts();
137     $this->checks['acls']['TITLE']     = _("Checking for administrational account");
138     $this->checks['acls']['STATUS']    = FALSE;
139     $this->checks['acls']['STATUS_MSG']= "";
140     $this->checks['acls']['ERROR_MSG'] = "";
141     $this->check_administrativeAccount();
143     $this->checks['outside_users']['TITLE']     = _("Checking for users outside the people department.");
144     $this->checks['outside_users']['STATUS']    = FALSE;
145     $this->checks['outside_users']['STATUS_MSG']= "";
146     $this->checks['outside_users']['ERROR_MSG'] = "";
147     $this->search_outside_users();
148     
149     $this->checks['outside_groups']['TITLE']     = _("Checking for groups outside the groups department.");
150     $this->checks['outside_groups']['STATUS']    = FALSE;
151     $this->checks['outside_groups']['STATUS_MSG']= "";
152     $this->checks['outside_groups']['ERROR_MSG'] = "";
153     $this->search_outside_groups();
155     $this->checks['outside_winstations']['TITLE']     = _("Checking for windows workstations outside the winstation department.");
156     $this->checks['outside_winstations']['STATUS']    = FALSE;
157     $this->checks['outside_winstations']['STATUS_MSG']= "";
158     $this->checks['outside_winstations']['ERROR_MSG'] = "";
159     $this->search_outside_winstations();
161     $this->checks['uidNumber_usage']['TITLE']     = _("Checking for multiple use of same uidNumber value.");
162     $this->checks['uidNumber_usage']['STATUS']    = FALSE;
163     $this->checks['uidNumber_usage']['STATUS_MSG']= "";
164     $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
165     $this->check_uidNumber();
166     
167     $this->checks['gidNumber_usage']['TITLE']     = _("Checking for multiple use of same gidNumber value.");
168     $this->checks['gidNumber_usage']['STATUS']    = FALSE;
169     $this->checks['gidNumber_usage']['STATUS_MSG']= "";
170     $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
171     $this->check_gidNumber();
172   }
174   function check_uidNumber()
175   {
176     $cv = $this->parent->captured_values;
177     $ldap = new LDAP($cv['admin'],
178         $cv['password'],
179         $cv['connection'],
180         FALSE,
181         $cv['tls']);
183     $ldap->cd($cv['base']);
184     $res = $ldap->search("uidNumber=*",array("dn","uidNumber"));
185     if(!$res){
186       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
187       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
188       $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
189       return(false);
190     }
192     $this->check_uidNumbers= array(); 
193     while($attrs = $ldap->fetch()){
194       $tmp[$attrs['uidNumber'][0]][] = $attrs;
195     }
197     foreach($tmp as $id => $entries){
198       if(count($entries) > 1){
199         foreach($entries as $entry){
200           $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
201         }
202       }
203     }
205     if($this->check_uidNumbers){
206       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
207       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Failed");
208       $this->checks['uidNumber_usage']['ERROR_MSG'] =
209         sprintf(_("Found %s duplicated uidNumber values."),count($this->check_uidNumbers));
210       return(false);
211     }else{
212       $this->checks['uidNumber_usage']['STATUS']    = TRUE;
213       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
214       $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
215       return(TRUE);
216     }
217   }
219   function check_gidNumber()
220   {
221     $cv = $this->parent->captured_values;
222     $ldap = new LDAP($cv['admin'],
223         $cv['password'],
224         $cv['connection'],
225         FALSE,
226         $cv['tls']);
228     $ldap->cd($cv['base']);
229     $res = $ldap->search("gidNumber=*",array("dn","gidNumber"));
230     if(!$res){
231       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
232       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
233       $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
234       return(false);
235     }
237     $this->check_gidNumbers= array(); 
238     while($attrs = $ldap->fetch()){
239       $tmp[$attrs['gidNumber'][0]][] = $attrs;
240     }
242     foreach($tmp as $id => $entries){
243       if(count($entries) > 1){
244         foreach($entries as $entry){
245           $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
246         }
247       }
248     }
250     if($this->check_gidNumbers){
251       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
252       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Failed");
253       $this->checks['gidNumber_usage']['ERROR_MSG'] =
254         sprintf(_("Found %s duplicated gidNumber values."),count($this->check_gidNumbers));
255       return(false);
256     }else{
257       $this->checks['gidNumber_usage']['STATUS']    = TRUE;
258       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
259       $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
260       return(TRUE);
261     }
262   }
265   /* Search for winstations outside the winstation ou */
266   function search_outside_winstations()
267   {
268     $cv = $this->parent->captured_values;
269     $ldap = new LDAP($cv['admin'],
270         $cv['password'],
271         $cv['connection'],
272         FALSE,
273         $cv['tls']);
275     /* Get winstation ou */
276     if($cv['generic_settings']['wws_ou_active']) {
277       $winstation_ou = $cv['generic_settings']['ws_ou'];
278     }else{
279       $winstation_ou = "ou=winstations";
280     }
281  
282     $ldap->cd($cv['base']);
283     $res = $ldap->search("(&(objectClass=posixGroup)(sambaGroupType=2)(sambaSID=*))",array("dn","sambaSID"));
284     if(!$res){
285       $this->checks['outside_winstations']['STATUS']    = FALSE;
286       $this->checks['outside_winstations']['STATUS_MSG']= _("Ldap query failed.");
287       $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
288       return(false);
289     }
291     $this->outside_winstations = array();
292     while($attrs = $ldap->fetch()){
293       if(preg_match("/-516$/","",$attrs['sambaSID'][0]) && !preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])){
294         $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
295       }
296     }
298     if(count($this->outside_winstations)){
299       $this->checks['outside_winstations']['STATUS']    = FALSE;
300       $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
301       $this->checks['outside_winstations']['ERROR_MSG'] = 
302         sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
303       return(false);
304     }else{
305       $this->checks['outside_winstations']['STATUS']    = TRUE;
306       $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
307       $this->checks['outside_winstations']['ERROR_MSG'] = "";
308       return(TRUE);
309     }
310   }
313   /* Search for groups outside the group ou */
314   function search_outside_groups()
315   {
316     $cv = $this->parent->captured_values;
317     $ldap = new LDAP($cv['admin'],
318         $cv['password'],
319         $cv['connection'],
320         FALSE,
321         $cv['tls']);
323     $group_ou = $cv['groupou'];
324     $ldap->cd($cv['base']);
325     $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
326     if(!$res){
327       $this->checks['outside_groups']['STATUS']    = FALSE;
328       $this->checks['outside_groups']['STATUS_MSG']= _("Ldap query failed.");
329       $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
330       return(false);
331     }
334     $this->outside_groups = array();
335     while($attrs = $ldap->fetch()){
336       if(!preg_match("/^[^,]+,".normalizePreg($group_ou)."/",$attrs['dn'])){
337         $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
338       }
339     }
341     if(count($this->outside_groups)){
342       $this->checks['outside_groups']['STATUS']    = FALSE;
343       $this->checks['outside_groups']['STATUS_MSG']= _("Failed");
344       $this->checks['outside_groups']['ERROR_MSG'] = 
345         sprintf(_("Found %s groups outside the selected group ou '%s'."),count($this->outside_groups),$group_ou);
346       return(false);
347     }else{
348       $this->checks['outside_groups']['STATUS']    = TRUE;
349       $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
350       $this->checks['outside_groups']['ERROR_MSG'] = "";
351       return(TRUE);
352     }
353   }
355   /* Search for users outside the people ou */
356   function search_outside_users()
357   {
358     $cv = $this->parent->captured_values;
359     $ldap = new LDAP($cv['admin'],
360         $cv['password'],
361         $cv['connection'],
362         FALSE,
363         $cv['tls']);
364     $people_ou = $cv['peopleou'];
365     $ldap->cd($cv['base']);
366     $res = $ldap->search("(objectClass=gosaAccount)",array("dn"));
367     if(!$res){
368       $this->checks['outside_users']['STATUS']    = FALSE;
369       $this->checks['outside_users']['STATUS_MSG']= _("Ldap query failed.");
370       $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
371       return(false);
372     }
375     $this->outside_users = array();
376     while($attrs = $ldap->fetch()){
377       if(!preg_match("/^[^,]+,".normalizePreg($people_ou)."/",$attrs['dn'])){
378         $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
379       }
380     }
382     if(count($this->outside_users)){
383       $this->checks['outside_users']['STATUS']    = FALSE;
384       $this->checks['outside_users']['STATUS_MSG']= _("Failed");
385       $this->checks['outside_users']['ERROR_MSG'] = 
386         sprintf(_("Found %s users outside the selected user ou '%s'."),count($this->outside_users),$people_ou);
387       return(false);
388     }else{
389       $this->checks['outside_users']['STATUS']    = TRUE;
390       $this->checks['outside_users']['STATUS_MSG']= _("Ok");
391       $this->checks['outside_users']['ERROR_MSG'] = "";
392       return(TRUE);
393     }
394   }
397   /* Check ldap accessibility 
398    * Create and remove a dummy object, 
399    *  to ensure that we have the necessary permissions
400    */
401   function check_ldap_permissions()
402   {
403     $cv = $this->parent->captured_values;
404     $ldap = new LDAP($cv['admin'],
405         $cv['password'],
406         $cv['connection'],
407         FALSE,
408         $cv['tls']);
410     /* Create dummy entry 
411      */
412     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
413     $dn       = "ou=".$name.",".$cv['base'];
414     $testEntry= array();
415     $testEntry['objectClass'][]= "top";
416     $testEntry['objectClass'][]= "organizationalUnit";
417     $testEntry['objectClass'][]= "gosaDepartment";
418     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
419     $testEntry['ou']  = $name;
421     /* check if simple ldap cat will be successful 
422      */
423     $res = $ldap->cat($cv['base']);  
424     if(!$res){
425       $this->checks['permissions']['STATUS']    = FALSE;
426       $this->checks['permissions']['STATUS_MSG']= _("Ldap query failed.");
427       $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
428       return(false);
429     }
430   
431     /* Try to create dummy object 
432      */ 
433     $ldap->cd ($dn);
434     $ldap->create_missing_trees($dn);
435     $res = $ldap->add($testEntry);
436     if(!$res){
437       gosa_log($ldap->get_error());
438       $this->checks['permissions']['STATUS']    = FALSE;
439       $this->checks['permissions']['STATUS_MSG']= _("Failed");
440       $this->checks['permissions']['ERROR_MSG'] = 
441         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
442       return(false);
443     }
445     /* Try to remove created entry 
446      */
447     $res = $ldap->rmDir($dn);
448     if(!$res){
449       gosa_log($ldap->get_error());
450       $this->checks['permissions']['STATUS']    = FALSE;
451       $this->checks['permissions']['STATUS_MSG']= _("Failed");
452       $this->checks['permissions']['ERROR_MSG'] = 
453         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
454       return(false);
455     }
457     /* Create & remove of dummy object was successful */
458     $this->checks['permissions']['STATUS']    = TRUE;
459     $this->checks['permissions']['STATUS_MSG']= _("Ok");
460     $this->checks['permissions']['ERROR_MSG'] = "";
461     return(true);
462   } 
465   /* Check if there are users which will 
466    *  be invisible for GOsa 
467    */
468   function check_gosaAccounts()
469   {
470     /* Remember old list of ivisible users, to be able to set 
471      *  the 'html checked' status for the checkboxes again 
472      */
473     $cnt_ok = 0;
474     $old    = $this->users_to_migrate;
475     $this->users_to_migrate = array();
477     /* Get collected configuration settings */
478     $cv = $this->parent->captured_values;
480     /* Establish ldap connection */
481     $ldap = new LDAP($cv['admin'],
482         $cv['password'],
483         $cv['connection'],
484         FALSE,
485         $cv['tls']);
487     /* Get all invisible users 
488      */
489     $ldap->cd($cv['base']); 
490     $res =$ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
491     while($attrs = $ldap->fetch()){
492       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
493         $attrs['checked'] = FALSE;
494         $attrs['before']  = "";
495         $attrs['after']   = "";
497         /* Set objects to selected, that were selected before reload */
498         if(isset($old[base64_encode($attrs['dn'])])){
499           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
500         }
501         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
502       }
503     }
505     /* No invisible */
506     if(!$res){
507       $this->checks['users_visible']['STATUS']    = FALSE;
508       $this->checks['users_visible']['STATUS_MSG']= _("Ldap query failed.");
509       $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
510     }elseif(count($this->users_to_migrate) == 0){
511       $this->checks['users_visible']['STATUS']    = TRUE;
512       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
513       $this->checks['users_visible']['ERROR_MSG'] = "";
514     }else{
515       $this->checks['users_visible']['STATUS']    = FALSE;
516       $this->checks['users_visible']['STATUS_MSG']= "";
517       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."), 
518           count($this->users_to_migrate));
519       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
520     }
521   }
524   /* Start user account migration 
525    */  
526   function migrate_gosaAccounts($only_ldif = FALSE)
527   {
528     /* Get collected configuration settings */
529     $cv = $this->parent->captured_values;
531     /* Establish ldap connection */
532     $ldap = new LDAP($cv['admin'],
533         $cv['password'],
534         $cv['connection'],
535         FALSE,
536         $cv['tls']);
538     /* Add gosaAccount objectClass to the selected users  
539      */
540     foreach($this->users_to_migrate as $key => $dep){
541       if($dep['checked']){
543         /* Get old objectClasses */
544         $ldap->cat($dep['dn'],array("objectClass"));
545         $attrs      = $ldap->fetch();
547         /* Create new objectClass array */
548         $new_attrs  = array();
549         $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
550         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
551           if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
552             $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
553           }
554         }
556         /* Set info attributes for current object, 
557          *  or write changes to the ldap database 
558          */
559         if($only_ldif){
560           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
561           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
562         }else{
563           $ldap->cd($attrs['dn']);
564           if(!$ldap->modify($new_attrs)){
565             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
566             return(false);
567           }
568         }
569       }
570     }
571     return(TRUE);
572   }
575   /* Check if there are invisible organizational Units 
576    */
577   function check_organizationalUnits()
578   {
579     $cnt_ok = 0;
580     $old = $this->deps_to_migrate;
581     $this->deps_to_migrate = array();
583     /* Get collected configuration settings */
584     $cv = $this->parent->captured_values;
586     /* Establish ldap connection */
587     $ldap = new LDAP($cv['admin'],
588         $cv['password'],
589         $cv['connection'],
590         FALSE,
591         $cv['tls']);
593     /* Skip GOsa internal departments */
594     $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
595         "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
596         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
597         "/(,|)ou=winstations,/");
600     /* Get all invisible departments */
601     $ldap->cd($cv['base']); 
602     $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
603     while($attrs = $ldap->fetch()){
604       $attrs['checked'] = FALSE;
605       $attrs['before']  = "";
606       $attrs['after']   = "";
608       /* Set objects to selected, that were selected before reload */
609       if(isset($old[base64_encode($attrs['dn'])])){
610         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
611       }
612       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
613     }
615     /* Filter returned list of departments and ensure that 
616      *  GOsa internal departments will not be listed 
617      */
618     foreach($this->deps_to_migrate as $key => $attrs){
619       $dn = $attrs['dn'];
620       $skip = false;
621       foreach($skip_dns as $skip_dn){
622         if(preg_match($skip_dn,$dn)){
623           $skip = true;
624         }
625       }
626       if($skip){
627         unset($this->deps_to_migrate[$key]);
628       }
629     }
631     /* If we have no invisible departments found  
632      *  tell the user that everything is ok 
633      */
634     if(!$res){
635       $this->checks['deps_visible']['STATUS']    = FALSE;
636       $this->checks['deps_visible']['STATUS_MSG']= _("Ldap query failed.");
637       $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
638     }elseif(count($this->deps_to_migrate) == 0 ){
639       $this->checks['deps_visible']['STATUS']    = TRUE;
640       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
641       $this->checks['deps_visible']['ERROR_MSG'] = "";
642     }else{
643       $this->checks['deps_visible']['STATUS']    = FALSE;
644       $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
645       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
646       $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
647     }
648   }
652   /* Start deparmtment migration */  
653   function migrate_organizationalUnits($only_ldif = FALSE)
654   {
655     /* Get collected configuration settings */
656     $cv = $this->parent->captured_values;
658     /* Establish ldap connection */
659     $ldap = new LDAP($cv['admin'],
660         $cv['password'],
661         $cv['connection'],
662         FALSE,
663         $cv['tls']);
665     /* Add gosaDepartment objectClass to each selected entry 
666      */
667     foreach($this->deps_to_migrate as $key => $dep){
668       if($dep['checked']){
670         /* Get current objectClasses */
671         $ldap->cat($dep['dn'],array("objectClass","description"));
672         $attrs      = $ldap->fetch();
674         /* Create new objectClass attribute including gosaDepartment*/
675         $new_attrs  = array();
676         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
677           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
678         }
679         $new_attrs['objectClass'][] = "gosaDepartment";
681         /* Append description it is missing */
682         if(!isset($attrs['description'])){
683           $new_attrs['description'][] = "GOsa department";
684         }
686         /* Depending on the parameter >only_diff< we save the changes as ldif
687          *  or we write our changes directly to the ldap database
688          */
689         if($only_ldif){
690           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
691           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
692         }else{
693           $ldap->cd($attrs['dn']);
694           if(!$ldap->modify($new_attrs)){
695             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
696             return(false);
697           }
698         }
699       }
700     }
701     return(TRUE);
702   }
705   /* Check Acls if there is at least one object with acls defined 
706    */
707   function check_administrativeAccount()
708   {
709     /* Establish ldap connection */
710     $cv = $this->parent->captured_values;
711     $ldap = new LDAP($cv['admin'],
712         $cv['password'],
713         $cv['connection'],
714         FALSE,
715         $cv['tls']);
717     /* Search for gosaAcls */ 
718     $ldap->cd($cv['base']);
719     $res = $ldap->search("(&(objectClass=gosaAccount)(|(objectClass=posixAccount)".     
720                            "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))");
721     if(!$res){
722       $this->checks['acls']['STATUS']    = FALSE;
723       $this->checks['acls']['STATUS_MSG']= _("Ldap query failed.");
724       $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
725     }elseif($ldap->count()){
726       $this->checks['acls']['STATUS']    = TRUE;
727       $this->checks['acls']['STATUS_MSG']= _("Ok");
728     }else{
729       $this->checks['acls']['STATUS']    = FALSE;
730       $this->checks['acls']['STATUS_MSG']= _("Failed");
731       $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create adminitrational account")."'>";
732     }
733     return($ldap->count()>=1);
734   }
737   function get_user_list()
738   {
739     /* Get collected configuration settings */
740     $cv = $this->parent->captured_values;
742     /* Establish ldap connection */
743     $ldap = new LDAP($cv['admin'],
744         $cv['password'],
745         $cv['connection'],
746         FALSE,
747         $cv['tls']);
748     
749     $ldap->cd($cv['base']);
750     $ldap->search("(objectClass=gosaAccount)",array("dn"));
751   
752     $tmp = array();
753     while($attrs = $ldap->fetch()){
754       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
755     }
757     return($tmp);
758   }
760   function get_group_list()
761   {
762     /* Get collected configuration settings */
763     $cv = $this->parent->captured_values;
765     /* Establish ldap connection */
766     $ldap = new LDAP($cv['admin'],
767         $cv['password'],
768         $cv['connection'],
769         FALSE,
770         $cv['tls']);
771     
772     $ldap->cd($cv['base']);
773     $ldap->search("(objectClass=posixGroup)",array("dn"));
774   
775     $tmp = array();
776     while($attrs = $ldap->fetch()){
777       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
778     }
780     return($tmp);
781   }
785   function create_admin($only_ldif = FALSE)
786   {
787     /* Reset '' */
788     $this->acl_create_changes="";
790     /* Object that should receive admin acls */
791     $dn = $this->acl_create_selected;
793     /* Get collected configuration settings */
794     $cv = $this->parent->captured_values;
796     /* Establish ldap connection */
797     $ldap = new LDAP($cv['admin'],
798         $cv['password'],
799         $cv['connection'],
800         FALSE,
801         $cv['tls']);
803     /* Get current base attributes */
804     $ldap->cd($cv['base']);
805     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
806     $attrs = $ldap->fetch();
808     /* Add acls for the selcted user to the base */
809     $attrs_new['objectClass'] = array("gosaACL");
811     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
812       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
813         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
814       }
815     }
817     $acl = "0:sub:".base64_encode($dn).":all;cmdrw";    
818     $attrs_new['gosaAclEntry'][] = $acl;
819     if(isset($attrs['gosaAclEntry'])){
820       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
821           
822         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
823         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
824  
825         $data = ($prio+1).$rest;
826         $attrs_new['gosaAclEntry'][] = $data;
827       }
828     }
830     if($only_ldif){
831       $this->acl_create_changes ="\n".$cv['base']."\n";
832       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
833       $this->acl_create_changes.="\n".$cv['base']."\n";
834       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
835     }else{
836    
837       $ldap->cd($cv['base']);
838       if(!$ldap->modify($attrs_new)){
839         print_red(sprintf(_("Adding acls for user '%s' failed, ldap says '%s'."),$dn,$ldap->get_error()));
840       }
841     }
842   }
843  
844   
845   function create_admin_user()
846   {
847     if(isset($_POST['new_user_password']) && !empty($_POST['new_user_password'])){
848       $pwd = $_POST['new_user_password'];
849     }else{
850       print_red(_("Please specify a valid password for the new GOsa admin user."));
851       return(FALSE);
852     }
853     
854     /* Establish ldap connection */
855     $cv = $this->parent->captured_values;
856     $ldap = new LDAP($cv['admin'],
857         $cv['password'],
858         $cv['connection'],
859         FALSE,
860         $cv['tls']);
862     /* Get current base attributes */
863     $ldap->cd($cv['base']);
864   
865     if($cv['peopledn'] == "cn"){
866       $dn = "cn=System Administrator,".$cv['peopleou'].",".$cv['base'];
867     }else{
868       $dn = "uid=admin,".$cv['peopleou'].",".$cv['base'];
869     }
871     $methods = @passwordMethod::get_available_methods_if_not_loaded();
872     $p_m = $methods[$cv['encryption']];
873     $p_c = new $p_m(array());
874     $hash = $p_c->generate_hash($pwd);
876     $new_user=array();
877     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
878     $new_user['givenName']  = "System";
879     $new_user['sn']  = "Administrator";
880     $new_user['cn']  = "System Administrator";
881     $new_user['uid'] = "admin";
882     $new_user['userPassword'] = $hash;
883     
884     $ldap->cd($cv['base']);
885     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
886     $ldap->cd($dn);  
887     $res = $ldap->add($new_user);
888     $this->acl_create_selected = $dn;
889     $this->create_admin();
890     
891     if(!$res){
892       print_red($ldap->get_error());
893     }
894   
895     $this->acl_create_dialog=FALSE;        
896     $this->check_administrativeAccount();
897   }
898  
900   function execute()
901   {
902     /* Initialise checks if this is the first call */
903     if(!$this->checks_initialised || isset($_POST['reload'])){
904       $this->initialize_checks();
905       $this->checks_initialised = TRUE;
906     }
907  
908     /*************
909      * Root object check  
910      *************/
911   
912     if(isset($_POST['retry_root_create'])){
913       $this->checkBase(FALSE);
914     }
915  
916     /*************
917      * User Migration handling 
918      *************/
920     if(isset($_POST['retry_acls'])){
921       $this->check_administrativeAccount();
922     }
924     if(isset($_POST['create_acls'])){
925       $this->acl_create_dialog = TRUE;
926       $this->dialog = TRUE;
927     }
928   
929     if(isset($_POST['create_acls_cancel'])){
930       $this->acl_create_dialog = FALSE;
931       $this->dialog = FALSE;
932     }
934     if(isset($_POST['create_acls_create_confirmed'])){
935       $this->create_admin();
936     }
938     if(isset($_POST['create_acls_create'])){
939       $this->create_admin(TRUE);
940     }
942     if(isset($_POST['create_admin_user'])){
943       $this->create_admin_user();
944     }
946     if($this->acl_create_dialog){
947       $smarty = get_smarty();
948       $smarty->assign("new_user_password",@$_POST['new_user_password']);
949       $smarty->assign("users" ,$this->get_user_list());
950       $smarty->assign("users_cnt" ,count($this->get_user_list()));
951       $smarty->assign("groups",$this->get_group_list());
952       $smarty->assign("groups_cnt",count($this->get_group_list()));
953       $smarty->assign("type"  ,$this->acl_create_type);
954       $smarty->assign("method","create_acls");
955       $smarty->assign("acl_create_selected",$this->acl_create_selected);
956       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
957       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
958     }
960     /*************
961      * User Migration handling 
962      *************/
964     /* Refresh list of deparments */
965     if(isset($_POST['users_visible_migrate_refresh'])){
966       $this->check_gosaAccounts();
967     }
969     /* Open migration dialog */
970     if(isset($_POST['users_visible_migrate'])){
971       $this->users_migration_dialog = TRUE;
972       $this->dialog =TRUE;
973     }
975     /* Close migration dialog */
976     if(isset($_POST['users_visible_migrate_close'])){
977       $this->users_migration_dialog = FALSE;
978       $this->dialog =FALSE;
979     }
981     /* Start migration */
982     if(isset($_POST['users_visible_migrate_migrate'])){
983       if($this->migrate_gosaAccounts()){
984         $this->check_gosaAccounts();
985       }
986     }
988     /* Start migration */
989     if(isset($_POST['users_visible_migrate_whatsdone'])){
990       $this->migrate_gosaAccounts(TRUE);
991     }
993     /* Display migration dialog */
994     if($this->users_migration_dialog){
995       $smarty = get_smarty();
996       $smarty->assign("users_to_migrate",$this->users_to_migrate);
997       $smarty->assign("method","migrate_users");
998       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
999     }
1002     /*************
1003      * Department Migration handling 
1004      *************/
1006     /* Refresh list of deparments */
1007     if(isset($_POST['deps_visible_migrate_refresh'])){
1008       $this->check_organizationalUnits();
1009     }
1011     /* Open migration dialog */
1012     if(isset($_POST['deps_visible_migrate'])){
1013       $this->dep_migration_dialog = TRUE;
1014       $this->dialog =TRUE;
1015     }
1017     /* Close migration dialog */
1018     if(isset($_POST['deps_visible_migrate_close'])){
1019       $this->dep_migration_dialog = FALSE;
1020       $this->dialog =FALSE;
1021     }
1023     /* Start migration */
1024     if(isset($_POST['deps_visible_migrate_migrate'])){
1025       if($this->migrate_organizationalUnits()){
1026         $this->check_organizationalUnits();
1027       }
1028     }
1030     /* Start migration */
1031     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1032       $this->migrate_organizationalUnits(TRUE);
1033     }
1035     /* Display migration dialog */
1036     if($this->dep_migration_dialog){
1037       $smarty = get_smarty();
1038       $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
1039       $smarty->assign("method","migrate_deps");
1040       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1041     }
1043     $smarty = get_smarty();
1044     $smarty->assign("checks",$this->checks);
1045     $smarty->assign("method","default");
1046     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1047   }
1050   function save_object()
1051   {
1052     /* Get "create acl" dialog posts */
1053     if($this->acl_create_dialog){
1054       if(isset($_POST['create_acls_create'])){
1055         if(isset($_POST['create_acls_selected'])){
1056           $this->acl_create_selected = base64_decode($_POST['create_acls_selected']);
1057         }else{
1058           $this->acl_create_selected = ""; 
1059         }
1060       }
1062       if(isset($_POST['create_acls_create_abort'])){
1063         $this->acl_create_selected = "";
1064       }
1066       if(isset($_POST['acl_create_type'])){
1067         $this->acl_create_type = $_POST['acl_create_type'];
1068       }
1069     }
1071     /* Get selected departments */
1072     if($this->dep_migration_dialog){
1073       foreach($this->deps_to_migrate as $id => $data){
1074         if(isset($_POST['migrate_'.$id])){
1075           $this->deps_to_migrate[$id]['checked'] = TRUE;
1076         }else{
1077           $this->deps_to_migrate[$id]['checked'] = FALSE;
1078         }
1079       }
1080     }
1082     /* Get selected users */
1083     if($this->users_migration_dialog){
1084       foreach($this->users_to_migrate as $id => $data){
1085         if(isset($_POST['migrate_'.$id])){
1086           $this->users_to_migrate[$id]['checked'] = TRUE;
1087         }else{
1088           $this->users_to_migrate[$id]['checked'] = FALSE;
1089         }
1090       }
1091     }
1092   }
1095   // checks for valid base entry
1096   function checkBase($just_check = TRUE)
1097   {
1098     /* Get collected setup informations */
1099     $cv = $this->parent->captured_values;
1101     /* Establish ldap connection */
1102     $ldap = new LDAP($cv['admin'],
1103         $cv['password'],
1104         $cv['connection'],
1105         FALSE,
1106         $cv['tls']);
1108     /* Check if root object exists */
1109     $ldap->cd($cv['base']);
1110     $res = $ldap->search("(objectClass=*)");
1111     $err = ldap_errno($ldap->cid); 
1113     if( !$res || 
1114         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1115         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1117       /* Root object doesn't exists 
1118        */
1119       if($just_check){
1120         $this->checks['root']['STATUS']    = FALSE;
1121         $this->checks['root']['STATUS_MSG']= _("Failed");
1122         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1123         return(FALSE);
1124       }else{
1126          /* Try to find out which values are necessary */
1127         $tmp = $ldap->get_objectclasses();
1128         $oc = $tmp['organization'];
1129       
1130         $must_attrs = $oc['MUST'];
1131         if(!is_array($must_attrs)){
1132           $must_attrs = array($must_attrs);
1133         }
1134       
1135         /* Root object does not exists try to create it */
1136         $ldapadd["objectclass"][0]="top";
1137         $ldapadd["objectclass"][1]="organization";
1139         /* Try to fill all collected must attributes */
1140         $base_parts = preg_split("/,/",$cv['base']);
1141         foreach($must_attrs as $attr){
1142           foreach($base_parts as $part){
1143             if(preg_match("/^".$attr."=/",$part) && !isset($ldapadd[$attr])){
1144               $ldapadd[$attr]= preg_replace("/^[^=]*+=/","",$part);
1145             }
1146           }
1147         }
1149         /* Add root object */ 
1150         $ldap->cd($cv['base']);
1151         $res = $ldap->add($ldapadd);
1153         /* Add root object */ 
1154  #       $ldap->cd($cv['base']);
1155 #        $res = $ldap->create_missing_trees($cv['base']);
1156   
1157         /* If adding failed, tell the user */
1158         if(!$res){
1159           $this->checks['root']['STATUS']    = FALSE;
1160           $this->checks['root']['STATUS_MSG']= _("Failed");
1161           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1162           $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1163           return($res);;
1164         }
1165       }
1166     }
1168     /* Create & remove of dummy object was successful */
1169     $this->checks['root']['STATUS']    = TRUE;
1170     $this->checks['root']['STATUS_MSG']= _("Ok");
1171   }
1174   /* Return ldif information for a 
1175    * given attribute array 
1176    */
1177   function array_to_ldif($atts)
1178   {
1179     $ret = "";
1180     unset($atts['count']);
1181     unset($atts['dn']);
1182     foreach($atts as $name => $value){
1183       if(is_numeric($name)) {
1184         continue;
1185       }
1186       if(is_array($value)){
1187         unset($value['count']);
1188         foreach($value as $a_val){
1189           $ret .= $name.": ". $a_val."\n";
1190         }
1191       }else{
1192         $ret .= $name.": ". $value."\n";
1193       }
1194     }
1195     return(preg_replace("/\n$/","",$ret));
1196   }
1199 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1200 ?>