Code

32bc9dd1d91fe45b023d80a88babd01fed964c84
[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  */
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();
62   var $show_details         = FALSE;
64   /* Department migration attributes */
65   var $users_migration_dialog= FALSE;
66   var $users_to_migrate      = array();
68   /* Create Acl attributes */
69   var $acl_create_dialog  = FALSE;
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   /* Device migration */
86   var $device_dialog         = FALSE;
87   var $device                = array();
89   /* Service migration */
90   var $service_dialog         = FALSE;
91   var $service                = array();
93   /* Group menus */
94   var $menu_dialog           = FALSE;
95   var $menu                  = array();
97   /* Win-Workstations outside to reserved ou */
98   var $outside_winstations        = array();
99   var $outside_winstations_dialog = FALSE;
101   /* check for multiple use of same uidNumber */
102   var $check_uidNumbers        = array();
103   var $check_uidNumbers_dialog = FALSE;
105   /* check for multiple use of same gidNumber */
106   var $check_gidNumbers        = array();
107   var $check_gidNumbers_dialog = FALSE;
109   var $group_list              = array();
111   function Step_Migrate()
112   {
113     $this->update_strings(); 
114   }
116   function update_strings()
117   {
118     $this->s_title      = _("LDAP inspection");
119     $this->s_title_long = _("LDAP inspection");
120     $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
121   }
123   function initialize_checks()
124   {
125     $this->checks = array();
126     $this->checks['root']['TITLE']     = _("Checking for root object");
127     $this->checks['root']['STATUS']    = FALSE;
128     $this->checks['root']['STATUS_MSG']= "";
129     $this->checks['root']['ERROR_MSG'] = "";
130     $this->checkBase();
132     $this->checks['permissions']['TITLE']     = _("Checking permissions on LDAP database");
133     $this->checks['permissions']['STATUS']    = FALSE;
134     $this->checks['permissions']['STATUS_MSG']= "";
135     $this->checks['permissions']['ERROR_MSG'] = "";
136     $this->check_ldap_permissions();
138     $this->checks['deps_visible']['TITLE']     = _("Checking for invisible departments");
139     $this->checks['deps_visible']['STATUS']    = FALSE;
140     $this->checks['deps_visible']['STATUS_MSG']= "";
141     $this->checks['deps_visible']['ERROR_MSG'] = "";
143     $this->checks['users_visible']['TITLE']     = _("Checking for invisible users");
144     $this->checks['users_visible']['STATUS']    = FALSE;
145     $this->checks['users_visible']['STATUS_MSG']= "";
146     $this->checks['users_visible']['ERROR_MSG'] = "";
147     $this->check_gosaAccounts();
149     $this->checks['acls']['TITLE']     = _("Checking for super administrator");
150     $this->checks['acls']['STATUS']    = FALSE;
151     $this->checks['acls']['STATUS_MSG']= "";
152     $this->checks['acls']['ERROR_MSG'] = "";
153     $this->check_administrativeAccount();
155     $this->checks['outside_users']['TITLE']     = _("Checking for users outside the people tree");
156     $this->checks['outside_users']['STATUS']    = FALSE;
157     $this->checks['outside_users']['STATUS_MSG']= "";
158     $this->checks['outside_users']['ERROR_MSG'] = "";
159     $this->search_outside_users();
161     $this->checks['outside_groups']['TITLE']     = _("Checking for groups outside the groups tree");
162     $this->checks['outside_groups']['STATUS']    = FALSE;
163     $this->checks['outside_groups']['STATUS_MSG']= "";
164     $this->checks['outside_groups']['ERROR_MSG'] = "";
165     $this->search_outside_groups();
166     $this->check_organizationalUnits();
168     $this->checks['outside_winstations']['TITLE']     = _("Checking for windows workstations outside the winstation tree");
169     $this->checks['outside_winstations']['STATUS']    = FALSE;
170     $this->checks['outside_winstations']['STATUS_MSG']= "";
171     $this->checks['outside_winstations']['ERROR_MSG'] = "";
172     $this->search_outside_winstations();
174     $this->checks['uidNumber_usage']['TITLE']     = _("Checking for duplicated UID numbers");
175     $this->checks['uidNumber_usage']['STATUS']    = FALSE;
176     $this->checks['uidNumber_usage']['STATUS_MSG']= "";
177     $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
178     $this->check_uidNumber();
180     $this->checks['gidNumber_usage']['TITLE']     = _("Checking for duplicate GID numbers");
181     $this->checks['gidNumber_usage']['STATUS']    = FALSE;
182     $this->checks['gidNumber_usage']['STATUS_MSG']= "";
183     $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
184     $this->check_gidNumber();
186     $this->checks['old_style_devices']['TITLE']     = _("Checking for old style USB devices");
187     $this->checks['old_style_devices']['STATUS']    = FALSE;
188     $this->checks['old_style_devices']['STATUS_MSG']= "";
189     $this->checks['old_style_devices']['ERROR_MSG'] = "";
190     $this->check_usb_devices();
192     $this->checks['old_style_services']['TITLE']     = _("Checking for old services that have to be migrated");
193     $this->checks['old_style_services']['STATUS']    = FALSE;
194     $this->checks['old_style_services']['STATUS_MSG']= "";
195     $this->checks['old_style_services']['ERROR_MSG'] = "";
196     $this->check_services();
198     $this->checks['old_style_menus']['TITLE']     = _("Checking for old style application menus");
199     $this->checks['old_style_menus']['STATUS']    = FALSE;
200     $this->checks['old_style_menus']['STATUS_MSG']= "";
201     $this->checks['old_style_menus']['ERROR_MSG'] = "";
202     $this->check_menus();
203   }
206   /* Check if there are uidNumbers which are used more than once. 
207    */
208   function check_uidNumber()
209   {
210     /* Establish ldap connection */
211     $cv = $this->parent->captured_values;
212     $ldap_l = new LDAP($cv['admin'],
213         $cv['password'],
214         $cv['connection'],
215         FALSE,
216         $cv['tls']);
218     $ldap = new ldapMultiplexer($ldap_l);
220     $ldap->cd($cv['base']);
221     $res = $ldap->search("(&(objectClass=posixAccount)(uidNumber=*))",array("dn","uidNumber"));
222     if(!$res){
223       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
224       $this->checks['uidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
225       $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
226       return(false);
227     }
229     $this->check_uidNumbers= array(); 
230     $tmp = array();
231     while($attrs = $ldap->fetch()){
232       $tmp[$attrs['uidNumber'][0]][] = $attrs;
233     }
235     foreach($tmp as $id => $entries){
236       if(count($entries) > 1){
237         foreach($entries as $entry){
238           $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
239         }
240       }
241     }
243     if($this->check_uidNumbers){
244       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
245       $this->checks['uidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
246       $this->checks['uidNumber_usage']['ERROR_MSG'] =
247         sprintf(_("Found %s duplicate values for attribute 'uidNumber'."),count($this->check_uidNumbers));
248       return(false);
249     }else{
250       $this->checks['uidNumber_usage']['STATUS']    = TRUE;
251       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
252       $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
253       return(TRUE);
254     }
255   }
257   
258   /* Check if there are duplicated gidNumbers present in ldap
259    */
260   function check_gidNumber()
261   {
262     /* Establish ldap connection */
263     $cv = $this->parent->captured_values;
264     $ldap_l = new LDAP($cv['admin'],
265         $cv['password'],
266         $cv['connection'],
267         FALSE,
268         $cv['tls']);
270     $ldap = new ldapMultiplexer($ldap_l);
272     $ldap->cd($cv['base']);
273     $res = $ldap->search("(&(objectClass=posixGroup)(gidNumber=*))",array("dn","gidNumber"));
274     if(!$res){
275       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
276       $this->checks['gidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
277       $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
278       return(false);
279     }
281     $this->check_gidNumbers= array(); 
282     $tmp = array();
283     while($attrs = $ldap->fetch()){
284       $tmp[$attrs['gidNumber'][0]][] = $attrs;
285     }
287     foreach($tmp as $id => $entries){
288       if(count($entries) > 1){
289         foreach($entries as $entry){
290           $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
291         }
292       }
293     }
295     if($this->check_gidNumbers){
296       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
297       $this->checks['gidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
298       $this->checks['gidNumber_usage']['ERROR_MSG'] =
299         sprintf(_("Found %s duplicate values for attribute 'gidNumber'."),count($this->check_gidNumbers));
300       return(false);
301     }else{
302       $this->checks['gidNumber_usage']['STATUS']    = TRUE;
303       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
304       $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
305       return(TRUE);
306     }
307   }
310   /* Search for winstations outside the winstation ou 
311    */
312   function search_outside_winstations()
313   {
314     /* Establish ldap connection */
315     $cv = $this->parent->captured_values;
316     $ldap_l = new LDAP($cv['admin'],
317         $cv['password'],
318         $cv['connection'],
319         FALSE,
320         $cv['tls']);
322     $ldap = new ldapMultiplexer($ldap_l);
324     /* Get winstation ou */
325     if($cv['generic_settings']['wws_ou_active']) {
326       $winstation_ou = $cv['generic_settings']['wws_ou'];
327     }else{
328       $winstation_ou = "ou=winstations";
329     }
331     if($cv['samba_version'] == 3){
332       $oc = "sambaSamAccount";
333     }else{
334       $oc = "sambaAccount";
335     }
336  
337     $ldap->cd($cv['base']);
338     $res = $ldap->search("(&(objectClass=".$oc.")(uid=*$))",array("dn","sambaSID"));
339     if(!$res){
340       $this->checks['outside_winstations']['STATUS']    = FALSE;
341       $this->checks['outside_winstations']['STATUS_MSG']= _("LDAP query failed");
342       $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
343       return(false);
344     }
346     $this->outside_winstations = array();
347     while($attrs = $ldap->fetch()){
348       if((!preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])) && !preg_match("/,dc=addressbook,/",$attrs['dn'])){
349         $attrs['selected'] = FALSE;
350         $attrs['ldif']     = "";
351         $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
352       }
353     }
355     if(count($this->outside_winstations)){
356       $this->checks['outside_winstations']['STATUS']    = FALSE;
357       $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
358       $this->checks['outside_winstations']['ERROR_MSG'] = 
359         sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
360       $this->checks['outside_winstations']['ERROR_MSG'].= "<input type='submit' name='outside_winstations_dialog' value='"._("Migrate")."...'>";
361       return(false);
362     }else{
363       $this->checks['outside_winstations']['STATUS']    = TRUE;
364       $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
365       $this->checks['outside_winstations']['ERROR_MSG'] = "";
366       return(TRUE);
367     }
368   }
371   /* Search for groups outside the group ou 
372    */
373   function search_outside_groups()
374   {
375     /* Establish ldap connection */
376     $cv = $this->parent->captured_values;
377     $ldap_l = new LDAP($cv['admin'],
378         $cv['password'],
379         $cv['connection'],
380         FALSE,
381         $cv['tls']);
383     $ldap = new ldapMultiplexer($ldap_l);
385     $group_ou = $cv['groupou'];
386     $ldap->cd($cv['base']);
388     /***********
389      * Get all gosaDepartments to be able to
390      *  validate correct ldap tree position of every single user
391      ***********/
392     $valid_deps = array();
393     $valid_deps['/'] = $cv['base'];
394     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
395     while($attrs = $ldap->fetch()){
396       $valid_deps[] = $attrs['dn'];
397     }
399     /***********
400      * Get all groups
401      ***********/
402     $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
403     if(!$res){
404       $this->checks['outside_groups']['STATUS']    = FALSE;
405       $this->checks['outside_groups']['STATUS_MSG']= _("LDAP query failed");
406       $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
407       return(false);
408     }
410     $this->outside_groups = array();
411     $this->groups_list = array();;
412     while($attrs = $ldap->fetch()){
413       $group_db_base = preg_replace("/^[^,]+,".normalizePreg($group_ou)."+,/i","",$attrs['dn']);
415       /* Check if entry is not an addressbook only user
416        *  and verify that he is in a valid department
417        */
418       if( !preg_match("/".normalizePreg("dc=addressbook,")."/",$group_db_base) &&
419           !in_array($group_db_base,$valid_deps)
420         ){
421         $attrs['selected'] = FALSE;
422         $attrs['ldif']     = "";
423         $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
424       }
425       $this->group_list[] = $attrs['dn'];
426     }
428     if(count($this->outside_groups)){
429       $this->checks['outside_groups']['STATUS']    = FALSE;
430       $this->checks['outside_groups']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
431       $this->checks['outside_groups']['ERROR_MSG'] =
432         sprintf(_("Found %s groups outside the configured tree '%s'."),count($this->outside_groups),$group_ou);
433       $this->checks['outside_groups']['ERROR_MSG'].= "&nbsp;<input type='submit' name='outside_groups_dialog' value='"._("Move")."...'>";
434       return(false);
435     }else{
436       $this->checks['outside_groups']['STATUS']    = TRUE;
437       $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
438       $this->checks['outside_groups']['ERROR_MSG'] = "";
439       return(TRUE);
440     }
441   }
443  /* Search for users outside the people ou
444    */
445   function search_outside_users()
446   {
447     /* Establish ldap connection */
448     $cv = $this->parent->captured_values;
449     $ldap_l = new LDAP($cv['admin'],
450         $cv['password'],
451         $cv['connection'],
452         FALSE,
453         $cv['tls']);
455     $ldap = new ldapMultiplexer($ldap_l);
456     $ldap->cd($cv['base']);
459     /***********
460      * Get all gosaDepartments to be able to
461      *  validate correct ldap tree position of every single user
462      ***********/
463     $valid_deps = array();
464     $valid_deps['/'] = $cv['base'];
465     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
466     while($attrs = $ldap->fetch()){
467       $valid_deps[] = $attrs['dn'];
468     }
470     /***********
471      * Search for all users
472      ***********/
473     $res = $ldap->search("(&(objectClass=gosaAccount)(!(uid=*$)))",array("dn"));
474     if(!$res){
475       $this->checks['outside_users']['STATUS']    = FALSE;
476       $this->checks['outside_users']['STATUS_MSG']= _("LDAP query failed");
477       $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
478       return(false);
479     }
481     /***********
482      * Check if returned users are within a valid GOsa deparmtment. (peopleou,gosaDepartment,base)
483      ***********/
484     $this->outside_users = array();
485     $people_ou = trim($cv['peopleou']);
486     if(!empty($people_ou)){
487       $people_ou = $people_ou.",";
488     }
490     while($attrs = $ldap->fetch()){
491       $people_db_base = preg_replace("/^[^,]+,".normalizePreg($people_ou)."/i","",$attrs['dn']);
493       /* Check if entry is not an addressbook only user
494        *  and verify that he is in a valid department
495        */
496       if( !preg_match("/".normalizePreg("dc=addressbook,")."/",$people_db_base) &&
497           !in_array($people_db_base,$valid_deps)
498          ){
499         $attrs['selected'] = FALSE;
500         $attrs['ldif']     = "";
501         $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
502       }
503     }
505     if(count($this->outside_users)){
506       $this->checks['outside_users']['STATUS']    = FALSE;
507       $this->checks['outside_users']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
508       $this->checks['outside_users']['ERROR_MSG'] =
509         sprintf(_("Found %s user(s) outside the configured tree '%s'."),count($this->outside_users),$people_ou);
510       $this->checks['outside_users']['ERROR_MSG'].= "<input type='submit' name='outside_users_dialog' value='"._("Move")."...'>";
511       return(false);
512     }else{
513       $this->checks['outside_users']['STATUS']    = TRUE;
514       $this->checks['outside_users']['STATUS_MSG']= _("Ok");
515       $this->checks['outside_users']['ERROR_MSG'] = "";
516       return(TRUE);
517     }
518   }
521   /* Check ldap accessibility 
522    * Create and remove a dummy object, 
523    *  to ensure that we have the necessary permissions
524    */
525   function check_ldap_permissions()
526   {
527     /* Establish ldap connection */
528     $cv = $this->parent->captured_values;
529     $ldap_l = new LDAP($cv['admin'],
530         $cv['password'],
531         $cv['connection'],
532         FALSE,
533         $cv['tls']);
535     $ldap = new ldapMultiplexer($ldap_l);
537     /* Create dummy entry 
538      */
539     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
540     $dn       = "ou=".$name.",".$cv['base'];
541     $testEntry= array();
542     $testEntry['objectClass'][]= "top";
543     $testEntry['objectClass'][]= "organizationalUnit";
544     $testEntry['objectClass'][]= "gosaDepartment";
545     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
546     $testEntry['ou']  = $name;
548     /* check if simple ldap cat will be successful 
549      */
550     $res = $ldap->cat($cv['base']);  
551     if(!$res){
552       $this->checks['permissions']['STATUS']    = FALSE;
553       $this->checks['permissions']['STATUS_MSG']= _("LDAP query failed");
554       $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
555       return(false);
556     }
557   
558     /* Try to create dummy object 
559      */ 
560     $ldap->cd ($dn);
561     $ldap->create_missing_trees($dn);
562     $res = $ldap->add($testEntry);
563     $ldap->cat($dn);
564     if(!$ldap->count()){
565       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
567       $this->checks['permissions']['STATUS']    = FALSE;
568       $this->checks['permissions']['STATUS_MSG']= _("Failed");
569       $this->checks['permissions']['ERROR_MSG'] = 
570         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
571       return(false);
572     }
574     /* Try to remove created entry 
575      */
576     $res = $ldap->rmDir($dn);
577     $ldap->cat($dn);
578     if($ldap->count()){
579       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
580       $this->checks['permissions']['STATUS']    = FALSE;
581       $this->checks['permissions']['STATUS_MSG']= _("Failed");
582       $this->checks['permissions']['ERROR_MSG'] = 
583         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
584       return(false);
585     }
587     /* Create & remove of dummy object was successful */
588     $this->checks['permissions']['STATUS']    = TRUE;
589     $this->checks['permissions']['STATUS_MSG']= _("Ok");
590     $this->checks['permissions']['ERROR_MSG'] = "";
591     return(true);
592   } 
595   /* Check if there are users which will 
596    *  be invisible for GOsa 
597    */
598   function check_gosaAccounts()
599   {
600     /* Remember old list of ivisible users, to be able to set 
601      *  the 'html checked' status for the checkboxes again 
602      */
603     $cnt_ok = 0;
604     $old    = $this->users_to_migrate;
605     $this->users_to_migrate = array();
607     /* Establish ldap connection */
608     $cv = $this->parent->captured_values;
609     $ldap_l = new LDAP($cv['admin'],
610         $cv['password'],
611         $cv['connection'],
612         FALSE,
613         $cv['tls']);
615     $ldap = new ldapMultiplexer($ldap_l);
617     /* Get all invisible users 
618      */
619     $ldap->cd($cv['base']); 
620     $res =$ldap->search("(&(|(objectClass=posixAccount)(&(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))(!(objectClass=gosaAccount))(uid=*))",array("sn","givenName","cn","uid"));
621     while($attrs = $ldap->fetch()){
622       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
623         $attrs['checked'] = FALSE;
624         $attrs['before']  = "";
625         $attrs['after']   = "";
627         /* Set objects to selected, that were selected before reload */
628         if(isset($old[base64_encode($attrs['dn'])])){
629           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
630         }
631         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
632       }
633     }
635     /* No invisible */
636     if(!$res){
637       $this->checks['users_visible']['STATUS']    = FALSE;
638       $this->checks['users_visible']['STATUS_MSG']= _("LDAP query failed");
639       $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
640     }elseif(count($this->users_to_migrate) == 0){
641       $this->checks['users_visible']['STATUS']    = TRUE;
642       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
643       $this->checks['users_visible']['ERROR_MSG'] = "";
644     }else{
645       $this->checks['users_visible']['STATUS']    = FALSE;
646       $this->checks['users_visible']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
647       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s user(s) that will not be visible in GOsa."), 
648           count($this->users_to_migrate));
649       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."...'>";
650     }
651   }
654   /* Start user account migration 
655    */  
656   function migrate_gosaAccounts($only_ldif = FALSE)
657   {
658     $this->show_details= $only_ldif;
660     /* Establish ldap connection */
661     $cv = $this->parent->captured_values;
662     $ldap_l = new LDAP($cv['admin'],
663         $cv['password'],
664         $cv['connection'],
665         FALSE,
666         $cv['tls']);
668     $ldap = new ldapMultiplexer($ldap_l);
670     /* Add gosaAccount objectClass to the selected users  
671      */
672     foreach($this->users_to_migrate as $key => $dep){
673       if($dep['checked']){
675         /* Get old objectClasses */
676         $ldap->cat($dep['dn'],array("objectClass"));
677         $attrs      = $ldap->fetch();
679         /* Create new objectClass array */
680         $new_attrs  = array();
681         $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
682         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
683           if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
684             $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
685           }
686         }
688         /* Set info attributes for current object, 
689          *  or write changes to the ldap database 
690          */
691         if($only_ldif){
692           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
693           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
694         }else{
695           $ldap->cd($attrs['dn']);
696           if(!$ldap->modify($new_attrs)){
697             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']),$ldap->get_error()), ERROR_DIALOG);
698             return(false);
699           }
700         }
701       }
702     }
703     return(TRUE);
704   }
707   /* Check if there are invisible organizational Units 
708    */
709   function check_organizationalUnits()
710   {
711     $cnt_ok = 0;
712     $old = $this->deps_to_migrate;
713     $this->deps_to_migrate = array();
715     /* Establish ldap connection */
716     $cv = $this->parent->captured_values;
717     $ldap_l = new LDAP($cv['admin'],
718         $cv['password'],
719         $cv['connection'],
720         FALSE,
721         $cv['tls']);
723     $ldap = new ldapMultiplexer($ldap_l);
725     /* Skip GOsa internal departments */
726     $skip_dns = array("/".$cv['peopleou']."/","/".$cv['groupou']."/","/^ou=people,/","/^ou=groups,/","/^ou=sudoers,/",
727         "/(,|)ou=configs,/","/(,|)ou=systems,/",
728         "/(,|)ou=apps,/","/(,|)ou=mime,/","/(,|)ou=devices/","/^ou=aclroles,/","/^ou=incoming,/",
729         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
730         "/(,|)ou=winstations,/");
732     /* Get all invisible departments */
733     $ldap->cd($cv['base']); 
734     $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
735     while($attrs = $ldap->fetch()){
736       $attrs['checked'] = FALSE;
737       $attrs['before']  = "";
738       $attrs['after']   = "";
740       /* Set objects to selected, that were selected before reload */
741       if(isset($old[base64_encode($attrs['dn'])])){
742         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
743       }
744       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
745     }
747     /* Filter returned list of departments and ensure that 
748      *  GOsa internal departments will not be listed 
749      */
750     foreach($this->deps_to_migrate as $key => $attrs){
751       $dn = $attrs['dn'];
752       $skip = false;;
754       /* Check if this object is an application release object
755           e.g. groups-> application menus.
756        */
757       if(preg_match("/^.*,[ ]*cn=/",$dn)){
758         $cn_dn = preg_replace("/^.*,[ ]*cn=/","cn=",$dn);
759         if(in_array($cn_dn,$this->group_list)){
760           $skip = true;
761         }
762       }
763     
764       foreach($skip_dns as $skip_dn){
765         if(preg_match($skip_dn,$dn)){
766           $skip = true;
767         }
768       }
769       if($skip){
770         unset($this->deps_to_migrate[$key]);
771       }
772     }
774     /* If we have no invisible departments found  
775      *  tell the user that everything is ok 
776      */
777     if(!$res){
778       $this->checks['deps_visible']['STATUS']    = FALSE;
779       $this->checks['deps_visible']['STATUS_MSG']= _("LDAP query failed");
780       $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
781     }elseif(count($this->deps_to_migrate) == 0 ){
782       $this->checks['deps_visible']['STATUS']    = TRUE;
783       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
784       $this->checks['deps_visible']['ERROR_MSG'] = "";
785     }else{
786       $this->checks['deps_visible']['STATUS']    = TRUE;
787       $this->checks['deps_visible']['STATUS_MSG']= '<font style="color:#FFA500">'._("Warning").'</font>';
788       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s department(s) that will not be visible in GOsa."),count($this->deps_to_migrate));
789       $this->checks['deps_visible']['ERROR_MSG'] .= "&nbsp;<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."...'>";
790     }
791   }
795   /* Start deparmtment migration */  
796   function migrate_organizationalUnits($only_ldif = FALSE)
797   {
798     $this->show_details= $only_ldif;
800     /* Establish ldap connection */
801     $cv = $this->parent->captured_values;
802     $ldap_l = new LDAP($cv['admin'],
803         $cv['password'],
804         $cv['connection'],
805         FALSE,
806         $cv['tls']);
808     $ldap = new ldapMultiplexer($ldap_l);
810     /* Add gosaDepartment objectClass to each selected entry 
811      */
812     foreach($this->deps_to_migrate as $key => $dep){
813       if($dep['checked']){
815         /* Get current objectClasses */
816         $ldap->cat($dep['dn'],array("objectClass","description"));
817         $attrs      = $ldap->fetch();
819         /* Create new objectClass attribute including gosaDepartment*/
820         $new_attrs  = array();
821         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
822           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
823         }
824         $new_attrs['objectClass'][] = "gosaDepartment";
826         /* Append description it is missing */
827         if(!isset($attrs['description'])){
828           $new_attrs['description'][] = "GOsa department";
829         }
831         /* Depending on the parameter >only_diff< we save the changes as ldif
832          *  or we write our changes directly to the ldap database
833          */
834         if($only_ldif){
835           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
836           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
837         }else{
838           $ldap->cd($attrs['dn']);
839           if(!$ldap->modify($new_attrs)){
840             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']), $ldap->get_error()), ERROR_DIALOG);
841             return(false);
842           }
843         }
844       }
845     }
846     return(TRUE);
847   }
850   /* Check Acls if there is at least one object with acls defined 
851    */
852   function check_administrativeAccount()
853   {
854     /* Establish ldap connection */
855     $cv = $this->parent->captured_values;
856     $ldap_l = new LDAP($cv['admin'],
857         $cv['password'],
858         $cv['connection'],
859         FALSE,
860         $cv['tls']);
862     $ldap = new ldapMultiplexer($ldap_l);
863     $ldap->cd($cv['base']);
864     $res = $ldap->cat($cv['base']);
865     
866     if(!$res){
867       $this->checks['acls']['STATUS']    = FALSE;
868       $this->checks['acls']['STATUS_MSG']= _("LDAP query failed");
869       $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
870     }else{
871       $found = false;
872       $username = "";
873       $attrs = $ldap->fetch();
874       if(isset($attrs['gosaAclEntry'])){
875         $acls = $attrs['gosaAclEntry'];
876         for($i = 0 ; $i < $acls['count'] ; $i++){
877           $acl = $acls[$i];
878           $tmp = split(":",$acl);
879           if($tmp[1] == "psub"){
880             $members = split(",",$tmp[2]);
881             foreach($members as $member){
882               $member = base64_decode($member);
884               /* Check if acl owner is a valid GOsa user account */
885               $ldap->cat($member,array("objectClass","uid","cn"));
886               $ret = $ldap->fetch();
888               if(isset($ret['objectClass']) && in_array("posixGroup",$ret['objectClass'])){
889                 $found = TRUE;
890                 $username .= "ACL-Group:&nbsp;".$ret['cn'][0]."<br>";
891               }elseif(isset($ret['objectClass']) && in_array("gosaAccount",$ret['objectClass']) &&
892                   in_array("organizationalPerson",$ret['objectClass']) &&
893                   in_array("inetOrgPerson",$ret['objectClass'])){
894                 $found = TRUE;
895                 $username .= "ACL:&nbsp;".$ret['uid'][0]."<br>";
896               }
897             }
898           }elseif($tmp[1] == "role"){
900             /* Check if acl owner is a valid GOsa user account */
901             $ldap->cat(base64_decode($tmp[2]),array("gosaAclTemplate"));
902             $ret = $ldap->fetch();
904             if(isset($ret['gosaAclTemplate'])){
905               $cnt = $ret['gosaAclTemplate']['count'];
906               for($e = 0 ; $e < $cnt ; $e++){
908                 $a_str = $ret['gosaAclTemplate'][$e];
909                 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all;cmdrw$/",$a_str)){
911                   $members = split(",",$tmp[3]);
912                   foreach($members as $member){
913                     $member = base64_decode($member);
915                     /* Check if acl owner is a valid GOsa user account */
916                     $ldap->cat($member,array("objectClass","uid"));
917                     $ret = $ldap->fetch();
918   
919                     if(isset($ret['objectClass']) && in_array("gosaAccount",$ret['objectClass']) &&
920                         in_array("organizationalPerson",$ret['objectClass']) &&
921                         in_array("inetOrgPerson",$ret['objectClass'])){
922                       $found = TRUE;
923                       $username .= "ACL Role:&nbsp;".$ret['uid'][0]."<br>";
924                     }
925                   }
926                 }
927               }
928             }
929           }
930         }
931       }
933       # For debugging
934       #echo $username;
936       if($found){
937         $this->checks['acls']['STATUS']    = TRUE;
938         $this->checks['acls']['STATUS_MSG']= _("Ok");
939         $this->checks['acls']['ERROR_MSG'] = "";
940       }else{
941         $this->checks['acls']['STATUS']    = FALSE;
942         $this->checks['acls']['STATUS_MSG']= _("Failed");
943         $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")."&nbsp;";
944         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
945       }
946     }
947     return($ldap->count()>=1);
948   }
952   function create_admin($only_ldif = FALSE)
953   {
954     /* Reset '' */
955     $this->acl_create_changes="";
957     /* Object that should receive admin acls */
958     $dn = $this->acl_create_selected;
960     /* Get collected configuration settings */
961     $cv = $this->parent->captured_values;
963     /* On first call check for rid/sid base */
964     $ldap_l = new LDAP($cv['admin'],
965         $cv['password'],
966         $cv['connection'],
967         FALSE,
968         $cv['tls']);
970     $ldap = new ldapMultiplexer($ldap_l);
972     /* Get current base attributes */
973     $ldap->cd($cv['base']);
974     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
975     $attrs = $ldap->fetch();
977     /* Add acls for the selcted user to the base */
978     $attrs_new = array();
979     $attrs_new['objectClass'] = array("gosaACL");
981     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
982       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
983         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
984       }
985     }
987     $acl = "0:psub:".base64_encode($dn).":all;cmdrw";    
988     $attrs_new['gosaAclEntry'][] = $acl;
989     if(isset($attrs['gosaAclEntry'])){
990       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
991           
992         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
993         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
994  
995         $data = ($prio+1).$rest;
996         $attrs_new['gosaAclEntry'][] = $data;
997       }
998     }
1000     if($only_ldif){
1001       $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
1002       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
1003       $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
1004       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
1005     }else{
1006    
1007       $ldap->cd($cv['base']);
1008       if(!$ldap->modify($attrs_new)){
1009         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);
1010         return(FALSE);
1011       }else{
1012         return(TRUE);
1013       }
1014     }
1015   }
1016  
1017   
1018   function create_admin_user()
1019   {
1020     $pw1 = $pw2 = "";
1021     $uid = "";
1022   
1023     if(isset($_POST['new_user_uid'])){
1024       $uid = $_POST['new_user_uid'];
1025     }
1026     if(isset($_POST['new_user_password'])){
1027       $pw1 = $_POST['new_user_password'];
1028     }
1029     if(isset($_POST['new_user_password2'])){
1030       $pw2 = $_POST['new_user_password2'];
1031     }
1032   
1033     if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
1034       msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
1035       return false;
1036     }
1037  
1038     if(!tests::is_uid($uid) || empty($uid)){
1039       msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
1040       return false;
1041     }
1042     
1043     /* On first call check for rid/sid base */
1044     $cv = $this->parent->captured_values;
1045     $ldap_l = new LDAP($cv['admin'],
1046         $cv['password'],
1047         $cv['connection'],
1048         FALSE,
1049         $cv['tls']);
1051     $ldap = new ldapMultiplexer($ldap_l);
1053     /* Get current base attributes */
1054     $ldap->cd($cv['base']);
1055   
1056     $people_ou = trim($cv['peopleou']);
1057     if(!empty($people_ou)){
1058       $people_ou = trim($people_ou).",";
1059     }
1061     if($cv['peopledn'] == "cn"){
1062       $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
1063     }else{
1064       $dn = "uid=".$uid.",".$people_ou.$cv['base'];
1065     }
1067     $hash = passwordMethod::make_hash($pw2, $cv['encryption']);
1069     $new_user=array();
1070     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
1071     $new_user['givenName']  = "System";
1072     $new_user['sn']  = "Administrator";
1073     $new_user['cn']  = "System Administrator-".$uid;
1074     $new_user['uid'] = $uid;
1075     $new_user['userPassword'] = $hash;
1076    
1077     $ldap->cd($cv['base']);
1078   
1079     $ldap->cat($dn,array("dn"));
1080     if($ldap->count()){
1081       msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
1082       return(FALSE);  
1083     }
1085     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
1086     $ldap->cd($dn);  
1087     $res = $ldap->add($new_user);
1088     $this->acl_create_selected = $dn;
1089     $this->create_admin();
1090     
1091     if(!$res){
1092       msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
1093       return(FALSE);
1094     }
1095   
1096     $this->acl_create_dialog=FALSE;        
1097     $this->check_administrativeAccount();
1098     return(TRUE);
1099   }
1100  
1102   function migrate_outside_winstations($perform = FALSE)
1103   {
1104     /* Establish ldap connection */
1105     $cv = $this->parent->captured_values;
1106     $ldap_l = new LDAP($cv['admin'],
1107         $cv['password'],
1108         $cv['connection'],
1109         FALSE,
1110         $cv['tls']);
1112     $ldap = new ldapMultiplexer($ldap_l);
1114     $ldap->cd($cv['base']);
1116     /* Check if there was a destination department posted */
1117     if(isset($_POST['move_winstation_to'])){
1118       $destination_dep = $_POST['move_winstation_to'];
1119     }else{
1120       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1121       return(false);
1122     }
1123  
1124     foreach($this->outside_winstations as $b_dn => $data){
1125       $this->outside_winstations[$b_dn]['ldif'] ="";
1126       if($data['selected']){
1127         $dn = base64_decode($b_dn);
1128         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1129         if(!$perform){
1130           $this->outside_winstations[$b_dn]['ldif'] = _("Winstation will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1133           /* Check if there are references to this object */
1134           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1135           $refs = "";
1136           while($attrs = $ldap->fetch()){
1137             $ref_dn = $attrs['dn'];
1138             $refs .= "<br />\t".$ref_dn;
1139           } 
1140           if(!empty($refs)){ 
1141             $this->outside_winstations[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1142           }
1144         }else{
1145           $this->move($dn,$d_dn);
1146         }
1147       }
1148     }
1149   }
1150   
1152   function migrate_outside_groups($perform = FALSE)
1153   {
1154     /* Establish ldap connection */
1155     $cv = $this->parent->captured_values;
1156     $ldap_l = new LDAP($cv['admin'],
1157         $cv['password'],
1158         $cv['connection'],
1159         FALSE,
1160         $cv['tls']);
1162     $ldap = new ldapMultiplexer($ldap_l);
1163     $ldap->cd($cv['base']);
1165     /* Check if there was a destination department posted */
1166     if(isset($_POST['move_group_to'])){
1167       $destination_dep = $_POST['move_group_to'];
1168     }else{
1169       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1170       return(false);
1171     }
1172  
1173     foreach($this->outside_groups as $b_dn => $data){
1174       $this->outside_groups[$b_dn]['ldif'] ="";
1175       if($data['selected']){
1176         $dn = base64_decode($b_dn);
1177         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1178         if(!$perform){
1180           $this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1182           /* Check if there are references to this object */
1183           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1184           $refs = "";
1185           while($attrs = $ldap->fetch()){
1186             $ref_dn = $attrs['dn'];
1187             $refs .= "<br />\t".$ref_dn;
1188           } 
1189           if(!empty($refs)){ 
1190             $this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1191           }
1193         }else{
1194           $this->move($dn,$d_dn);
1195         }
1196       }
1197     }
1198   }
1199   
1201   function migrate_outside_users($perform = FALSE)
1202   {
1203     /* Establish ldap connection */
1204     $cv = $this->parent->captured_values;
1205     $ldap_l = new LDAP($cv['admin'],
1206         $cv['password'],
1207         $cv['connection'],
1208         FALSE,
1209         $cv['tls']);
1211     $ldap = new ldapMultiplexer($ldap_l);
1212     $ldap->cd($cv['base']);
1214     /* Check if there was a destination department posted */
1215     if(isset($_POST['move_user_to'])){
1216       $destination_dep = $_POST['move_user_to'];
1217     }else{
1218       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1219       return(false);
1220     }
1221       
1222     foreach($this->outside_users as $b_dn => $data){
1223       $this->outside_users[$b_dn]['ldif'] ="";
1224       if($data['selected']){
1225         $dn = base64_decode($b_dn);
1226         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1227         if(!$perform){
1228           $this->outside_users[$b_dn]['ldif'] = _("User will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1230           /* Check if there are references to this object */
1231           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1232           $refs = "";
1233           while($attrs = $ldap->fetch()){
1234             $ref_dn = $attrs['dn'];
1235             $refs .= "<br />\t".$ref_dn;
1236           } 
1237           if(!empty($refs)){ 
1238             $this->outside_users[$b_dn]['ldif'] .= "<br /><br /><i>"._("The following references will be updated").":</i>".$refs;
1239           }
1241         }else{
1242           $this->move($dn,$d_dn);
1243         }
1244       }
1245     }
1246   }
1247   
1249   function execute()
1250   {
1251     /* Initialise checks if this is the first call */
1252     if(!$this->checks_initialised || isset($_POST['reload'])){
1253       $this->initialize_checks();
1254       $this->checks_initialised = TRUE;
1255     }
1257     /*************
1258      * Winstations outside the group ou 
1259      *************/
1260     
1261     if(isset($_POST['outside_winstations_dialog_cancel'])){
1262       $this->outside_winstations_dialog = FALSE;
1263       $this->dialog = FALSE;
1264       $this->show_details = FALSE;
1265     }
1266    
1267     if(isset($_POST['outside_winstations_dialog_whats_done'])){
1268       $this->migrate_outside_winstations(FALSE);
1269     }
1270  
1271     if(isset($_POST['outside_winstations_dialog_perform'])){
1272       $this->migrate_outside_winstations(TRUE);
1273       $this->search_outside_winstations();
1274       $this->dialog = FALSE;
1275       $this->show_details = FALSE;
1276       $this->outside_winstations_dialog = FALSE;
1277     }
1279     if(isset($_POST['outside_winstations_dialog'])){
1280       $this->outside_winstations_dialog = TRUE;
1281       $this->dialog = TRUE;
1282     }
1283     
1284     if($this->outside_winstations_dialog){
1286       /* Fix displayed dn syntax */ 
1287       $tmp = $this->outside_winstations;
1288       foreach($tmp as $key => $data){
1289         $tmp[$key]['dn'] = @LDAP::fix($data['dn']);
1290       }
1292       $smarty = get_smarty();
1293       $smarty->assign("ous",$this->get_all_winstation_ous());
1294       $smarty->assign("method","outside_winstations");
1295       $smarty->assign("outside_winstations",$tmp);
1296       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1297     }
1298     /*************
1299      * Groups outside the group ou 
1300      *************/
1301     
1302     if(isset($_POST['outside_groups_dialog_cancel'])){
1303       $this->outside_groups_dialog = FALSE;
1304       $this->show_details = FALSE;
1305       $this->dialog = FALSE;
1306     }
1307    
1308     if(isset($_POST['outside_groups_dialog_whats_done'])){
1309       $this->show_details= TRUE;
1310       $this->migrate_outside_groups(FALSE);
1311     }
1312  
1313     if(isset($_POST['outside_groups_dialog_refresh'])){
1314       $this->show_details= FALSE;
1315     }
1317     if(isset($_POST['outside_groups_dialog_perform'])){
1318       $this->migrate_outside_groups(TRUE);
1319       $this->dialog = FALSE;
1320       $this->show_details = FALSE;
1321       $this->outside_groups_dialog = FALSE;
1322       $this->initialize_checks();
1323     }
1325     if(isset($_POST['outside_groups_dialog'])){
1326       $this->outside_groups_dialog = TRUE;
1327       $this->dialog = TRUE;
1328     }
1329     
1330     if($this->outside_groups_dialog){
1332       /* Fix displayed dn syntax */ 
1333       $tmp = $this->outside_groups;
1334       foreach($tmp as $key => $data){
1335         $tmp[$key]['dn'] = @LDAP::fix($data['dn']);
1336       }
1338       $smarty = get_smarty();
1339       $smarty->assign("ous",$this->get_all_group_ous());
1340       $smarty->assign("method","outside_groups");
1341       $smarty->assign("outside_groups",$tmp);
1342       $smarty->assign("group_details", $this->show_details);
1343       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1344     }
1345  
1346     /*************
1347      * User outside the people ou 
1348      *************/
1349     
1350     if(isset($_POST['outside_users_dialog_cancel'])){
1351       $this->outside_users_dialog = FALSE;
1352       $this->dialog = FALSE;
1353       $this->show_details = FALSE;
1354     }
1355    
1356     if(isset($_POST['outside_users_dialog_whats_done'])){
1357       $this->show_details= TRUE;
1358       $this->migrate_outside_users(FALSE);
1359     }
1360  
1361     if(isset($_POST['outside_users_dialog_perform'])){
1362       $this->migrate_outside_users(TRUE);
1363       $this->initialize_checks();
1364       $this->dialog = FALSE;
1365       $this->show_details = FALSE;
1366       $this->outside_users_dialog = FALSE;
1367     }
1369     if (isset($_POST['outside_users_dialog_refresh'])){
1370       $this->show_details= FALSE;
1371     }
1373     if(isset($_POST['outside_users_dialog'])){
1374       $this->outside_users_dialog = TRUE;
1375       $this->dialog = TRUE;
1376     }
1377     
1378     if($this->outside_users_dialog){
1380       /* Fix displayed dn syntax */ 
1381       $tmp = $this->outside_users;
1382       foreach($tmp as $key => $data){
1383         $tmp[$key]['dn'] = @LDAP::fix($data['dn']);
1384       }
1386       $smarty = get_smarty();
1387       $smarty->assign("ous",$this->get_all_people_ous());
1388       $smarty->assign("method","outside_users");
1389       $smarty->assign("outside_users",$tmp);
1390       $smarty->assign("user_details", $this->show_details);
1391       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1392     }
1393  
1394     /*************
1395      * Root object check  
1396      *************/
1397   
1398     if(isset($_POST['retry_root_create'])){
1400       $state = $this->checks['root']['STATUS'];
1401       $this->checkBase(FALSE);
1402       if($state != $this->checks['root']['STATUS']){
1403         $this->initialize_checks();
1404       }
1405     }
1406  
1407     /*************
1408      * User Migration handling 
1409      *************/
1411     if(isset($_POST['retry_acls'])){
1412       $this->check_administrativeAccount();
1413     }
1415     if(isset($_POST['create_acls'])){
1416       $this->acl_create_dialog = TRUE;
1417       $this->dialog = TRUE;
1418     }
1419   
1420     if(isset($_POST['create_acls_cancel'])){
1421       $this->acl_create_dialog = FALSE;
1422       $this->dialog = FALSE;
1423       $this->show_details = FALSE;
1424     }
1426 #    if(isset($_POST['create_acls_create_confirmed'])){
1427 #      if($this->create_admin()){
1428 #        $this->acl_create_dialog = FALSE;
1429 #        $this->dialog = FALSE;
1430 #      $this->show_details = FALSE;
1431 #        $this->initialize_checks();
1432 #      }
1433 #    }
1435     if(isset($_POST['create_acls_create'])){
1436       $this->create_admin(TRUE);
1437     }
1439     if(isset($_POST['create_admin_user'])){
1440       if($this->create_admin_user()){
1441         $this->dialog = FALSE;
1442       $this->show_details = FALSE;
1443       }
1444     }
1446     if($this->acl_create_dialog){
1447       $smarty = get_smarty();
1448   
1449       $uid = "admin";
1450       if(isset($_POST['new_user_uid'])){
1451         $uid = $_POST['new_user_uid'];
1452       }
1454       $smarty->assign("new_user_uid",$uid);
1455       $smarty->assign("new_user_password",@$_POST['new_user_password']);
1456       $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
1457       $smarty->assign("method","create_acls");
1458       $smarty->assign("acl_create_selected",$this->acl_create_selected);
1459       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
1460       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1461     }
1463     /*************
1464      * User Migration handling 
1465      *************/
1467     /* Refresh list of deparments */
1468     if(isset($_POST['users_visible_migrate_refresh'])){
1469       $this->check_gosaAccounts();
1470     }
1472     /* Open migration dialog */
1473     if(isset($_POST['users_visible_migrate'])){
1474       $this->show_details= FALSE;
1475       $this->users_migration_dialog = TRUE;
1476       $this->dialog =TRUE;
1477     }
1479     /* Close migration dialog */
1480     if(isset($_POST['users_visible_migrate_close'])){
1481       $this->users_migration_dialog = FALSE;
1482       $this->dialog =FALSE;
1483       $this->show_details = FALSE;
1484     }
1486     /* Start migration */
1487     if(isset($_POST['users_visible_migrate_migrate'])){
1488       if($this->migrate_gosaAccounts()){
1489         $this->initialize_checks();
1490         $this->dialog = FALSE;
1491         $this->show_details = FALSE;
1492         $this->users_migration_dialog = FALSE;
1493       }
1494     }
1496     /* Start migration */
1497     if(isset($_POST['users_visible_migrate_whatsdone'])){
1498       $this->migrate_gosaAccounts(TRUE);
1499     }
1501     /* Display migration dialog */
1502     if($this->users_migration_dialog){
1504       /* Fix displayed dn syntax */ 
1505       $tmp = $this->users_to_migrate;
1506       foreach($tmp as $key => $data){
1507         $tmp[$key]['dn'] = @LDAP::fix($data['dn']);
1508       }
1510       $smarty = get_smarty();
1511       $smarty->assign("users_to_migrate",$tmp);
1512       $smarty->assign("method","migrate_users");
1513       $smarty->assign("user_details", $this->show_details);
1514       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1515     }
1518     /*************
1519      * Department Migration handling 
1520      *************/
1522     /* Refresh list of deparments */
1523     if(isset($_POST['deps_visible_migrate_refresh'])){
1524       $this->check_organizationalUnits();
1525       $this->show_details= FALSE;
1526     }
1528     /* Open migration dialog */
1529     if(isset($_POST['deps_visible_migrate'])){
1530       $this->dep_migration_dialog = TRUE;
1531       $this->dialog =TRUE;
1532     }
1534     /* Close migration dialog */
1535     if(isset($_POST['deps_visible_migrate_close'])){
1536       $this->dep_migration_dialog = FALSE;
1537       $this->dialog =FALSE;
1538       $this->show_details = FALSE;
1539     }
1541     /* Start migration */
1542     if(isset($_POST['deps_visible_migrate_migrate'])){
1543       if($this->migrate_organizationalUnits()){
1544         $this->show_details= FALSE;
1545         $this->check_organizationalUnits();
1546         $this->dialog = FALSE;
1547         $this->dep_migration_dialog = FALSE;
1548       }
1549     }
1551     /* Start migration */
1552     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1553       $this->migrate_organizationalUnits(TRUE);
1554     }
1556     /* Display migration dialog */
1557     if($this->dep_migration_dialog){
1558       $smarty = get_smarty();
1559    
1560       /* Fix displayed dn syntax */ 
1561       $tmp = $this->deps_to_migrate;
1562       foreach($tmp as $key => $data){
1563         $tmp[$key]['dn'] = @LDAP::fix($data['dn']);
1564       }
1566       $smarty->assign("deps_to_migrate",$tmp);
1567       $smarty->assign("method","migrate_deps");
1568       $smarty->assign("deps_details", $this->show_details);
1569       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1570     }
1573     /*************
1574      * Device migration 
1575      *************/
1576    
1577     if($this->device_dialog) {
1578       $this->check_device_posts();
1579     }
1580  
1581     if(isset($_POST['device_dialog_cancel'])){
1582       $this->device_dialog = FALSE;
1583       $this->show_details = FALSE;
1584       $this->dialog = FALSE;
1585     }
1586    
1587     if(isset($_POST['device_dialog_whats_done'])){
1588       $this->show_details= TRUE;
1589     }
1590  
1591     if(isset($_POST['device_dialog_refresh'])){
1592       $this->show_details= FALSE;
1593     }
1595     if(isset($_POST['migrate_devices'])){
1596       $this->migrate_usb_devices();
1597 #      $this->dialog = FALSE;
1598  #     $this->show_details = FALSE;
1599   #    $this->device_dialog = FALSE;
1600    #   $this->initialize_checks();
1601     }
1603     if(isset($_POST['device_dialog'])){
1604       $this->device_dialog = TRUE;
1605       $this->dialog = TRUE;
1606     }
1607     
1608     if($this->device_dialog){
1609       $smarty = get_smarty();
1610       $smarty->assign("method","devices");
1611       $smarty->assign("devices",$this->device);
1612       $smarty->assign("device_details", $this->show_details);
1613       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1614     }
1617     /*************
1618      * Service migration 
1619      *************/
1620    
1621     if($this->service_dialog) {
1622       $this->check_service_posts();
1623     }
1624  
1625     if(isset($_POST['service_dialog_cancel'])){
1626       $this->service_dialog = FALSE;
1627       $this->show_details = FALSE;
1628       $this->dialog = FALSE;
1629     }
1630    
1631     if(isset($_POST['service_dialog_whats_done'])){
1632       $this->show_details= TRUE;
1633     }
1634  
1635     if(isset($_POST['service_dialog_refresh'])){
1636       $this->show_details= FALSE;
1637     }
1639     if(isset($_POST['migrate_services'])){
1640       $this->migrate_services();
1641 #      $this->dialog = FALSE;
1642  #     $this->show_details = FALSE;
1643   #    $this->service_dialog = FALSE;
1644    #   $this->initialize_checks();
1645     }
1647     if(isset($_POST['service_dialog'])){
1648       $this->service_dialog = TRUE;
1649       $this->dialog = TRUE;
1650     }
1651     
1652     if($this->service_dialog){
1653       $smarty = get_smarty();
1654       $smarty->assign("method","services");
1655       $smarty->assign("services",$this->service);
1656       $smarty->assign("service_details", $this->show_details);
1657       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1658     }
1661     /*************
1662      * Menu migration 
1663      *************/
1664    
1665     if($this->menu_dialog) {
1666       $this->check_menu_posts();
1667     }
1668  
1669     if(isset($_POST['menu_dialog_cancel'])){
1670       $this->menu_dialog = FALSE;
1671       $this->show_details = FALSE;
1672       $this->dialog = FALSE;
1673     }
1674    
1675     if(isset($_POST['menu_dialog_whats_done'])){
1676       $this->show_details= TRUE;
1677     }
1678  
1679     if(isset($_POST['menu_dialog_refresh'])){
1680       $this->show_details= FALSE;
1681     }
1683     if(isset($_POST['migrate_menus'])){
1684       $this->migrate_menus();
1685 #      $this->dialog = FALSE;
1686  #     $this->show_details = FALSE;
1687   #    $this->menu_dialog = FALSE;
1688    #   $this->initialize_checks();
1689     }
1691     if(isset($_POST['menu_dialog'])){
1692       $this->menu_dialog = TRUE;
1693       $this->dialog = TRUE;
1694     }
1695     
1696     if($this->menu_dialog){
1697       $smarty = get_smarty();
1698       $smarty->assign("method","menus");
1699       $smarty->assign("menus",$this->menu);
1700       $smarty->assign("menu_details", $this->show_details);
1701       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1702     }
1704     $smarty = get_smarty();
1705     $smarty->assign("checks",$this->checks);
1706     $smarty->assign("method","default");
1707     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1708   }
1711   function save_object()
1712   {
1713     $this->is_completed= TRUE;
1715     /* Capture all selected winstations from outside_winstations_dialog */
1716     if($this->outside_winstations_dialog){
1717       foreach($this->outside_winstations as $dn => $data){
1718         if(isset($_POST['select_winstation_'.$dn])){
1719           $this->outside_winstations[$dn]['selected'] = TRUE;
1720         }else{
1721           $this->outside_winstations[$dn]['selected'] = FALSE;
1722         }
1723       }
1724     }
1726     /* Capture all selected groups from outside_groups_dialog */
1727     if($this->outside_groups_dialog){
1728       foreach($this->outside_groups as $dn => $data){
1729         if(isset($_POST['select_group_'.$dn])){
1730           $this->outside_groups[$dn]['selected'] = TRUE;
1731         }else{
1732           $this->outside_groups[$dn]['selected'] = FALSE;
1733         }
1734       }
1735     }
1737     /* Capture all selected users from outside_users_dialog */
1738     if($this->outside_users_dialog){
1739       foreach($this->outside_users as $dn => $data){
1740         if(isset($_POST['select_user_'.$dn])){
1741           $this->outside_users[$dn]['selected'] = TRUE;
1742         }else{
1743           $this->outside_users[$dn]['selected'] = FALSE;
1744         }
1745       }
1746     }
1748     /* Get "create acl" dialog posts */
1749     if($this->acl_create_dialog){
1751       if(isset($_POST['create_acls_create_abort'])){
1752         $this->acl_create_selected = "";
1753       }
1754     }
1756     /* Get selected departments */
1757     if($this->dep_migration_dialog){
1758       foreach($this->deps_to_migrate as $id => $data){
1759         if(isset($_POST['migrate_'.$id])){
1760           $this->deps_to_migrate[$id]['checked'] = TRUE;
1761         }else{
1762           $this->deps_to_migrate[$id]['checked'] = FALSE;
1763         }
1764       }
1765     }
1767     /* Get selected users */
1768     if($this->users_migration_dialog){
1769       foreach($this->users_to_migrate as $id => $data){
1770         if(isset($_POST['migrate_'.$id])){
1771           $this->users_to_migrate[$id]['checked'] = TRUE;
1772         }else{
1773           $this->users_to_migrate[$id]['checked'] = FALSE;
1774         }
1775       }
1776     }
1777   }
1780   /* Check if the root object exists.
1781    * If the parameter just_check is true, then just check if the 
1782    *  root object is missing and update the info messages.
1783    * If the Parameter is false, try to create a new root object.
1784    */
1785   function checkBase($just_check = TRUE)
1786   {
1787     /* Establish ldap connection */
1788     $cv = $this->parent->captured_values;
1789     $ldap_l = new LDAP($cv['admin'],
1790         $cv['password'],
1791         $cv['connection'],
1792         FALSE,
1793         $cv['tls']);
1795     $ldap = new ldapMultiplexer($ldap_l);
1797     /* Check if root object exists */
1798     $ldap->cd($cv['base']);
1799     $ldap->set_size_limit(1);
1800     $res = $ldap->search("(objectClass=*)");
1801     $ldap->set_size_limit(0);
1802     $err = ldap_errno($ldap->cid); 
1804     if( !$res || 
1805         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1806         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1808       /* Root object doesn't exists 
1809        */
1810       if($just_check){
1811         $this->checks['root']['STATUS']    = FALSE;
1812         $this->checks['root']['STATUS_MSG']= _("Failed");
1813         $this->checks['root']['ERROR_MSG'] =  _("The LDAP root object is missing. It is required to use your LDAP service.").'&nbsp;';
1814         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1815         return(FALSE);
1816       }else{
1818         /* Add root object */ 
1819         $ldap->cd($cv['base']);
1820         $res = $ldap->create_missing_trees($cv['base']);
1822         /* If adding failed, tell the user */
1823         if(!$res){
1824           $this->checks['root']['STATUS']    = FALSE;
1825           $this->checks['root']['STATUS_MSG']= _("Failed");
1826           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1827           $this->checks['root']['ERROR_MSG'].= "&nbsp;<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1828           return($res);;
1829         }
1830       }
1831     }
1833     /* Create & remove of dummy object was successful */
1834     $this->checks['root']['STATUS']    = TRUE;
1835     $this->checks['root']['STATUS_MSG']= _("Ok");
1836   }
1839   /* Return ldif information for a 
1840    * given attribute array 
1841    */
1842   function array_to_ldif($atts)
1843   {
1844     $ret = "";
1845     unset($atts['count']);
1846     unset($atts['dn']);
1847     foreach($atts as $name => $value){
1848       if(is_numeric($name)) {
1849         continue;
1850       }
1851       if(is_array($value)){
1852         unset($value['count']);
1853         foreach($value as $a_val){
1854           $ret .= $name.": ". $a_val."\n";
1855         }
1856       }else{
1857         $ret .= $name.": ". $value."\n";
1858       }
1859     }
1860     return(preg_replace("/\n$/","",$ret));
1861   }
1864   function get_user_list()
1865   {
1866     /* Establish ldap connection */
1867     $cv = $this->parent->captured_values;
1868     $ldap_l = new LDAP($cv['admin'],
1869         $cv['password'],
1870         $cv['connection'],
1871         FALSE,
1872         $cv['tls']);
1874     $ldap = new ldapMultiplexer($ldap_l);
1875     $ldap->cd($cv['base']);
1876     $ldap->search("(objectClass=gosaAccount)",array("dn"));
1877   
1878     $tmp = array();
1879     while($attrs = $ldap->fetch()){
1880       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
1881     }
1882     return($tmp);
1883   }
1886  function get_all_people_ous()
1887   {
1888     /* Get collected configuration settings */
1889     $cv = $this->parent->captured_values;
1890     $people_ou = trim($cv['peopleou']);
1892     /* Establish ldap connection */
1893     $cv = $this->parent->captured_values;
1894     $ldap_l = new LDAP($cv['admin'],
1895         $cv['password'],
1896         $cv['connection'],
1897         FALSE,
1898         $cv['tls']);
1900     $ldap = new ldapMultiplexer($ldap_l);
1902     /*****************
1903      * If people ou is NOT empty
1904      * search for for all objects matching the given container
1905      *****************/
1906     if(!empty($people_ou)){
1907       $ldap->search("(".$people_ou.")",array("dn"));
1909       /* Create people ou if there is currently none */
1910       if($ldap->count() == 0 ){
1911         $add_dn = $cv['peopleou'].",".$cv['base'];
1912         $naming_attr = preg_replace("/=.*$/","",$add_dn);
1913         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
1914         $add = array();
1915         $add['objectClass'] = array("organizationalUnit");
1916         $add[$naming_attr] = $naming_value;
1917         $ldap->cd($cv['base']);
1918         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
1919         $ldap->cd($add_dn);
1920         $ldap->add($add);
1921       }
1923       /* Create result */
1924       $ldap->search("(".$cv['peopleou'].")",array("dn"));
1925       $tmp = array();
1926       while($attrs= $ldap->fetch()){
1927         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
1928           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
1929         }
1930       }
1931     } else{
1933       /************
1934        * If people ou is empty
1935        * Get all valid gosaDepartments
1936        ************/
1937       $ldap->cd($cv['base']);
1938       $tmp = array();
1939       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
1940       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
1941       while($attrs = $ldap->fetch()){
1942         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
1943       }
1944     }
1945     return($tmp);
1946   }
1949   function get_all_winstation_ous()
1950   {
1951     /* Establish ldap connection */
1952     $cv = $this->parent->captured_values;
1953     $ldap_l = new LDAP($cv['admin'],
1954         $cv['password'],
1955         $cv['connection'],
1956         FALSE,
1957         $cv['tls']);
1959     $ldap = new ldapMultiplexer($ldap_l);
1961     /* Get winstation ou */
1962     if($cv['generic_settings']['wws_ou_active']) {
1963       $winstation_ou = $cv['generic_settings']['wws_ou'];
1964     }else{
1965       $winstation_ou = "ou=winstations";
1966     }
1968     $ldap->cd($cv['base']);
1969     $ldap->search("(".$winstation_ou.")",array("dn"));
1970   
1971     if($ldap->count() == 0 ){
1972       $add_dn = $winstation_ou.",ou=systems,".$cv['base'];
1973       $naming_attr = preg_replace("/=.*$/","",$add_dn);
1974       $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
1975       $add = array();
1976       $add['objectClass'] = array("organizationalUnit");
1977       $add[$naming_attr] = $naming_value;
1979       $ldap->cd($cv['base']);
1980       $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
1981       $ldap->cd($add_dn);
1982       $ldap->add($add);
1983     }
1985     $ldap->search("(".$winstation_ou.")",array("dn"));
1986     $tmp = array();
1987     while($attrs= $ldap->fetch()){
1988       if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
1989         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
1990       }
1991     }
1992     return($tmp); 
1993   }
1996  function get_all_group_ous()
1997   {
1998     /* Establish ldap connection */
1999     $cv = $this->parent->captured_values;
2000     $ldap_l = new LDAP($cv['admin'],
2001         $cv['password'],
2002         $cv['connection'],
2003         FALSE,
2004         $cv['tls']);
2006     $ldap = new ldapMultiplexer($ldap_l);
2008     $group_ou = trim($cv['groupou']);
2009     if(!empty($group_ou)){
2010       $group_ou = trim($group_ou);
2011     }
2013     /************
2014      * If group ou is NOT empty
2015      * Get all valid group ous, create one if necessary
2016      ************/
2017     $ldap->cd($cv['base']);
2018     if(!empty($group_ou)){
2019       $ldap->search("(".$group_ou.")",array("dn"));
2020       if($ldap->count() == 0 ){
2021         $add_dn = $group_ou.$cv['base'];
2022         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2023         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2024         $add = array();
2025         $add['objectClass'] = array("organizationalUnit");
2026         $add[$naming_attr] = $naming_value;
2028         $ldap->cd($cv['base']);
2029         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2030         $ldap->cd($add_dn);
2031         $ldap->add($add);
2032       }
2033       $ldap->search("(".$group_ou.")",array("dn"));
2034       $tmp = array();
2035       while($attrs= $ldap->fetch()){
2036         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2037           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2038         }
2039       }
2040     }else{
2041       /************
2042        * If group ou is empty
2043        * Get all valid gosaDepartments
2044        ************/
2045       $ldap->cd($cv['base']);
2046       $tmp = array();
2047       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2048       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2049       while($attrs = $ldap->fetch()){
2050         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2051       }
2052     }
2053     return($tmp);
2054   }
2057   function get_group_list()
2058   {
2059     /* Establish ldap connection */
2060     $cv = $this->parent->captured_values;
2061     $ldap_l = new LDAP($cv['admin'],
2062         $cv['password'],
2063         $cv['connection'],
2064         FALSE,
2065         $cv['tls']);
2067     $ldap = new ldapMultiplexer($ldap_l);
2068     
2069     $ldap->cd($cv['base']);
2070     $ldap->search("(objectClass=posixGroup)",array("dn"));
2071   
2072     $tmp = array();
2073     while($attrs = $ldap->fetch()){
2074       $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
2075     }
2076     return($tmp);
2077   }
2080   function move($source,$destination)
2081   {
2082     /* Establish ldap connection */
2083     $cv = $this->parent->captured_values;
2084     $ldap_l = new LDAP($cv['admin'],
2085         $cv['password'],
2086         $cv['connection'],
2087         FALSE,
2088         $cv['tls']);
2090     $ldap = new ldapMultiplexer($ldap_l);
2092      /* Update object references in gosaGroupOfNames */
2093     $ogs_to_fix = array();
2094     $ldap->cd($cv['base']);
2095     $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($source).'))', array('cn','member'));
2096     while ($attrs= $ldap->fetch()){
2097       $dn = $attrs['dn'];
2098       $attrs = $this->cleanup_array($attrs);
2099       $member_new = array($destination);
2100       foreach($attrs['member'] as $member){
2101         if($member != $source){
2102           $member_new[] = $member;
2103         }
2104       }
2105       $attrs['member'] = $member_new;
2106       $ogs_to_fix[$dn] = $attrs;
2107     }
2109     /* Copy source to destination dn */
2110     $ldap->cat($source);
2111     $new_data = $this->cleanup_array($ldap->fetch());
2112     $ldap->cd($destination);
2113     $res = $ldap->add($new_data);
2115     /* Display warning if copy failed */
2116     if(!$res){
2117       msg_dialog::display(_("LDAP error"), sprintf(_("Copy '%s' to '%s' failed:")."<br><br><i>%s</i>", LDAP::fix($source), LDAP::fix($destination), $ldap->get_error()), ERROR_DIALOG);
2118     }else{
2119       $res = $ldap->rmDir($source);
2120       if (!$ldap->success()){
2121         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_DEL, get_class()));
2122       }
2124       /* Object is copied, so update its references */
2125       foreach($ogs_to_fix as $dn => $data){
2126         $ldap->cd($dn);
2127         $ldap->modify($data);
2128       }
2129     }
2130   }
2133   /* Cleanup ldap result to be able to write it be to ldap */
2134   function cleanup_array($attrs)
2135   {
2136     foreach($attrs as $key => $value) {
2137       if(is_numeric($key) || in_array($key,array("count","dn"))){
2138         unset($attrs[$key]);
2139       }
2140       if(is_array($value) && isset($value['count'])){
2141         unset($attrs[$key]['count']);
2142       }
2143     }
2144     return($attrs);
2145   }
2148   /*! \brief  Act in posts from the device migration dialog 
2149    */
2150   function check_device_posts()
2151   {
2152     foreach($this->device as $key => $device){
2153       if(isset($_POST["migrate_".$key])){
2154         $this->device[$key]['DETAILS'] =TRUE;
2155       }else{
2156         $this->device[$key]['DETAILS'] =FALSE;
2157       }
2158     }
2159   }
2162   /*! \brief  Check for old style (gosa-2.5) devices.
2163               Save readable informations and a list of migratable devices 
2164                in $this->devices.
2165    */
2166   function check_usb_devices ()
2167   {
2168     /* Establish ldap connection */
2169     $cv = $this->parent->captured_values;
2170     $ldap_l = new LDAP($cv['admin'],
2171         $cv['password'],
2172         $cv['connection'],
2173         FALSE,
2174         $cv['tls']);
2176     $ldap = new ldapMultiplexer($ldap_l);
2177     $ldap->cd($cv['base']);
2178     $res = $ldap->search("(&(|(objectClass=posixAccount)(objectClass=posixGroup))(gotoHotplugDevice=*))",
2179         array("cn","gotoHotplugDevice","gosaUnitTag"));
2181     if(!$res){
2182       $this->checks['old_style_devices']['STATUS']    = FALSE;
2183       $this->checks['old_style_devices']['STATUS_MSG']= _("LDAP query failed");
2184       $this->checks['old_style_devices']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2185       return;
2186     }
2189     /* If adding failed, tell the user */
2190     if($ldap->count()){
2191   
2192       $this->device = array();
2193       while($attrs = $ldap->fetch()){
2195         for ($j= 0; $j < $attrs['gotoHotplugDevice']['count']; $j++){
2197           $after  = "";
2198           $current= "";
2200           $entry= $attrs['gotoHotplugDevice'][$j];
2202           @list($name,$desc,$serial,$vendor,$product) = explode('|', $entry);
2203   
2204           $add = 1;
2205           $new_name  = $name;
2206           while(isset($dest[$new_name])){
2207             $new_name = $name."_".$add;
2208             $add ++;
2209           }
2210           $name = $new_name;
2211           $newdn= "cn=$name,ou=devices,".preg_replace('/^[^,]+,/', '', $attrs['dn']);
2213           if (!isset($dest[$name])){
2214             $dest[$name]= $newdn;
2216             $current.= "dn: ".$attrs['dn']."\n"; 
2217     
2218             for ($c= 0; $c < $attrs['gotoHotplugDevice']['count']; $c++){
2219               if($c == $j){
2220                 $current.= "<b>gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."</b>\n"; 
2221               }else{
2222                 $current.= "gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."\n"; 
2223               }
2224             }
2226             $after.= "dn: $newdn\n";
2227             $after.= "changetype: add\n";
2228             $after.= "objectClass: top\n";
2229             $after.= "objectClass: gotoDevice\n";
2230             if (isset($attrs['gosaunittag'][0])){
2231               $after.= "objectClass: gosaAdminiafter\n";
2232               $after.= "gosaUnitTag: ".$attrs['gosaunittag'][0]."\n";
2233             }
2234             $after.= "cn: $name\n";
2235             $after.= "gotoHotplugDevice: $desc|$serial|$vendor|$product\n\n";
2237             $this->device[] = array(
2238                 'CURRENT'     =>  $current,
2239                 'AFTER'       => $after,
2240                 'OLD_DEVICE'  => $entry,
2241                 'DN'          => $attrs['dn'],
2242                 'NEW_DN'      => $newdn,
2243                 'DEVICE_NAME' => $name,
2244                 'DETAILS'     => FALSE);
2245           }
2246         }
2247       }
2249       $this->checks['old_style_devices']['STATUS']    = FALSE;
2250       $this->checks['old_style_devices']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2251       $this->checks['old_style_devices']['ERROR_MSG'] = 
2252         sprintf(_("There are %s devices that need to be migrated."),count($this->device)).
2253           "<input type='submit' name='device_dialog' value='"._("Migrate")."'>";
2254     }else{
2255       $this->checks['old_style_devices']['STATUS']    = TRUE;
2256       $this->checks['old_style_devices']['STATUS_MSG']= _("Ok");
2257       $this->checks['old_style_devices']['ERROR_MSG'] = "";
2258     }
2259   }
2262   /*! \brief  Migrate all selected devices. 
2263               Execute all required ldap actions to migrate the 
2264                selected devices.
2265    */
2266   function migrate_usb_devices ()
2267   {
2268     /* Establish ldap connection */
2269     $cv = $this->parent->captured_values;
2270     $ldap_l = new LDAP($cv['admin'],
2271         $cv['password'],
2272         $cv['connection'],
2273         FALSE,
2274         $cv['tls']);
2276     $ldap = new ldapMultiplexer($ldap_l);
2278     /* Walk through migrateable devices and initiate migration for all 
2279         devices that are checked (DETAILS==TRUE) 
2280      */
2281     foreach($this->device as $key => $device){
2282       if($device['DETAILS']){
2284         /* Get source object and verify that the specified device is a 
2285             member attribute of it. 
2286          */
2287         $ldap->cd($cv['base']);
2288         $ldap->cat($device['DN']);
2289         $attrs = $ldap->fetch();
2290         if(in_array($device['OLD_DEVICE'],$attrs['gotoHotplugDevice'])){
2292           /* Create new hotplug device object 'gotoDevice'
2293            */ 
2294           @list($name,$desc,$serial,$vendor,$product) = explode('|', $device['OLD_DEVICE']);    
2295           $newdn = $device['NEW_DN'];
2296           $new_attr = array();
2297           $new_attr['cn'] = $device['DEVICE_NAME'];
2298           $new_attr['objectClass'] = array('top','gotoDevice');
2299           $new_attr['gotoHotplugDevice'] = "$desc|$serial|$vendor|$product";
2301           /* Add new object 
2302            */
2303           $ldap->cd($cv['base']);
2304           $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$newdn));
2305           $ldap->cd($newdn);
2306           $ldap->add($new_attr);
2308           /* Throw an error message if the action failed. 
2309            */
2310           if(!$ldap->success()){
2311             msg_dialog::display(_("LDAP error"), 
2312                 sprintf(_("Ldap add failed for %s with error %s"),
2313                   "<b>".LDAP::fix($newdn)."</b>", 
2314                   "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
2315           }else{
2317             /* Remove old style device definition from source object. 
2318              */
2319             $update['gotoHotplugDevice'] = array();
2320             for($i = 0 ; $i < $attrs['gotoHotplugDevice']['count'] ; $i++){
2321               if($attrs['gotoHotplugDevice'][$i] == $device['OLD_DEVICE']){
2322                  continue;
2323               }
2324               $update['gotoHotplugDevice'][] = $attrs['gotoHotplugDevice'][$i];
2325             }
2327             $ldap->cd($device['DN']);
2328             $ldap->modify($update);
2329             $ldap->cat($device['DN'],array("gotoHotplugDevice"));
2330             if(!$ldap->success()){
2331               msg_dialog::display(_("LDAP error"), 
2332                   sprintf(_("Ldap update failed for %s with error %s"),
2333                     "<b>".LDAP::fix($device['DN'])."</b>", 
2334                     "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2335             }else{
2336               unset($this->device[$key]);
2337             }
2338           }
2339         }
2340       }
2341     }
2342     $this->check_usb_devices();
2343   }
2346   /*! \brief  Check for old style (gosa-2.5) services that have to be migrated
2347                to be useable in gosa-2.6.
2348               All required changes are stored in $this->service, also some
2349                readable informations describing the actions required 
2350                to migrate the service
2351    */
2352   function check_services()
2353   {
2354     /* Establish ldap connection */
2355     $cv = $this->parent->captured_values;
2356     $ldap_l = new LDAP($cv['admin'],
2357         $cv['password'],
2358         $cv['connection'],
2359         FALSE,
2360         $cv['tls']);
2362     $ldap = new ldapMultiplexer($ldap_l);
2363     $this->service = array();
2365     /* Check for Ldap services that must be migrated 
2366      */ 
2367     $ldap->cd($cv['base']);
2368     $res = $ldap->search("(objectClass=goLdapServer)", array("goLdapBase", "cn"));
2370     /* Check if we were able to query the ldap server 
2371      */
2372     if(!$res){
2373       $this->checks['old_style_services']['STATUS']    = FALSE;
2374       $this->checks['old_style_services']['STATUS_MSG']= _("LDAP query failed");
2375       $this->checks['old_style_services']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2376       return;
2377     }
2379     /* Walk through each configured ldap server 
2380         and check if it is configured correctly.
2381      */
2382     while($attrs = $ldap->fetch()){
2383       $dn= $attrs['dn'];
2384       $uri= $attrs['goLdapBase'][0];
2385       if (! preg_match("!^ldaps?://!", $uri)){
2386         $this->service[] = array(
2387             "TYPE"    => "modify" , 
2388             "DN"      => $dn, 
2389             "DETAILS" => FALSE, 
2390             "ATTRS"   => array("goLdapBase" => "ldap://".$attrs['cn'][0]."/$uri"),
2391             "CURRENT" => "goLdapBase: ".$uri,
2392             "AFTER"   => "goLdapBase: "."ldap://".$attrs['cn'][0]."/$uri");
2393       }
2394     }
2396     /* Other sevices following here later ...maybe
2397      */
2399     /*  Update status message
2400      */
2401     if(count($this->service)){
2402       $this->checks['old_style_services']['STATUS']    = FALSE;
2403       $this->checks['old_style_services']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2404       $this->checks['old_style_services']['ERROR_MSG'] =
2405         sprintf(_("There are %s services that need to be migrated."),
2406             count($this->service)).
2407         "<input type='submit' name='service_dialog' value='"._("Migrate")."'>";
2408     }else{
2409       $this->checks['old_style_services']['STATUS']    = TRUE;
2410       $this->checks['old_style_services']['STATUS_MSG']= _("Ok");
2411       $this->checks['old_style_services']['ERROR_MSG'] = "";
2412     }
2413   }
2416   
2417   /*! \brief  Migrate selected services.
2418               This function executes the commands collected by the 
2419                service_check() function.
2420    */
2421   function migrate_services()
2422   {
2423     /* Establish ldap connection 
2424      */
2425     $cv = $this->parent->captured_values;
2426     $ldap_l = new LDAP($cv['admin'],
2427         $cv['password'],
2428         $cv['connection'],
2429         FALSE,
2430         $cv['tls']);
2432     $ldap = new ldapMultiplexer($ldap_l);
2434     /* Handle each service 
2435      */
2436     foreach($this->service as $key => $service){
2437       if($service['DETAILS']){
2439         /* Handle modify requests 
2440          */
2441         if($service['TYPE'] == "modify"){
2442           $ldap->cd($service['DN']);
2443           $ldap->modify($service['ATTRS']);
2445           /* Check if everything done was successful 
2446            */
2447           if(!$ldap->success()){
2448             msg_dialog::display(_("LDAP error"), 
2449                 sprintf(_("Ldap update failed for %s with error %s"),
2450                   "<b>".LDAP::fix($service['DN'])."</b>", 
2451                   "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2452           }else{
2453         
2454             /* Remove action from list 
2455              */
2456             unset($this->service[$key]);
2457           }
2458         }
2459       }
2460     }
2462     /* Update the service migration status 
2463      */
2464     $this->check_services();
2465   }
2468   /*! \brief  Ensure that posts made on the service migration dialog 
2469                are processed.
2470    */
2471   function check_service_posts()
2472   {
2473     foreach($this->service as $key => $service){
2474       if(isset($_POST["migrate_".$key])){
2475         $this->service[$key]['DETAILS'] =TRUE;
2476       }else{
2477         $this->service[$key]['DETAILS'] =FALSE;
2478       }
2479     }
2480   }
2483   /*! \brief  This function checks the given ldap for old style (gosa-2.5) 
2484                menu entries and will prepare a list of actions that are required
2485                to migrate them to gosa-2.6.
2486               All required actions and some readable informations are stored in 
2487                $this->menu.
2488    */
2489   function check_menus()
2490   {
2491     /* Establish ldap connection
2492      */
2493     $cv = $this->parent->captured_values;
2494     $ldap_l = new LDAP($cv['admin'],
2495         $cv['password'],
2496         $cv['connection'],
2497         FALSE,
2498         $cv['tls']);
2500     $ldap = new ldapMultiplexer($ldap_l);
2502     /* First detect all release names 
2503      */
2504     $ldap->cd($cv['base']);
2505     $res = $ldap->search("(&(objectClass=organizational)(objectClass=FAIbranch))",array("ou","objectClass"));
2507     /* Check if we were able to query the ldap server
2508      */
2509     if(!$res){
2510       $this->checks['old_style_menus']['STATUS']    = FALSE;
2511       $this->checks['old_style_menus']['STATUS_MSG']= _("LDAP query failed");
2512       $this->checks['old_style_menus']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2513       return;
2514     }
2516     /* Create application -> parameter mapping, used later to detect 
2517         which configured parameter belongs to which application entry.
2518      */
2519     $amap= array();
2520     $todo = array();
2521     $ldap->cd($cv['base']);
2522     $ldap->search("(objectClass=gosaApplication)", array("cn", "gosaApplicationParameter"));
2523     while($info = $ldap->fetch()){
2524       if (isset($info['gosaApplicationParameter']['count'])){
2525         for ($j= 0; $j < $info['gosaApplicationParameter']['count']; $j++){
2526           $p= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$j]);
2528           if(!isset($amap[$info['cn'][0]]) || !in_array($p, $amap[$info['cn'][0]])){
2529             $amap[$info['cn'][0]][]= $p;
2530           }
2531         }
2532       } else {
2533         $amap[$info['cn'][0]]= array();
2534       }
2535     }
2537     /* Search for all groups that have an old style application menu configured.
2538      */  
2539     $appgroups = array();
2540     $ldap->cd($cv['base']);
2541     $ldap->search("(&(objectClass=gosaApplicationGroup)(objectClass=posixGroup)(FAIrelease=*))",
2542         array("gosaMemberApplication","gosaApplicationParameter","FAIrelease","objectClass","gosaUnitTag"));
2544     /* Create readable prefix for "What will be done" infos 
2545      */
2546     $s_add = "<i>"._("add")."</i>\t";
2547     $s_del = "<i>"._("remove")."</i>\t";
2549     /* Walk through all found old-style menu configurations.
2550         -Prepare ldap update list     $data   
2551         -Prepare printable changes    $after/$current
2552      */
2553     while($info = $ldap->fetch()){
2555       $data = array();
2556       $current = "";
2557       $after ="";
2559       /* Get unit tag 
2560        */
2561       $tag ="";
2562       if(isset($info['gosaUnitTag'])){
2563         $tag = $info['gosaUnitTag'][0];
2564       }
2566       /* Collect application parameter for this group
2567        */
2568       $params= array();
2569       if(isset($info['gosaApplicationParameter'])){
2570         for ($i= 0; $i < $info['gosaApplicationParameter']['count']; $i++){
2571           $name= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$i]);
2572           $params[$name]= $info['gosaApplicationParameter'][$i];
2573         }
2574       }
2576       /* Create release container for each release/subrelease.
2577          eg.   "sisa/1.0.0":
2578          .       "ou=siga, ..."
2579          .       "ou=1.0.0,ou=siga, .."
2580        */ 
2581       $release = "";
2582       $r = $info['FAIrelease'][0];
2583       $z = split("/",$r);
2584       foreach($z as $part){
2586         if(!empty($part)){
2587           $release = "ou=".$part.",".$release;
2589           /* Append release department information to "What will be done" info
2590            */
2591           $release_dn = $release.$info['dn'];
2592           $after   .=  $s_add."dn: $release_dn\n";
2593           $after   .=  $s_add."objectClass: top\n";
2594           $after   .=  $s_add."objectClass: FAIbranch\n";
2595           $after   .=  $s_add."objectClass: organizationalUnit\n";
2596          
2597           /* Append UnitTag 
2598            */ 
2599           if($tag != ""){ 
2600             $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2601             $after   .=  $s_add."gosaUnitTag: $tag\n";
2602           }
2603           $after   .=  $s_add."ou: $part\n";
2605           /* Append release data to ldap actions 
2606            */
2607           $d = array();
2608           $d['objectClass'] = array("top","FAIbranch","organizationalUnit");
2609           if(!empty($tag)){
2610             $d['objectClass'][] = "gosaAdministrativeUnitTag";
2611             $d['gosaUnitTag']   = $tag;
2612           }
2613           $d['ou']          = $part;
2614           $data['ADD'][$release_dn]= $d;
2615         }
2616       }
2618       /* Add member applications to the array.
2619        */ 
2620       $current .= "dn: ".$info['dn']."\n";
2621       $menu_structure = array();
2622       for ($i= 0; $i < $info['gosaMemberApplication']['count']; $i++){
2623         list($name, $location, $priority)= explode("|", $info['gosaMemberApplication'][$i]);
2625         /* Create location dn 
2626          */
2627         $location_dn ="";
2628         if(!empty($location)){
2629           $location_dn ="cn=".$location.",";
2630         }
2632         /* Append old style element to current detail informations 
2633          */      
2634         $current .= $s_del."gosaMemberApplication: ".$info['gosaMemberApplication'][$i]."\n";
2636         /* Append ldap update action to remove the old menu entry attributes 
2637          */
2638         unset($info['objectClass']['count']);
2639         $d = array();
2640         $d['gosaMemberApplication']      = array();
2641         $d['gosaApplicationParameter']  = array();
2642         if(isset($info['FAIrelease'])){
2643           $d['FAIrelease'] = array();
2644         }
2645         $d['objectClass']               = array_remove_entries(array("gosaApplicationGroup","FAIreleaseTag"),$info['objectClass']);
2646         $data['MODIFY'][$info['dn']]    = $d;
2648         /* Create new application menu structure 
2649          */
2650         if (isset($amap[$name])){
2652           /* Append missing menu structure to "What is done info"
2653            */
2654           if(!isset($menu_structure[$location]) && !empty($location)){
2655             $menu_structure[$location] = TRUE;
2656             $after .= "\n";
2657             $after .= $s_add."dn: $location_dn$release_dn\n";
2658             $after .= $s_add."objectClass: gotoSubmenuEntry\n";
2660             /* Append UnitTag
2661              */
2662             if($tag != ""){
2663               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2664               $after   .=  $s_add."gosaUnitTag: $tag\n";
2665             }
2666             $after .= $s_add."cn: $location\n";
2667   
2668             /* Create ldap entry to append 
2669              */
2670             $d = array();
2671             $d['cn'] = $location;
2672             $d['objectClass'] = array("gotoSubmenuEntry");
2673             if(!empty($tag)){
2674               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2675               $d['gosaUnitTag']   = $tag;
2676             }
2677             $data['ADD'][$location_dn.$release_dn] = $d;
2678           }
2681           /* Append missing menu entry for "What is done info".
2682            */
2683           if(!empty($name)){
2684             $after .= "\n";
2685             $after .= $s_add."dn: cn=$name,$location_dn$release_dn\n";
2686             $after .= $s_add."objectClass: gotoMenuEntry\n";
2687             if($tag != ""){
2688               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2689               $after   .=  $s_add."gosaUnitTag: $tag\n";
2690             }
2691             $after .= $s_add."cn: $name\n";
2692             $after .= $s_add."gosaApplicationPriority: $priority\n";
2694             /* Create ldap entry 
2695              */
2696             $d= array();
2697             $d['objectClass'] = array("gotoMenuEntry");
2698             if(!empty($tag)){
2699               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2700               $d['gosaUnitTag']   = $tag;
2701             }
2702             $d['cn']          = $name;
2703             $d['gosaApplicationPriority'] = $priority;
2705             foreach ($amap[$name] as $n){
2706               if (isset($params[$n])){
2707                 $after .= $s_add."gosaApplicationParameter: ".$params[$n]."\n";
2708                 $d['gosaApplicationParameter'][] = $params[$n];
2709               }
2710             }
2711             $data['ADD']["cn=$name,$location_dn$release_dn"] = $d;
2712           }         
2713         }
2714       }
2716       /* Updated todo list 
2717        */ 
2718       $todo[] = array(
2719           "DETAILS" => FALSE,
2720           "DN"      => $info['dn'],
2721           "AFTER"   => $after,
2722           "CURRENT" => $current,
2723           "TODO"    => $data
2724           );
2725     }
2727     /* Remember checks.
2728      */
2729     $this->menu = $todo;
2731     /* Check if we were able to query the ldap server
2732      */
2733     if(count($this->menu)){
2734       $this->checks['old_style_menus']['STATUS']    = FALSE;
2735       $this->checks['old_style_menus']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2736       $this->checks['old_style_menus']['ERROR_MSG'] = sprintf(_("There are %s application menus which have to be converted."),
2737                                                       count($this->menu))."<input type='submit' name='menu_dialog' value='"._("Migrate")."'>";
2738     }else{
2739       $this->checks['old_style_menus']['STATUS']    = TRUE;
2740       $this->checks['old_style_menus']['STATUS_MSG']= _("Ok");
2741       $this->checks['old_style_menus']['ERROR_MSG'] = "";
2742     }
2743   }
2745   
2746   /*! \brief  Handle posts for the menu_dialog 
2747               Ensure that checked checkboxes stay checked.
2748    */
2749   function check_menu_posts()
2750   {
2751     foreach($this->menu as $key => $menu){
2752       if(isset($_POST["migrate_".$key])){
2753         $this->menu[$key]['DETAILS'] =TRUE;
2754       }else{
2755         $this->menu[$key]['DETAILS'] =FALSE;
2756       }
2757     }
2758   }
2761   /*! \brief  This function updates old-style application menus to
2762                valid 2.6 application menus.
2763               All selected menus will be converted (DETAILS = TRUE). 
2764               The ldap actions collected by check_menus() will be executed. 
2765    */
2766   function migrate_menus()
2767   {
2769     /* Establish ldap connection
2770      */
2771     $cv = $this->parent->captured_values;
2772     $ldap_l = new LDAP($cv['admin'],
2773         $cv['password'],
2774         $cv['connection'],
2775         FALSE,
2776         $cv['tls']);
2778     $ldap = new ldapMultiplexer($ldap_l);
2779     $ldap->cd($cv['base']);
2781     /* Walk through menus and detect selected menu 
2782      */
2783     foreach($this->menu as $key => $menu){
2784       if($menu['DETAILS']) {
2786         /* Excute all LDAP-ADD actions 
2787          */
2788         $success = TRUE;
2789         foreach($menu['TODO']['ADD'] as $dn => $data){
2790           $ldap->cd($cv['base']);
2791           if(!$ldap->dn_exists($dn)){
2792             $ldap->cd($dn);
2793             $ldap->add($data);
2794             if (!$ldap->success()){
2795               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
2796               $success = FALSE;
2797             }
2798           }
2799         }
2801         /* Execute all LDAP-MODIFY actions 
2802          */
2803         foreach($menu['TODO']['MODIFY'] as $dn => $data){
2804           $ldap->cd($cv['base']);
2805           if($ldap->dn_exists($dn)){
2806             $ldap->cd($dn);
2807             $ldap->modify($data);
2808             if (!$ldap->success()){
2809               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
2810               $success = FALSE;
2811             }
2812           }
2813         }
2814   
2815         /* If every action was successful, remove this entry from the list 
2816          */
2817         if($success){
2818           unset($this->menu[$key]);
2819         }
2820       }
2821     }
2823     /* Udpate migration status for application menus
2824      */
2825     $this->check_menus();
2826   }
2829 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
2830 ?>