Code

Added warning
[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     $tmp = array();
194     while($attrs = $ldap->fetch()){
195       $tmp[$attrs['uidNumber'][0]][] = $attrs;
196     }
198     foreach($tmp as $id => $entries){
199       if(count($entries) > 1){
200         foreach($entries as $entry){
201           $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
202         }
203       }
204     }
206     if($this->check_uidNumbers){
207       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
208       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Failed");
209       $this->checks['uidNumber_usage']['ERROR_MSG'] =
210         sprintf(_("Found %s duplicated uidNumber values."),count($this->check_uidNumbers));
211       return(false);
212     }else{
213       $this->checks['uidNumber_usage']['STATUS']    = TRUE;
214       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
215       $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
216       return(TRUE);
217     }
218   }
220   function check_gidNumber()
221   {
222     $cv = $this->parent->captured_values;
223     $ldap = new LDAP($cv['admin'],
224         $cv['password'],
225         $cv['connection'],
226         FALSE,
227         $cv['tls']);
229     $ldap->cd($cv['base']);
230     $res = $ldap->search("gidNumber=*",array("dn","gidNumber"));
231     if(!$res){
232       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
233       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
234       $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
235       return(false);
236     }
238     $this->check_gidNumbers= array(); 
239     $tmp = array();
240     while($attrs = $ldap->fetch()){
241       $tmp[$attrs['gidNumber'][0]][] = $attrs;
242     }
244     foreach($tmp as $id => $entries){
245       if(count($entries) > 1){
246         foreach($entries as $entry){
247           $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
248         }
249       }
250     }
252     if($this->check_gidNumbers){
253       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
254       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Failed");
255       $this->checks['gidNumber_usage']['ERROR_MSG'] =
256         sprintf(_("Found %s duplicated gidNumber values."),count($this->check_gidNumbers));
257       return(false);
258     }else{
259       $this->checks['gidNumber_usage']['STATUS']    = TRUE;
260       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
261       $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
262       return(TRUE);
263     }
264   }
267   /* Search for winstations outside the winstation ou */
268   function search_outside_winstations()
269   {
270     $cv = $this->parent->captured_values;
271     $ldap = new LDAP($cv['admin'],
272         $cv['password'],
273         $cv['connection'],
274         FALSE,
275         $cv['tls']);
277     /* Get winstation ou */
278     if($cv['generic_settings']['wws_ou_active']) {
279       $winstation_ou = $cv['generic_settings']['ws_ou'];
280     }else{
281       $winstation_ou = "ou=winstations";
282     }
283  
284     $ldap->cd($cv['base']);
285     $res = $ldap->search("(&(objectClass=posixGroup)(sambaGroupType=2)(sambaSID=*))",array("dn","sambaSID"));
286     if(!$res){
287       $this->checks['outside_winstations']['STATUS']    = FALSE;
288       $this->checks['outside_winstations']['STATUS_MSG']= _("Ldap query failed.");
289       $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
290       return(false);
291     }
293     $this->outside_winstations = array();
294     while($attrs = $ldap->fetch()){
295       if(preg_match("/-516$/","",$attrs['sambaSID'][0]) && !preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])){
296         $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
297       }
298     }
300     if(count($this->outside_winstations)){
301       $this->checks['outside_winstations']['STATUS']    = FALSE;
302       $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
303       $this->checks['outside_winstations']['ERROR_MSG'] = 
304         sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
305       return(false);
306     }else{
307       $this->checks['outside_winstations']['STATUS']    = TRUE;
308       $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
309       $this->checks['outside_winstations']['ERROR_MSG'] = "";
310       return(TRUE);
311     }
312   }
315   /* Search for groups outside the group ou */
316   function search_outside_groups()
317   {
318     $cv = $this->parent->captured_values;
319     $ldap = new LDAP($cv['admin'],
320         $cv['password'],
321         $cv['connection'],
322         FALSE,
323         $cv['tls']);
325     $group_ou = $cv['groupou'];
326     $ldap->cd($cv['base']);
327     $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
328     if(!$res){
329       $this->checks['outside_groups']['STATUS']    = FALSE;
330       $this->checks['outside_groups']['STATUS_MSG']= _("Ldap query failed.");
331       $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
332       return(false);
333     }
336     $this->outside_groups = array();
337     while($attrs = $ldap->fetch()){
338       if(!preg_match("/^[^,]+,".normalizePreg($group_ou)."/",$attrs['dn'])){
339         $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
340       }
341     }
343     if(count($this->outside_groups)){
344       $this->checks['outside_groups']['STATUS']    = FALSE;
345       $this->checks['outside_groups']['STATUS_MSG']= _("Failed");
346       $this->checks['outside_groups']['ERROR_MSG'] = 
347         sprintf(_("Found %s groups outside the selected group ou '%s'."),count($this->outside_groups),$group_ou);
348       return(false);
349     }else{
350       $this->checks['outside_groups']['STATUS']    = TRUE;
351       $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
352       $this->checks['outside_groups']['ERROR_MSG'] = "";
353       return(TRUE);
354     }
355   }
357   /* Search for users outside the people ou */
358   function search_outside_users()
359   {
360     $cv = $this->parent->captured_values;
361     $ldap = new LDAP($cv['admin'],
362         $cv['password'],
363         $cv['connection'],
364         FALSE,
365         $cv['tls']);
366     $people_ou = $cv['peopleou'];
367     $ldap->cd($cv['base']);
368     $res = $ldap->search("(objectClass=gosaAccount)",array("dn"));
369     if(!$res){
370       $this->checks['outside_users']['STATUS']    = FALSE;
371       $this->checks['outside_users']['STATUS_MSG']= _("Ldap query failed.");
372       $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
373       return(false);
374     }
377     $this->outside_users = array();
378     while($attrs = $ldap->fetch()){
379       if(!preg_match("/^[^,]+,".normalizePreg($people_ou)."/",$attrs['dn'])){
380         $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
381       }
382     }
384     if(count($this->outside_users)){
385       $this->checks['outside_users']['STATUS']    = FALSE;
386       $this->checks['outside_users']['STATUS_MSG']= _("Failed");
387       $this->checks['outside_users']['ERROR_MSG'] = 
388         sprintf(_("Found %s users outside the selected user ou '%s'."),count($this->outside_users),$people_ou);
389       return(false);
390     }else{
391       $this->checks['outside_users']['STATUS']    = TRUE;
392       $this->checks['outside_users']['STATUS_MSG']= _("Ok");
393       $this->checks['outside_users']['ERROR_MSG'] = "";
394       return(TRUE);
395     }
396   }
399   /* Check ldap accessibility 
400    * Create and remove a dummy object, 
401    *  to ensure that we have the necessary permissions
402    */
403   function check_ldap_permissions()
404   {
405     $cv = $this->parent->captured_values;
406     $ldap = new LDAP($cv['admin'],
407         $cv['password'],
408         $cv['connection'],
409         FALSE,
410         $cv['tls']);
412     /* Create dummy entry 
413      */
414     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
415     $dn       = "ou=".$name.",".$cv['base'];
416     $testEntry= array();
417     $testEntry['objectClass'][]= "top";
418     $testEntry['objectClass'][]= "organizationalUnit";
419     $testEntry['objectClass'][]= "gosaDepartment";
420     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
421     $testEntry['ou']  = $name;
423     /* check if simple ldap cat will be successful 
424      */
425     $res = $ldap->cat($cv['base']);  
426     if(!$res){
427       $this->checks['permissions']['STATUS']    = FALSE;
428       $this->checks['permissions']['STATUS_MSG']= _("Ldap query failed.");
429       $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
430       return(false);
431     }
432   
433     /* Try to create dummy object 
434      */ 
435     $ldap->cd ($dn);
436     $ldap->create_missing_trees($dn);
437     $res = $ldap->add($testEntry);
438     if(!$res){
439       gosa_log($ldap->get_error());
440       $this->checks['permissions']['STATUS']    = FALSE;
441       $this->checks['permissions']['STATUS_MSG']= _("Failed");
442       $this->checks['permissions']['ERROR_MSG'] = 
443         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
444       return(false);
445     }
447     /* Try to remove created entry 
448      */
449     $res = $ldap->rmDir($dn);
450     if(!$res){
451       gosa_log($ldap->get_error());
452       $this->checks['permissions']['STATUS']    = FALSE;
453       $this->checks['permissions']['STATUS_MSG']= _("Failed");
454       $this->checks['permissions']['ERROR_MSG'] = 
455         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
456       return(false);
457     }
459     /* Create & remove of dummy object was successful */
460     $this->checks['permissions']['STATUS']    = TRUE;
461     $this->checks['permissions']['STATUS_MSG']= _("Ok");
462     $this->checks['permissions']['ERROR_MSG'] = "";
463     return(true);
464   } 
467   /* Check if there are users which will 
468    *  be invisible for GOsa 
469    */
470   function check_gosaAccounts()
471   {
472     /* Remember old list of ivisible users, to be able to set 
473      *  the 'html checked' status for the checkboxes again 
474      */
475     $cnt_ok = 0;
476     $old    = $this->users_to_migrate;
477     $this->users_to_migrate = array();
479     /* Get collected configuration settings */
480     $cv = $this->parent->captured_values;
482     /* Establish ldap connection */
483     $ldap = new LDAP($cv['admin'],
484         $cv['password'],
485         $cv['connection'],
486         FALSE,
487         $cv['tls']);
489     /* Get all invisible users 
490      */
491     $ldap->cd($cv['base']); 
492     $res =$ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
493     while($attrs = $ldap->fetch()){
494       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
495         $attrs['checked'] = FALSE;
496         $attrs['before']  = "";
497         $attrs['after']   = "";
499         /* Set objects to selected, that were selected before reload */
500         if(isset($old[base64_encode($attrs['dn'])])){
501           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
502         }
503         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
504       }
505     }
507     /* No invisible */
508     if(!$res){
509       $this->checks['users_visible']['STATUS']    = FALSE;
510       $this->checks['users_visible']['STATUS_MSG']= _("Ldap query failed.");
511       $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
512     }elseif(count($this->users_to_migrate) == 0){
513       $this->checks['users_visible']['STATUS']    = TRUE;
514       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
515       $this->checks['users_visible']['ERROR_MSG'] = "";
516     }else{
517       $this->checks['users_visible']['STATUS']    = FALSE;
518       $this->checks['users_visible']['STATUS_MSG']= "";
519       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."), 
520           count($this->users_to_migrate));
521       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
522     }
523   }
526   /* Start user account migration 
527    */  
528   function migrate_gosaAccounts($only_ldif = FALSE)
529   {
530     /* Get collected configuration settings */
531     $cv = $this->parent->captured_values;
533     /* Establish ldap connection */
534     $ldap = new LDAP($cv['admin'],
535         $cv['password'],
536         $cv['connection'],
537         FALSE,
538         $cv['tls']);
540     /* Add gosaAccount objectClass to the selected users  
541      */
542     foreach($this->users_to_migrate as $key => $dep){
543       if($dep['checked']){
545         /* Get old objectClasses */
546         $ldap->cat($dep['dn'],array("objectClass"));
547         $attrs      = $ldap->fetch();
549         /* Create new objectClass array */
550         $new_attrs  = array();
551         $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
552         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
553           if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
554             $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
555           }
556         }
558         /* Set info attributes for current object, 
559          *  or write changes to the ldap database 
560          */
561         if($only_ldif){
562           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
563           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
564         }else{
565           $ldap->cd($attrs['dn']);
566           if(!$ldap->modify($new_attrs)){
567             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
568             return(false);
569           }
570         }
571       }
572     }
573     return(TRUE);
574   }
577   /* Check if there are invisible organizational Units 
578    */
579   function check_organizationalUnits()
580   {
581     $cnt_ok = 0;
582     $old = $this->deps_to_migrate;
583     $this->deps_to_migrate = array();
585     /* Get collected configuration settings */
586     $cv = $this->parent->captured_values;
588     /* Establish ldap connection */
589     $ldap = new LDAP($cv['admin'],
590         $cv['password'],
591         $cv['connection'],
592         FALSE,
593         $cv['tls']);
595     /* Skip GOsa internal departments */
596     $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
597         "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
598         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
599         "/(,|)ou=winstations,/");
602     /* Get all invisible departments */
603     $ldap->cd($cv['base']); 
604     $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
605     while($attrs = $ldap->fetch()){
606       $attrs['checked'] = FALSE;
607       $attrs['before']  = "";
608       $attrs['after']   = "";
610       /* Set objects to selected, that were selected before reload */
611       if(isset($old[base64_encode($attrs['dn'])])){
612         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
613       }
614       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
615     }
617     /* Filter returned list of departments and ensure that 
618      *  GOsa internal departments will not be listed 
619      */
620     foreach($this->deps_to_migrate as $key => $attrs){
621       $dn = $attrs['dn'];
622       $skip = false;
623       foreach($skip_dns as $skip_dn){
624         if(preg_match($skip_dn,$dn)){
625           $skip = true;
626         }
627       }
628       if($skip){
629         unset($this->deps_to_migrate[$key]);
630       }
631     }
633     /* If we have no invisible departments found  
634      *  tell the user that everything is ok 
635      */
636     if(!$res){
637       $this->checks['deps_visible']['STATUS']    = FALSE;
638       $this->checks['deps_visible']['STATUS_MSG']= _("Ldap query failed.");
639       $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
640     }elseif(count($this->deps_to_migrate) == 0 ){
641       $this->checks['deps_visible']['STATUS']    = TRUE;
642       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
643       $this->checks['deps_visible']['ERROR_MSG'] = "";
644     }else{
645       $this->checks['deps_visible']['STATUS']    = FALSE;
646       $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
647       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
648       $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
649     }
650   }
654   /* Start deparmtment migration */  
655   function migrate_organizationalUnits($only_ldif = FALSE)
656   {
657     /* Get collected configuration settings */
658     $cv = $this->parent->captured_values;
660     /* Establish ldap connection */
661     $ldap = new LDAP($cv['admin'],
662         $cv['password'],
663         $cv['connection'],
664         FALSE,
665         $cv['tls']);
667     /* Add gosaDepartment objectClass to each selected entry 
668      */
669     foreach($this->deps_to_migrate as $key => $dep){
670       if($dep['checked']){
672         /* Get current objectClasses */
673         $ldap->cat($dep['dn'],array("objectClass","description"));
674         $attrs      = $ldap->fetch();
676         /* Create new objectClass attribute including gosaDepartment*/
677         $new_attrs  = array();
678         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
679           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
680         }
681         $new_attrs['objectClass'][] = "gosaDepartment";
683         /* Append description it is missing */
684         if(!isset($attrs['description'])){
685           $new_attrs['description'][] = "GOsa department";
686         }
688         /* Depending on the parameter >only_diff< we save the changes as ldif
689          *  or we write our changes directly to the ldap database
690          */
691         if($only_ldif){
692           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
693           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
694         }else{
695           $ldap->cd($attrs['dn']);
696           if(!$ldap->modify($new_attrs)){
697             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
698             return(false);
699           }
700         }
701       }
702     }
703     return(TRUE);
704   }
707   /* Check Acls if there is at least one object with acls defined 
708    */
709   function check_administrativeAccount()
710   {
711     /* Establish ldap connection */
712     $cv = $this->parent->captured_values;
713     $ldap = new LDAP($cv['admin'],
714         $cv['password'],
715         $cv['connection'],
716         FALSE,
717         $cv['tls']);
719     /* Search for gosaAcls */ 
720     $ldap->cd($cv['base']);
721     $res = $ldap->search("(&(objectClass=gosaAccount)(|(objectClass=posixAccount)".     
722                            "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))");
723     if(!$res){
724       $this->checks['acls']['STATUS']    = FALSE;
725       $this->checks['acls']['STATUS_MSG']= _("Ldap query failed.");
726       $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
727     }elseif($ldap->count()){
728       $this->checks['acls']['STATUS']    = TRUE;
729       $this->checks['acls']['STATUS_MSG']= _("Ok");
730     }else{
731       $this->checks['acls']['STATUS']    = FALSE;
732       $this->checks['acls']['STATUS_MSG']= _("Failed");
733       $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create adminitrational account")."'>";
734     }
735     return($ldap->count()>=1);
736   }
739   function get_user_list()
740   {
741     /* Get collected configuration settings */
742     $cv = $this->parent->captured_values;
744     /* Establish ldap connection */
745     $ldap = new LDAP($cv['admin'],
746         $cv['password'],
747         $cv['connection'],
748         FALSE,
749         $cv['tls']);
750     
751     $ldap->cd($cv['base']);
752     $ldap->search("(objectClass=gosaAccount)",array("dn"));
753   
754     $tmp = array();
755     while($attrs = $ldap->fetch()){
756       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
757     }
759     return($tmp);
760   }
762   function get_group_list()
763   {
764     /* Get collected configuration settings */
765     $cv = $this->parent->captured_values;
767     /* Establish ldap connection */
768     $ldap = new LDAP($cv['admin'],
769         $cv['password'],
770         $cv['connection'],
771         FALSE,
772         $cv['tls']);
773     
774     $ldap->cd($cv['base']);
775     $ldap->search("(objectClass=posixGroup)",array("dn"));
776   
777     $tmp = array();
778     while($attrs = $ldap->fetch()){
779       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
780     }
782     return($tmp);
783   }
787   function create_admin($only_ldif = FALSE)
788   {
789     /* Reset '' */
790     $this->acl_create_changes="";
792     /* Object that should receive admin acls */
793     $dn = $this->acl_create_selected;
795     /* Get collected configuration settings */
796     $cv = $this->parent->captured_values;
798     /* Establish ldap connection */
799     $ldap = new LDAP($cv['admin'],
800         $cv['password'],
801         $cv['connection'],
802         FALSE,
803         $cv['tls']);
805     /* Get current base attributes */
806     $ldap->cd($cv['base']);
807     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
808     $attrs = $ldap->fetch();
810     /* Add acls for the selcted user to the base */
811     $attrs_new['objectClass'] = array("gosaACL");
813     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
814       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
815         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
816       }
817     }
819     $acl = "0:sub:".base64_encode($dn).":all;cmdrw";    
820     $attrs_new['gosaAclEntry'][] = $acl;
821     if(isset($attrs['gosaAclEntry'])){
822       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
823           
824         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
825         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
826  
827         $data = ($prio+1).$rest;
828         $attrs_new['gosaAclEntry'][] = $data;
829       }
830     }
832     if($only_ldif){
833       $this->acl_create_changes ="\n".$cv['base']."\n";
834       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
835       $this->acl_create_changes.="\n".$cv['base']."\n";
836       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
837     }else{
838    
839       $ldap->cd($cv['base']);
840       if(!$ldap->modify($attrs_new)){
841         print_red(sprintf(_("Adding acls for user '%s' failed, ldap says '%s'."),$dn,$ldap->get_error()));
842       }
843     }
844   }
845  
846   
847   function create_admin_user()
848   {
849     if(isset($_POST['new_user_password']) && !empty($_POST['new_user_password'])){
850       $pwd = $_POST['new_user_password'];
851     }else{
852       print_red(_("Please specify a valid password for the new GOsa admin user."));
853       return(FALSE);
854     }
855     
856     /* Establish ldap connection */
857     $cv = $this->parent->captured_values;
858     $ldap = new LDAP($cv['admin'],
859         $cv['password'],
860         $cv['connection'],
861         FALSE,
862         $cv['tls']);
864     /* Get current base attributes */
865     $ldap->cd($cv['base']);
866   
867     if($cv['peopledn'] == "cn"){
868       $dn = "cn=System Administrator,".$cv['peopleou'].",".$cv['base'];
869     }else{
870       $dn = "uid=admin,".$cv['peopleou'].",".$cv['base'];
871     }
873     $methods = @passwordMethod::get_available_methods_if_not_loaded();
874     $p_m = $methods[$cv['encryption']];
875     $p_c = new $p_m(array());
876     $hash = $p_c->generate_hash($pwd);
878     $new_user=array();
879     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
880     $new_user['givenName']  = "System";
881     $new_user['sn']  = "Administrator";
882     $new_user['cn']  = "System Administrator";
883     $new_user['uid'] = "admin";
884     $new_user['userPassword'] = $hash;
885     
886     $ldap->cd($cv['base']);
887     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
888     $ldap->cd($dn);  
889     $res = $ldap->add($new_user);
890     $this->acl_create_selected = $dn;
891     $this->create_admin();
892     
893     if(!$res){
894       print_red($ldap->get_error());
895     }
896   
897     $this->acl_create_dialog=FALSE;        
898     $this->check_administrativeAccount();
899   }
900  
902   function execute()
903   {
904     /* Initialise checks if this is the first call */
905     if(!$this->checks_initialised || isset($_POST['reload'])){
906       $this->initialize_checks();
907       $this->checks_initialised = TRUE;
908     }
909  
910     /*************
911      * Root object check  
912      *************/
913   
914     if(isset($_POST['retry_root_create'])){
915       $this->checkBase(FALSE);
916     }
917  
918     /*************
919      * User Migration handling 
920      *************/
922     if(isset($_POST['retry_acls'])){
923       $this->check_administrativeAccount();
924     }
926     if(isset($_POST['create_acls'])){
927       $this->acl_create_dialog = TRUE;
928       $this->dialog = TRUE;
929     }
930   
931     if(isset($_POST['create_acls_cancel'])){
932       $this->acl_create_dialog = FALSE;
933       $this->dialog = FALSE;
934     }
936     if(isset($_POST['create_acls_create_confirmed'])){
937       $this->create_admin();
938     }
940     if(isset($_POST['create_acls_create'])){
941       $this->create_admin(TRUE);
942     }
944     if(isset($_POST['create_admin_user'])){
945       $this->create_admin_user();
946     }
948     if($this->acl_create_dialog){
949       $smarty = get_smarty();
950       $smarty->assign("new_user_password",@$_POST['new_user_password']);
951       $smarty->assign("users" ,$this->get_user_list());
952       $smarty->assign("users_cnt" ,count($this->get_user_list()));
953       $smarty->assign("groups",$this->get_group_list());
954       $smarty->assign("groups_cnt",count($this->get_group_list()));
955       $smarty->assign("type"  ,$this->acl_create_type);
956       $smarty->assign("method","create_acls");
957       $smarty->assign("acl_create_selected",$this->acl_create_selected);
958       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
959       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
960     }
962     /*************
963      * User Migration handling 
964      *************/
966     /* Refresh list of deparments */
967     if(isset($_POST['users_visible_migrate_refresh'])){
968       $this->check_gosaAccounts();
969     }
971     /* Open migration dialog */
972     if(isset($_POST['users_visible_migrate'])){
973       $this->users_migration_dialog = TRUE;
974       $this->dialog =TRUE;
975     }
977     /* Close migration dialog */
978     if(isset($_POST['users_visible_migrate_close'])){
979       $this->users_migration_dialog = FALSE;
980       $this->dialog =FALSE;
981     }
983     /* Start migration */
984     if(isset($_POST['users_visible_migrate_migrate'])){
985       if($this->migrate_gosaAccounts()){
986         $this->check_gosaAccounts();
987       }
988     }
990     /* Start migration */
991     if(isset($_POST['users_visible_migrate_whatsdone'])){
992       $this->migrate_gosaAccounts(TRUE);
993     }
995     /* Display migration dialog */
996     if($this->users_migration_dialog){
997       $smarty = get_smarty();
998       $smarty->assign("users_to_migrate",$this->users_to_migrate);
999       $smarty->assign("method","migrate_users");
1000       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1001     }
1004     /*************
1005      * Department Migration handling 
1006      *************/
1008     /* Refresh list of deparments */
1009     if(isset($_POST['deps_visible_migrate_refresh'])){
1010       $this->check_organizationalUnits();
1011     }
1013     /* Open migration dialog */
1014     if(isset($_POST['deps_visible_migrate'])){
1015       $this->dep_migration_dialog = TRUE;
1016       $this->dialog =TRUE;
1017     }
1019     /* Close migration dialog */
1020     if(isset($_POST['deps_visible_migrate_close'])){
1021       $this->dep_migration_dialog = FALSE;
1022       $this->dialog =FALSE;
1023     }
1025     /* Start migration */
1026     if(isset($_POST['deps_visible_migrate_migrate'])){
1027       if($this->migrate_organizationalUnits()){
1028         $this->check_organizationalUnits();
1029       }
1030     }
1032     /* Start migration */
1033     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1034       $this->migrate_organizationalUnits(TRUE);
1035     }
1037     /* Display migration dialog */
1038     if($this->dep_migration_dialog){
1039       $smarty = get_smarty();
1040       $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
1041       $smarty->assign("method","migrate_deps");
1042       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1043     }
1045     $smarty = get_smarty();
1046     $smarty->assign("checks",$this->checks);
1047     $smarty->assign("method","default");
1048     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1049   }
1052   function save_object()
1053   {
1054     /* Get "create acl" dialog posts */
1055     if($this->acl_create_dialog){
1056       if(isset($_POST['create_acls_create'])){
1057         if(isset($_POST['create_acls_selected'])){
1058           $this->acl_create_selected = base64_decode($_POST['create_acls_selected']);
1059         }else{
1060           $this->acl_create_selected = ""; 
1061         }
1062       }
1064       if(isset($_POST['create_acls_create_abort'])){
1065         $this->acl_create_selected = "";
1066       }
1068       if(isset($_POST['acl_create_type'])){
1069         $this->acl_create_type = $_POST['acl_create_type'];
1070       }
1071     }
1073     /* Get selected departments */
1074     if($this->dep_migration_dialog){
1075       foreach($this->deps_to_migrate as $id => $data){
1076         if(isset($_POST['migrate_'.$id])){
1077           $this->deps_to_migrate[$id]['checked'] = TRUE;
1078         }else{
1079           $this->deps_to_migrate[$id]['checked'] = FALSE;
1080         }
1081       }
1082     }
1084     /* Get selected users */
1085     if($this->users_migration_dialog){
1086       foreach($this->users_to_migrate as $id => $data){
1087         if(isset($_POST['migrate_'.$id])){
1088           $this->users_to_migrate[$id]['checked'] = TRUE;
1089         }else{
1090           $this->users_to_migrate[$id]['checked'] = FALSE;
1091         }
1092       }
1093     }
1094   }
1097   // checks for valid base entry
1098   function checkBase($just_check = TRUE)
1099   {
1100     /* Get collected setup informations */
1101     $cv = $this->parent->captured_values;
1103     /* Establish ldap connection */
1104     $ldap = new LDAP($cv['admin'],
1105         $cv['password'],
1106         $cv['connection'],
1107         FALSE,
1108         $cv['tls']);
1110     /* Check if root object exists */
1111     $ldap->cd($cv['base']);
1112     $res = $ldap->search("(objectClass=*)");
1113     $err = ldap_errno($ldap->cid); 
1115     if( !$res || 
1116         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1117         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1119       /* Root object doesn't exists 
1120        */
1121       if($just_check){
1122         $this->checks['root']['STATUS']    = FALSE;
1123         $this->checks['root']['STATUS_MSG']= _("Failed");
1124         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1125         return(FALSE);
1126       }else{
1128       echo "REMOVE this : Autocreation of the root object will be donw be create_missing_trees later. !!!!!!!";
1130          /* Try to find out which values are necessary */
1131         $tmp = $ldap->get_objectclasses();
1132         $oc = $tmp['organization'];
1133       
1134         $must_attrs = $oc['MUST'];
1135         if(!is_array($must_attrs)){
1136           $must_attrs = array($must_attrs);
1137         }
1138       
1139         /* Root object does not exists try to create it */
1140         $ldapadd["objectclass"][0]="top";
1141         $ldapadd["objectclass"][1]="organization";
1143         /* Try to fill all collected must attributes */
1144         $base_parts = preg_split("/,/",$cv['base']);
1145         foreach($must_attrs as $attr){
1146           foreach($base_parts as $part){
1147             if(preg_match("/^".$attr."=/",$part) && !isset($ldapadd[$attr])){
1148               $ldapadd[$attr]= preg_replace("/^[^=]*+=/","",$part);
1149             }
1150           }
1151         }
1153         /* Add root object */ 
1154         $ldap->cd($cv['base']);
1155         $res = $ldap->add($ldapadd);
1157         /* Add root object */ 
1158  #       $ldap->cd($cv['base']);
1159 #        $res = $ldap->create_missing_trees($cv['base']);
1160   
1161         /* If adding failed, tell the user */
1162         if(!$res){
1163           $this->checks['root']['STATUS']    = FALSE;
1164           $this->checks['root']['STATUS_MSG']= _("Failed");
1165           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1166           $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1167           return($res);;
1168         }
1169       }
1170     }
1172     /* Create & remove of dummy object was successful */
1173     $this->checks['root']['STATUS']    = TRUE;
1174     $this->checks['root']['STATUS_MSG']= _("Ok");
1175   }
1178   /* Return ldif information for a 
1179    * given attribute array 
1180    */
1181   function array_to_ldif($atts)
1182   {
1183     $ret = "";
1184     unset($atts['count']);
1185     unset($atts['dn']);
1186     foreach($atts as $name => $value){
1187       if(is_numeric($name)) {
1188         continue;
1189       }
1190       if(is_array($value)){
1191         unset($value['count']);
1192         foreach($value as $a_val){
1193           $ret .= $name.": ". $a_val."\n";
1194         }
1195       }else{
1196         $ret .= $name.": ". $value."\n";
1197       }
1198     }
1199     return(preg_replace("/\n$/","",$ret));
1200   }
1203 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1204 ?>