Code

Removed sizelimit for departments
[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/setup/migrate.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   /* Migrateable users */
112   var $migrate_users = array();
113   var $acl_migrate_dialog      = FALSE;
114   var $migrate_acl_base_entry  = "";
116   /* Root object classes */
117   var $rootOC_migrate_dialog = FALSE;
118   var $rootOC_details = array();
119         
120   function Step_Migrate()
121   {
122     $this->update_strings(); 
123   }
125   function update_strings()
126   {
127     $this->s_title      = _("LDAP inspection");
128     $this->s_title_long = _("LDAP inspection");
129     $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
130   }
132   function initialize_checks()
133   {
134     $this->checks = array();
135     $this->checks['root']['TITLE']     = _("Checking for root object");
136     $this->checks['root']['STATUS']    = FALSE;
137     $this->checks['root']['STATUS_MSG']= "";
138     $this->checks['root']['ERROR_MSG'] = "";
139     $this->checkBase();
141     $this->checks['rootOC']['TITLE']     = _("Inspecting object classes in root object");
142     $this->checks['rootOC']['STATUS']    = FALSE;
143     $this->checks['rootOC']['STATUS_MSG']= "";
144     $this->checks['rootOC']['ERROR_MSG'] = "";
145     $this->checkBaseOC();
147     $this->checks['permissions']['TITLE']     = _("Checking permission for LDAP database");
148     $this->checks['permissions']['STATUS']    = FALSE;
149     $this->checks['permissions']['STATUS_MSG']= "";
150     $this->checks['permissions']['ERROR_MSG'] = "";
151     $this->check_ldap_permissions();
153     $this->checks['deps_visible']['TITLE']     = _("Checking for invisible departments");
154     $this->checks['deps_visible']['STATUS']    = FALSE;
155     $this->checks['deps_visible']['STATUS_MSG']= "";
156     $this->checks['deps_visible']['ERROR_MSG'] = "";
158     $this->checks['users_visible']['TITLE']     = _("Checking for invisible users");
159     $this->checks['users_visible']['STATUS']    = FALSE;
160     $this->checks['users_visible']['STATUS_MSG']= "";
161     $this->checks['users_visible']['ERROR_MSG'] = "";
162     $this->check_gosaAccounts();
164     $this->migrate_users = array();
165     $this->checks['acls']['TITLE']     = _("Checking for super administrator");
166     $this->checks['acls']['STATUS']    = FALSE;
167     $this->checks['acls']['STATUS_MSG']= "";
168     $this->checks['acls']['ERROR_MSG'] = "";
169     $this->check_administrativeAccount();
171     $this->checks['outside_users']['TITLE']     = _("Checking for users outside the people tree");
172     $this->checks['outside_users']['STATUS']    = FALSE;
173     $this->checks['outside_users']['STATUS_MSG']= "";
174     $this->checks['outside_users']['ERROR_MSG'] = "";
175     $this->search_outside_users();
177     $this->checks['outside_groups']['TITLE']     = _("Checking for groups outside the groups tree");
178     $this->checks['outside_groups']['STATUS']    = FALSE;
179     $this->checks['outside_groups']['STATUS_MSG']= "";
180     $this->checks['outside_groups']['ERROR_MSG'] = "";
181     $this->search_outside_groups();
182     $this->check_organizationalUnits();
184     $this->checks['outside_winstations']['TITLE']     = _("Checking for windows workstations outside the winstation tree");
185     $this->checks['outside_winstations']['STATUS']    = FALSE;
186     $this->checks['outside_winstations']['STATUS_MSG']= "";
187     $this->checks['outside_winstations']['ERROR_MSG'] = "";
188     $this->search_outside_winstations();
190     $this->checks['uidNumber_usage']['TITLE']     = _("Checking for duplicated UID numbers");
191     $this->checks['uidNumber_usage']['STATUS']    = FALSE;
192     $this->checks['uidNumber_usage']['STATUS_MSG']= "";
193     $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
194     $this->check_uidNumber();
196     $this->checks['gidNumber_usage']['TITLE']     = _("Checking for duplicate GID numbers");
197     $this->checks['gidNumber_usage']['STATUS']    = FALSE;
198     $this->checks['gidNumber_usage']['STATUS_MSG']= "";
199     $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
200     $this->check_gidNumber();
202     $this->checks['old_style_devices']['TITLE']     = _("Checking for old style USB devices");
203     $this->checks['old_style_devices']['STATUS']    = FALSE;
204     $this->checks['old_style_devices']['STATUS_MSG']= "";
205     $this->checks['old_style_devices']['ERROR_MSG'] = "";
206     $this->check_usb_devices();
208     $this->checks['old_style_services']['TITLE']     = _("Checking for old services that have to be migrated");
209     $this->checks['old_style_services']['STATUS']    = FALSE;
210     $this->checks['old_style_services']['STATUS_MSG']= "";
211     $this->checks['old_style_services']['ERROR_MSG'] = "";
212     $this->check_services();
214     $this->checks['old_style_menus']['TITLE']     = _("Checking for old style application menus");
215     $this->checks['old_style_menus']['STATUS']    = FALSE;
216     $this->checks['old_style_menus']['STATUS_MSG']= "";
217     $this->checks['old_style_menus']['ERROR_MSG'] = "";
218     $this->check_menus();
219   }
222   /* Check if there are uidNumbers which are used more than once. 
223    */
224   function check_uidNumber()
225   {
226     /* Establish ldap connection */
227     $cv = $this->parent->captured_values;
228     $ldap_l = new LDAP($cv['admin'],
229         $cv['password'],
230         $cv['connection'],
231         FALSE,
232         $cv['tls']);
234     $ldap = new ldapMultiplexer($ldap_l);
236     $ldap->cd($cv['base']);
237     $res = $ldap->search("(&(objectClass=posixAccount)(uidNumber=*))",array("dn","uidNumber"));
238     if(!$res){
239       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
240       $this->checks['uidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
241       $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
242       return(false);
243     }
245     $this->check_uidNumbers= array(); 
246     $tmp = array();
247     while($attrs = $ldap->fetch()){
248       $tmp[$attrs['uidNumber'][0]][] = $attrs;
249     }
251     foreach($tmp as $id => $entries){
252       if(count($entries) > 1){
253         foreach($entries as $entry){
254           $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
255         }
256       }
257     }
259     if($this->check_uidNumbers){
260       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
261       $this->checks['uidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
262       $this->checks['uidNumber_usage']['ERROR_MSG'] =
263         sprintf(_("Found %s duplicate values for attribute 'uidNumber'."),count($this->check_uidNumbers));
264       return(false);
265     }else{
266       $this->checks['uidNumber_usage']['STATUS']    = TRUE;
267       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
268       $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
269       return(TRUE);
270     }
271   }
273   
274   /* Check if there are duplicated gidNumbers present in ldap
275    */
276   function check_gidNumber()
277   {
278     /* Establish ldap connection */
279     $cv = $this->parent->captured_values;
280     $ldap_l = new LDAP($cv['admin'],
281         $cv['password'],
282         $cv['connection'],
283         FALSE,
284         $cv['tls']);
286     $ldap = new ldapMultiplexer($ldap_l);
288     $ldap->cd($cv['base']);
289     $res = $ldap->search("(&(objectClass=posixGroup)(gidNumber=*))",array("dn","gidNumber"));
290     if(!$res){
291       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
292       $this->checks['gidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
293       $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
294       return(false);
295     }
297     $this->check_gidNumbers= array(); 
298     $tmp = array();
299     while($attrs = $ldap->fetch()){
300       $tmp[$attrs['gidNumber'][0]][] = $attrs;
301     }
303     foreach($tmp as $id => $entries){
304       if(count($entries) > 1){
305         foreach($entries as $entry){
306           $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
307         }
308       }
309     }
311     if($this->check_gidNumbers){
312       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
313       $this->checks['gidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
314       $this->checks['gidNumber_usage']['ERROR_MSG'] =
315         sprintf(_("Found %s duplicate values for attribute 'gidNumber'."),count($this->check_gidNumbers));
316       return(false);
317     }else{
318       $this->checks['gidNumber_usage']['STATUS']    = TRUE;
319       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
320       $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
321       return(TRUE);
322     }
323   }
326   /* Search for winstations outside the winstation ou 
327    */
328   function search_outside_winstations()
329   {
330     /* Establish ldap connection */
331     $cv = $this->parent->captured_values;
332     $ldap_l = new LDAP($cv['admin'],
333         $cv['password'],
334         $cv['connection'],
335         FALSE,
336         $cv['tls']);
338     $ldap = new ldapMultiplexer($ldap_l);
340     /* Get winstation ou */
341     if($cv['generic_settings']['wws_ou_active']) {
342       $winstation_ou = $cv['generic_settings']['wws_ou'];
343     }else{
344       $winstation_ou = "ou=winstations";
345     }
347     if($cv['samba_version'] == 3){
348       $oc = "sambaSamAccount";
349     }else{
350       $oc = "sambaAccount";
351     }
352  
353     $ldap->cd($cv['base']);
354     $res = $ldap->search("(&(objectClass=".$oc.")(uid=*$))",array("dn","sambaSID"));
355     if(!$res){
356       $this->checks['outside_winstations']['STATUS']    = FALSE;
357       $this->checks['outside_winstations']['STATUS_MSG']= _("LDAP query failed");
358       $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
359       return(false);
360     }
362     $this->outside_winstations = array();
363     while($attrs = $ldap->fetch()){
364       if((!preg_match("/^[^,]+,".preg_quote($winstation_ou, '/')."/",$attrs['dn'])) && !preg_match("/,dc=addressbook,/",$attrs['dn'])){
365         $attrs['selected'] = FALSE;
366         $attrs['ldif']     = "";
367         $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
368       }
369     }
371     if(count($this->outside_winstations)){
372       $this->checks['outside_winstations']['STATUS']    = FALSE;
373       $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
374       $this->checks['outside_winstations']['ERROR_MSG'] = 
375         sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
376       $this->checks['outside_winstations']['ERROR_MSG'].= "<input type='submit' name='outside_winstations_dialog' value='"._("Migrate")."...'>";
377       return(false);
378     }else{
379       $this->checks['outside_winstations']['STATUS']    = TRUE;
380       $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
381       $this->checks['outside_winstations']['ERROR_MSG'] = "";
382       return(TRUE);
383     }
384   }
387   /* Search for groups outside the group ou 
388    */
389   function search_outside_groups()
390   {
391     /* Establish ldap connection */
392     $cv = $this->parent->captured_values;
393     $ldap_l = new LDAP($cv['admin'],
394         $cv['password'],
395         $cv['connection'],
396         FALSE,
397         $cv['tls']);
399     $ldap = new ldapMultiplexer($ldap_l);
401     $group_ou = $cv['groupou'];
402     $ldap->cd($cv['base']);
404     /***********
405      * Get all gosaDepartments to be able to
406      *  validate correct ldap tree position of every single user
407      ***********/
408     $valid_deps = array();
409     $valid_deps['/'] = $cv['base'];
410     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
411     while($attrs = $ldap->fetch()){
412       $valid_deps[] = $attrs['dn'];
413     }
415     /***********
416      * Get all groups
417      ***********/
418     $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
419     if(!$res){
420       $this->checks['outside_groups']['STATUS']    = FALSE;
421       $this->checks['outside_groups']['STATUS_MSG']= _("LDAP query failed");
422       $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
423       return(false);
424     }
426     $this->outside_groups = array();
427     $this->groups_list = array();;
428     while($attrs = $ldap->fetch()){
429       $group_db_base = preg_replace("/^[^,]+,".preg_quote($group_ou, '/')."+,/i","",$attrs['dn']);
431       /* Check if entry is not an addressbook only user
432        *  and verify that he is in a valid department
433        */
434       if( !preg_match("/".preg_quote("dc=addressbook,", '/')."/",$group_db_base) &&
435           !in_array($group_db_base,$valid_deps)
436         ){
437         $attrs['selected'] = FALSE;
438         $attrs['ldif']     = "";
439         $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
440       }
441       $this->group_list[] = $attrs['dn'];
442     }
444     if(count($this->outside_groups)){
445       $this->checks['outside_groups']['STATUS']    = FALSE;
446       $this->checks['outside_groups']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
447       $this->checks['outside_groups']['ERROR_MSG'] =
448         sprintf(_("Found %s groups outside the configured tree '%s'."),count($this->outside_groups),$group_ou);
449       $this->checks['outside_groups']['ERROR_MSG'].= "&nbsp;<input type='submit' name='outside_groups_dialog' value='"._("Move")."...'>";
450       return(false);
451     }else{
452       $this->checks['outside_groups']['STATUS']    = TRUE;
453       $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
454       $this->checks['outside_groups']['ERROR_MSG'] = "";
455       return(TRUE);
456     }
457   }
459  /* Search for users outside the people ou
460    */
461   function search_outside_users()
462   {
463     /* Establish ldap connection */
464     $cv = $this->parent->captured_values;
465     $ldap_l = new LDAP($cv['admin'],
466         $cv['password'],
467         $cv['connection'],
468         FALSE,
469         $cv['tls']);
471     $ldap = new ldapMultiplexer($ldap_l);
472     $ldap->cd($cv['base']);
475     /***********
476      * Get all gosaDepartments to be able to
477      *  validate correct ldap tree position of every single user
478      ***********/
479     $valid_deps = array();
480     $valid_deps['/'] = $cv['base'];
481     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
482     while($attrs = $ldap->fetch()){
483       $valid_deps[] = $attrs['dn'];
484     }
486     /***********
487      * Search for all users
488      ***********/
489     $res = $ldap->search("(&(objectClass=gosaAccount)(!(uid=*$)))",array("dn"));
490     if(!$res){
491       $this->checks['outside_users']['STATUS']    = FALSE;
492       $this->checks['outside_users']['STATUS_MSG']= _("LDAP query failed");
493       $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
494       return(false);
495     }
497     /***********
498      * Check if returned users are within a valid GOsa deparmtment. (peopleou,gosaDepartment,base)
499      ***********/
500     $this->outside_users = array();
501     $people_ou = trim($cv['peopleou']);
502     if(!empty($people_ou)){
503       $people_ou = $people_ou.",";
504     }
506     while($attrs = $ldap->fetch()){
507       $people_db_base = preg_replace("/^[^,]+,".preg_quote($people_ou, '/')."/i","",$attrs['dn']);
509       /* Check if entry is not an addressbook only user
510        *  and verify that he is in a valid department
511        */
512       if( !preg_match("/dc=addressbook,/",$people_db_base) &&
513           !in_array($people_db_base,$valid_deps)
514          ){
515         $attrs['selected'] = FALSE;
516         $attrs['ldif']     = "";
517         $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
518       }
519     }
521     if(count($this->outside_users)){
522       $this->checks['outside_users']['STATUS']    = FALSE;
523       $this->checks['outside_users']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
524       $this->checks['outside_users']['ERROR_MSG'] =
525         sprintf(_("Found %s user(s) outside the configured tree '%s'."),count($this->outside_users),$people_ou);
526       $this->checks['outside_users']['ERROR_MSG'].= "<input type='submit' name='outside_users_dialog' value='"._("Move")."...'>";
527       return(false);
528     }else{
529       $this->checks['outside_users']['STATUS']    = TRUE;
530       $this->checks['outside_users']['STATUS_MSG']= _("Ok");
531       $this->checks['outside_users']['ERROR_MSG'] = "";
532       return(TRUE);
533     }
534   }
537   /* Check ldap accessibility 
538    * Create and remove a dummy object, 
539    *  to ensure that we have the necessary permissions
540    */
541   function check_ldap_permissions()
542   {
543     /* Establish ldap connection */
544     $cv = $this->parent->captured_values;
545     $ldap_l = new LDAP($cv['admin'],
546         $cv['password'],
547         $cv['connection'],
548         FALSE,
549         $cv['tls']);
551     $ldap = new ldapMultiplexer($ldap_l);
553     /* Create dummy entry 
554      */
555     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
556     $dn       = "ou=".$name.",".$cv['base'];
557     $testEntry= array();
558     $testEntry['objectClass'][]= "top";
559     $testEntry['objectClass'][]= "organizationalUnit";
560     $testEntry['objectClass'][]= "gosaDepartment";
561     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
562     $testEntry['ou']  = $name;
564     /* check if simple ldap cat will be successful 
565      */
566     $res = $ldap->cat($cv['base']);  
567     if(!$res){
568       $this->checks['permissions']['STATUS']    = FALSE;
569       $this->checks['permissions']['STATUS_MSG']= _("LDAP query failed");
570       $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
571       return(false);
572     }
573   
574     /* Try to create dummy object 
575      */ 
576     $ldap->cd ($dn);
577     $ldap->create_missing_trees($dn);
578     $res = $ldap->add($testEntry);
579     $ldap->cat($dn);
580     if(!$ldap->count()){
581       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
583       $this->checks['permissions']['STATUS']    = FALSE;
584       $this->checks['permissions']['STATUS_MSG']= _("Failed");
585       $this->checks['permissions']['ERROR_MSG'] = 
586         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
587       return(false);
588     }
590     /* Try to remove created entry 
591      */
592     $res = $ldap->rmDir($dn);
593     $ldap->cat($dn);
594     if($ldap->count()){
595       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
596       $this->checks['permissions']['STATUS']    = FALSE;
597       $this->checks['permissions']['STATUS_MSG']= _("Failed");
598       $this->checks['permissions']['ERROR_MSG'] = 
599         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
600       return(false);
601     }
603     /* Create & remove of dummy object was successful */
604     $this->checks['permissions']['STATUS']    = TRUE;
605     $this->checks['permissions']['STATUS_MSG']= _("Ok");
606     $this->checks['permissions']['ERROR_MSG'] = "";
607     return(true);
608   } 
611   /* Check if there are users which will 
612    *  be invisible for GOsa 
613    */
614   function check_gosaAccounts()
615   {
616     /* Remember old list of ivisible users, to be able to set 
617      *  the 'html checked' status for the checkboxes again 
618      */
619     $cnt_ok = 0;
620     $old    = $this->users_to_migrate;
621     $this->users_to_migrate = array();
623     /* Establish ldap connection */
624     $cv = $this->parent->captured_values;
625     $ldap_l = new LDAP($cv['admin'],
626         $cv['password'],
627         $cv['connection'],
628         FALSE,
629         $cv['tls']);
631     $ldap = new ldapMultiplexer($ldap_l);
633     /* Get all invisible users 
634      */
635     $ldap->cd($cv['base']); 
636     $res =$ldap->search("(&(|(objectClass=posixAccount)(&(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))(!(objectClass=gosaAccount))(uid=*))",array("sn","givenName","cn","uid"));
637     while($attrs = $ldap->fetch()){
638       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
639         $attrs['checked'] = FALSE;
640         $attrs['before']  = "";
641         $attrs['after']   = "";
643         /* Set objects to selected, that were selected before reload */
644         if(isset($old[base64_encode($attrs['dn'])])){
645           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
646         }
647         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
648       }
649     }
651     /* No invisible */
652     if(!$res){
653       $this->checks['users_visible']['STATUS']    = FALSE;
654       $this->checks['users_visible']['STATUS_MSG']= _("LDAP query failed");
655       $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
656     }elseif(count($this->users_to_migrate) == 0){
657       $this->checks['users_visible']['STATUS']    = TRUE;
658       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
659       $this->checks['users_visible']['ERROR_MSG'] = "";
660     }else{
661       $this->checks['users_visible']['STATUS']    = FALSE;
662       $this->checks['users_visible']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
663       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s user(s) that will not be visible in GOsa."), 
664           count($this->users_to_migrate));
665       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."...'>";
666     }
667   }
670   /* Start user account migration 
671    */  
672   function migrate_gosaAccounts($only_ldif = FALSE)
673   {
674     $this->show_details= $only_ldif;
676     /* Establish ldap connection */
677     $cv = $this->parent->captured_values;
678     $ldap_l = new LDAP($cv['admin'],
679         $cv['password'],
680         $cv['connection'],
681         FALSE,
682         $cv['tls']);
684     $ldap = new ldapMultiplexer($ldap_l);
686     /* Add gosaAccount objectClass to the selected users  
687      */
688     foreach($this->users_to_migrate as $key => $dep){
689       if($dep['checked']){
691         /* Get old objectClasses */
692         $ldap->cat($dep['dn'],array("objectClass"));
693         $attrs      = $ldap->fetch();
695         /* Create new objectClass array */
696         $new_attrs  = array();
697         $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson","person");
698         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
699           if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
700             $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
701           }
702         }
704         /* Set info attributes for current object, 
705          *  or write changes to the ldap database 
706          */
707         if($only_ldif){
708           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
709           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
710         }else{
711           $ldap->cd($attrs['dn']);
712           if(!$ldap->modify($new_attrs)){
713             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']),$ldap->get_error()), ERROR_DIALOG);
714             return(false);
715           }
716         }
717       }
718     }
719     return(TRUE);
720   }
723   /* Check if there are invisible organizational Units 
724    */
725   function check_organizationalUnits()
726   {
727     $cnt_ok = 0;
728     $old = $this->deps_to_migrate;
729     $this->deps_to_migrate = array();
731     /* Establish ldap connection */
732     $cv = $this->parent->captured_values;
733     $ldap_l = new LDAP($cv['admin'],
734         $cv['password'],
735         $cv['connection'],
736         FALSE,
737         $cv['tls']);
739     $ldap = new ldapMultiplexer($ldap_l);
741     /* Skip GOsa internal departments */
742     $skip_dns = array("/".$cv['peopleou']."/","/".$cv['groupou']."/","/^ou=people,/","/^ou=groups,/","/^ou=sudoers,/",
743         "/(,|)ou=configs,/","/(,|)ou=systems,/",
744         "/(,|)ou=apps,/","/(,|)ou=mime,/","/(,|)ou=devices/","/^ou=aclroles,/","/^ou=incoming,/",
745         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
746         "/(,|)ou=winstations,/");
748     /* Get all invisible departments */
749     $ldap->cd($cv['base']); 
750     $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
751     while($attrs = $ldap->fetch()){
752       $attrs['checked'] = FALSE;
753       $attrs['before']  = "";
754       $attrs['after']   = "";
756       /* Set objects to selected, that were selected before reload */
757       if(isset($old[base64_encode($attrs['dn'])])){
758         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
759       }
760       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
761     }
763     /* Filter returned list of departments and ensure that 
764      *  GOsa internal departments will not be listed 
765      */
766     foreach($this->deps_to_migrate as $key => $attrs){
767       $dn = $attrs['dn'];
768       $skip = false;;
770       /* Check if this object is an application release object
771           e.g. groups-> application menus.
772        */
773       if(preg_match("/^.*,[ ]*cn=/",$dn)){
774         $cn_dn = preg_replace("/^.*,[ ]*cn=/","cn=",$dn);
775         if(in_array($cn_dn,$this->group_list)){
776           $skip = true;
777         }
778       }
779     
780       foreach($skip_dns as $skip_dn){
781         if(preg_match($skip_dn,$dn)){
782           $skip = true;
783         }
784       }
785       if($skip){
786         unset($this->deps_to_migrate[$key]);
787       }
788     }
790     /* If we have no invisible departments found  
791      *  tell the user that everything is ok 
792      */
793     if(!$res){
794       $this->checks['deps_visible']['STATUS']    = FALSE;
795       $this->checks['deps_visible']['STATUS_MSG']= _("LDAP query failed");
796       $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
797     }elseif(count($this->deps_to_migrate) == 0 ){
798       $this->checks['deps_visible']['STATUS']    = TRUE;
799       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
800       $this->checks['deps_visible']['ERROR_MSG'] = "";
801     }else{
802       $this->checks['deps_visible']['STATUS']    = TRUE;
803       $this->checks['deps_visible']['STATUS_MSG']= '<font style="color:#FFA500">'._("Warning").'</font>';
804       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s department(s) that will not be visible in GOsa."),count($this->deps_to_migrate));
805       $this->checks['deps_visible']['ERROR_MSG'] .= "&nbsp;<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."...'>";
806     }
807   }
811   /* Start deparmtment migration */  
812   function migrate_organizationalUnits($only_ldif = FALSE)
813   {
814     $this->show_details= $only_ldif;
816     /* Establish ldap connection */
817     $cv = $this->parent->captured_values;
818     $ldap_l = new LDAP($cv['admin'],
819         $cv['password'],
820         $cv['connection'],
821         FALSE,
822         $cv['tls']);
824     $ldap = new ldapMultiplexer($ldap_l);
826     /* Add gosaDepartment objectClass to each selected entry 
827      */
828     foreach($this->deps_to_migrate as $key => $dep){
829       if($dep['checked']){
831         /* Get current objectClasses */
832         $ldap->cat($dep['dn'],array("objectClass","description"));
833         $attrs      = $ldap->fetch();
835         /* Create new objectClass attribute including gosaDepartment*/
836         $new_attrs  = array();
837         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
838           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
839         }
840         $new_attrs['objectClass'][] = "gosaDepartment";
842         /* Append description it is missing */
843         if(!isset($attrs['description'])){
844           $new_attrs['description'][] = "GOsa department";
845         }
847         /* Depending on the parameter >only_diff< we save the changes as ldif
848          *  or we write our changes directly to the ldap database
849          */
850         if($only_ldif){
851           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
852           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
853         }else{
854           $ldap->cd($attrs['dn']);
855           if(!$ldap->modify($new_attrs)){
856             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']), $ldap->get_error()), ERROR_DIALOG);
857             return(false);
858           }
859         }
860       }
861     }
862     return(TRUE);
863   }
866   /* Check Acls if there is at least one object with acls defined 
867    */
868   function check_administrativeAccount()
869   {
870     /* Reset settings 
871      */ 
872     $GOsa_26_found = FALSE;
873     $this->migrate_users = array();
874     $this->acl_migrate_dialog = FALSE;
875     $this->migrate_acl_base_entry  = "";
877     /* Establish ldap connection */
878     $cv = $this->parent->captured_values;
879     $ldap_l = new LDAP($cv['admin'],
880         $cv['password'],
881         $cv['connection'],
882         FALSE,
883         $cv['tls']);
885     $ldap = new ldapMultiplexer($ldap_l);
886     $ldap->cd($cv['base']);
887     $res = $ldap->cat($cv['base']);
888    
889     if(!$res){
890       $this->checks['acls']['STATUS']    = FALSE;
891       $this->checks['acls']['STATUS_MSG']= _("LDAP query failed");
892       $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
893     }else{
894       $GOsa_26_found = false; // GOsa 2.6 Account found
895       $GOsa_25_found = false; // GOsa 2.5 Account found, allow migration
897       $username = "";
898       $attrs = $ldap->fetch();
900       /* Collect a list of available GOsa users and groups 
901        */
902       $users = array();
903       $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
904         "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
905       while($user_attrs = $ldap->fetch()){
906         $users[$user_attrs['dn']] = $user_attrs['uid'][0];
907         $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
908       }
909       $groups = array();
910       $ldap->search("objectClass=posixGroup",array("cn","dn"));
911       while($group_attrs = $ldap->fetch()){
912         $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
913       }
914       
915       /* Check if a valid GOsa 2.6 admin exists 
916           -> gosaAclEntry for an existing and accessible user.
917        */
918       $valid_users = "";
919       $valid_groups = "";
920       if(isset($attrs['gosaAclEntry'])){
921         $acls = $attrs['gosaAclEntry'];
922         for($i = 0 ; $i < $acls['count'] ; $i++){
923           $acl = $acls[$i];
924           $tmp = split(":",$acl);
926           if($tmp[1] == "psub"){
927             $members = split(",",$tmp[2]);
928             foreach($members as $member){
929               $member = base64_decode($member);
930               if(isset($users[$member])){
931                 if(preg_match("/all;cmdrw/i",$tmp[3])){
932                   $valid_users .= $users[$member].", ";
933                   $GOsa_26_found  = TRUE;
934                 }
935               }
936               if(isset($groups[$member])){
937                 if(preg_match("/all;cmdrw/i",$tmp[3])){
938                   $ldap->cat($member);
939                   $group_attrs = $ldap->fetch();
940                   $val_users = "";
941                   if(isset($group_attrs['memberUid'])){
942                     for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
943                       if(isset($rusers[$group_attrs['memberUid'][$e]])){
944                         $val_users .= $group_attrs['memberUid'][$e].", ";
945                       }
946                     }
947                   }
948                   if(!empty($val_users)){
949                     $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
950                     $GOsa_26_found  = TRUE;
951                   }
952                 }
953               }
954             }
955           }elseif($tmp[1] == "role"){
957             /* Check if acl owner is a valid GOsa user account */
958             $ldap->cat(base64_decode($tmp[2]),array("gosaAclTemplate"));
959             $ret = $ldap->fetch();
961             if(isset($ret['gosaAclTemplate'])){
962               $cnt = $ret['gosaAclTemplate']['count'];
963               for($e = 0 ; $e < $cnt ; $e++){
965                 $a_str = $ret['gosaAclTemplate'][$e];
966                 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all;cmdrw$/",$a_str)){
968                   $members = split(",",$tmp[3]);
969                   foreach($members as $member){
970                     $member = base64_decode($member);
972                     if(isset($users[$member])){
973                       $valid_users .= $users[$member].", ";
974                       $GOsa_26_found  = TRUE;
975                     }
976                     if(isset($groups[$member])){
977                       $ldap->cat($member);
978                       $group_attrs = $ldap->fetch();
979                       $val_users = "";
980                       if(isset($group_attrs['memberUid'])){
981                         for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
982                           if(isset($rusers[$group_attrs['memberUid'][$e]])){
983                             $val_users .= $group_attrs['memberUid'][$e].", ";
984                           }
985                         }
986                       }
987                       if(!empty($val_users)){
988                         $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
989                         $GOsa_26_found  = TRUE;
990                       }
991                     }
992                   }
993                 }
994               }
995             }
996           }
997         }
998       }
1000       /* Try to find an old GOsa 2.5 administrative account that may be migrated 
1001        */
1002       if(!$GOsa_26_found){
1003         $valid_users = "";
1004         $valid_groups = "";
1005         $ldap->cd($cv['base']);
1006         $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
1007         while($p_group = $ldap->fetch()){
1008           $val_users = "";
1009           for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
1010             $user = $p_group['memberUid'][$e];
1011             if(isset($rusers[$user])){
1012               $val_users .= $user.", ";
1013             }  
1014           }
1015           if(!empty($val_users)){
1016             $valid_groups .= $groups[$p_group['dn']]."(<i>".trim($val_users,", ")."</i>), ";
1017             $GOsa_25_found  = TRUE;
1018           }
1019         }
1020       }
1023       /* Print out results 
1024        */
1025       if($GOsa_25_found){
1026         $str = "";
1027         if(!empty($valid_groups)){
1028           $str.= "<i>".sprintf(_("GOsa 2.5 administrative accounts found: %s"),trim($valid_groups,", "))."</i><br>";
1029         }
1030         $this->checks['acls']['STATUS']    = FALSE;
1031         $this->checks['acls']['STATUS_MSG']= _("Failed");
1032         $this->checks['acls']['ERROR_MSG'] = $str;
1033         $this->checks['acls']['ERROR_MSG'].= _("There is no valid GOsa 2.6 administrator account inside your LDAP.")."&nbsp;";
1034         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='migrate_acls' value='"._("Migrate")."'>";
1035         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
1036       }elseif($GOsa_26_found){
1037         $str = "";
1038         if(!empty($valid_users)){
1039           $str.= "<b>"._("Users")."</b>:&nbsp;".trim($valid_users,", ")."<br>";
1040         }
1041         if(!empty($valid_groups)){
1042           $str.= "<b>"._("Groups")."</b>:&nbsp;".trim($valid_groups,", ")."<br>";
1043         }
1044         $this->checks['acls']['STATUS']    = TRUE;
1045         $this->checks['acls']['STATUS_MSG']= _("Ok");
1046         $this->checks['acls']['ERROR_MSG'] = $str;
1047       }else{
1048         $this->checks['acls']['STATUS']    = FALSE;
1049         $this->checks['acls']['STATUS_MSG']= _("Failed");
1050         $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")."&nbsp;";
1051         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
1052       }
1053     }
1054     return($GOsa_26_found);
1055   }
1059   function create_admin($only_ldif = FALSE)
1060   {
1061     /* Reset '' */
1062     $this->acl_create_changes="";
1064     /* Object that should receive admin acls */
1065     $dn = $this->acl_create_selected;
1067     /* Get collected configuration settings */
1068     $cv = $this->parent->captured_values;
1070     /* On first call check for rid/sid base */
1071     $ldap_l = new LDAP($cv['admin'],
1072         $cv['password'],
1073         $cv['connection'],
1074         FALSE,
1075         $cv['tls']);
1077     $ldap = new ldapMultiplexer($ldap_l);
1079     /* Get current base attributes */
1080     $ldap->cd($cv['base']);
1081     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
1082     $attrs = $ldap->fetch();
1084     /* Add acls for the selcted user to the base */
1085     $attrs_new = array();
1086     $attrs_new['objectClass'] = array("gosaACL");
1088     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
1089       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
1090         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
1091       }
1092     }
1094     $acl = "0:psub:".base64_encode($dn).":all;cmdrw";    
1095     $attrs_new['gosaAclEntry'][] = $acl;
1096     if(isset($attrs['gosaAclEntry'])){
1097       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
1098           
1099         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
1100         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
1101  
1102         $data = ($prio+1).$rest;
1103         $attrs_new['gosaAclEntry'][] = $data;
1104       }
1105     }
1107     if($only_ldif){
1108       $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
1109       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
1110       $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
1111       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
1112     }else{
1113    
1114       $ldap->cd($cv['base']);
1115       if(!$ldap->modify($attrs_new)){
1116         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);
1117         return(FALSE);
1118       }else{
1119         return(TRUE);
1120       }
1121     }
1122   }
1123  
1124   
1125   function create_admin_user()
1126   {
1127     $pw1 = $pw2 = "";
1128     $uid = "";
1130     /* On first call check for rid/sid base */
1131     $cv = $this->parent->captured_values;
1132     $ldap_l = new LDAP($cv['admin'],
1133         $cv['password'],
1134         $cv['connection'],
1135         FALSE,
1136         $cv['tls']);
1138     $ldap = new ldapMultiplexer($ldap_l);
1139   
1140     if(isset($_POST['new_user_uid'])){
1141       $uid = $_POST['new_user_uid'];
1142     }
1143     if(isset($_POST['new_user_password'])){
1144       $pw1 = $_POST['new_user_password'];
1145     }
1146     if(isset($_POST['new_user_password2'])){
1147       $pw2 = $_POST['new_user_password2'];
1148     }
1149   
1150     
1151     $ldap->cd($cv['base']);
1152     $ldap->search("(uid=".$uid.")");
1153     if($ldap->count()){
1154       msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
1155       return false;
1156     }
1157     
1158     if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
1159       msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
1160       return false;
1161     }
1162  
1163     if(!tests::is_uid($uid) || empty($uid)){
1164       msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
1165       return false;
1166     }
1167  
1168  
1169     /* Get current base attributes */
1170     $ldap->cd($cv['base']);
1171   
1172     $people_ou = trim($cv['peopleou']);
1173     if(!empty($people_ou)){
1174       $people_ou = trim($people_ou).",";
1175     }
1177     if($cv['peopledn'] == "cn"){
1178       $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
1179     }else{
1180       $dn = "uid=".$uid.",".$people_ou.$cv['base'];
1181     }
1183     $hash = passwordMethod::make_hash($pw2, $cv['encryption']);
1185     $new_user=array();
1186     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
1187     $new_user['givenName']  = "System";
1188     $new_user['sn']  = "Administrator";
1189     $new_user['cn']  = "System Administrator-".$uid;
1190     $new_user['uid'] = $uid;
1191     $new_user['userPassword'] = $hash;
1192    
1193     $ldap->cd($cv['base']);
1194   
1195     $ldap->cat($dn,array("dn"));
1196     if($ldap->count()){
1197       msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
1198       return(FALSE);  
1199     }
1201     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
1202     $ldap->cd($dn);  
1203     $res = $ldap->add($new_user);
1204     $this->acl_create_selected = $dn;
1205     $this->create_admin();
1206     
1207     if(!$res){
1208       msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
1209       return(FALSE);
1210     }
1211   
1212     $this->acl_create_dialog=FALSE;        
1213     $this->check_administrativeAccount();
1214     return(TRUE);
1215   }
1216  
1218   function migrate_outside_winstations($perform = FALSE)
1219   {
1220     /* Establish ldap connection */
1221     $cv = $this->parent->captured_values;
1222     $ldap_l = new LDAP($cv['admin'],
1223         $cv['password'],
1224         $cv['connection'],
1225         FALSE,
1226         $cv['tls']);
1228     $ldap = new ldapMultiplexer($ldap_l);
1230     $ldap->cd($cv['base']);
1232     /* Check if there was a destination department posted */
1233     if(isset($_POST['move_winstation_to'])){
1234       $destination_dep = $_POST['move_winstation_to'];
1235     }else{
1236       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1237       return(false);
1238     }
1239  
1240     foreach($this->outside_winstations as $b_dn => $data){
1241       $this->outside_winstations[$b_dn]['ldif'] ="";
1242       if($data['selected']){
1243         $dn = base64_decode($b_dn);
1244         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1245         if(!$perform){
1246           $this->outside_winstations[$b_dn]['ldif'] = _("Winstation will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1249           /* Check if there are references to this object */
1250           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1251           $refs = "";
1252           while($attrs = $ldap->fetch()){
1253             $ref_dn = $attrs['dn'];
1254             $refs .= "<br />\t".$ref_dn;
1255           } 
1256           if(!empty($refs)){ 
1257             $this->outside_winstations[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1258           }
1260         }else{
1261           $this->move($dn,$d_dn);
1262         }
1263       }
1264     }
1265   }
1266   
1268   function migrate_outside_groups($perform = FALSE)
1269   {
1270     /* Establish ldap connection */
1271     $cv = $this->parent->captured_values;
1272     $ldap_l = new LDAP($cv['admin'],
1273         $cv['password'],
1274         $cv['connection'],
1275         FALSE,
1276         $cv['tls']);
1278     $ldap = new ldapMultiplexer($ldap_l);
1279     $ldap->cd($cv['base']);
1281     /* Check if there was a destination department posted */
1282     if(isset($_POST['move_group_to'])){
1283       $destination_dep = $_POST['move_group_to'];
1284     }else{
1285       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1286       return(false);
1287     }
1288  
1289     foreach($this->outside_groups as $b_dn => $data){
1290       $this->outside_groups[$b_dn]['ldif'] ="";
1291       if($data['selected']){
1292         $dn = base64_decode($b_dn);
1293         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1294         if(!$perform){
1296           $this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1298           /* Check if there are references to this object */
1299           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1300           $refs = "";
1301           while($attrs = $ldap->fetch()){
1302             $ref_dn = $attrs['dn'];
1303             $refs .= "<br />\t".$ref_dn;
1304           } 
1305           if(!empty($refs)){ 
1306             $this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1307           }
1309         }else{
1310           $this->move($dn,$d_dn);
1311         }
1312       }
1313     }
1314   }
1315   
1317   function migrate_outside_users($perform = FALSE)
1318   {
1319     /* Establish ldap connection */
1320     $cv = $this->parent->captured_values;
1321     $ldap_l = new LDAP($cv['admin'],
1322         $cv['password'],
1323         $cv['connection'],
1324         FALSE,
1325         $cv['tls']);
1327     $ldap = new ldapMultiplexer($ldap_l);
1328     $ldap->cd($cv['base']);
1330     /* Check if there was a destination department posted */
1331     if(isset($_POST['move_user_to'])){
1332       $destination_dep = $_POST['move_user_to'];
1333     }else{
1334       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1335       return(false);
1336     }
1337       
1338     foreach($this->outside_users as $b_dn => $data){
1339       $this->outside_users[$b_dn]['ldif'] ="";
1340       if($data['selected']){
1341         $dn = base64_decode($b_dn);
1342         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1343         if(!$perform){
1344           $this->outside_users[$b_dn]['ldif'] = _("User will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1346           /* Check if there are references to this object */
1347           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1348           $refs = "";
1349           while($attrs = $ldap->fetch()){
1350             $ref_dn = $attrs['dn'];
1351             $refs .= "<br />\t".$ref_dn;
1352           } 
1353           if(!empty($refs)){ 
1354             $this->outside_users[$b_dn]['ldif'] .= "<br /><br /><i>"._("The following references will be updated").":</i>".$refs;
1355           }
1357         }else{
1358           $this->move($dn,$d_dn);
1359         }
1360       }
1361     }
1362   }
1363   
1365   function execute()
1366   {
1367     /* Initialise checks if this is the first call */
1368     if(!$this->checks_initialised || isset($_POST['reload'])){
1369       $this->initialize_checks();
1370       $this->checks_initialised = TRUE;
1371     }
1373     /*************
1374      * Winstations outside the group ou 
1375      *************/
1376     
1377     if(isset($_POST['outside_winstations_dialog_cancel'])){
1378       $this->outside_winstations_dialog = FALSE;
1379       $this->dialog = FALSE;
1380       $this->show_details = FALSE;
1381     }
1382    
1383     if(isset($_POST['outside_winstations_dialog_whats_done'])){
1384       $this->migrate_outside_winstations(FALSE);
1385     }
1386  
1387     if(isset($_POST['outside_winstations_dialog_perform'])){
1388       $this->migrate_outside_winstations(TRUE);
1389       $this->search_outside_winstations();
1390       $this->dialog = FALSE;
1391       $this->show_details = FALSE;
1392       $this->outside_winstations_dialog = FALSE;
1393     }
1395     if(isset($_POST['outside_winstations_dialog'])){
1396       $this->outside_winstations_dialog = TRUE;
1397       $this->dialog = TRUE;
1398     }
1399     
1400     if($this->outside_winstations_dialog){
1402       /* Fix displayed dn syntax */ 
1403       $tmp = $this->outside_winstations;
1404       foreach($tmp as $key => $data){
1405         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1406       }
1408       $smarty = get_smarty();
1409       $smarty->assign("ous",$this->get_all_winstation_ous());
1410       $smarty->assign("method","outside_winstations");
1411       $smarty->assign("outside_winstations",$tmp);
1412       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1413     }
1414     /*************
1415      * Groups outside the group ou 
1416      *************/
1417     
1418     if(isset($_POST['outside_groups_dialog_cancel'])){
1419       $this->outside_groups_dialog = FALSE;
1420       $this->show_details = FALSE;
1421       $this->dialog = FALSE;
1422     }
1423    
1424     if(isset($_POST['outside_groups_dialog_whats_done'])){
1425       $this->show_details= TRUE;
1426       $this->migrate_outside_groups(FALSE);
1427     }
1428  
1429     if(isset($_POST['outside_groups_dialog_refresh'])){
1430       $this->show_details= FALSE;
1431     }
1433     if(isset($_POST['outside_groups_dialog_perform'])){
1434       $this->migrate_outside_groups(TRUE);
1435       $this->dialog = FALSE;
1436       $this->show_details = FALSE;
1437       $this->outside_groups_dialog = FALSE;
1438       $this->initialize_checks();
1439     }
1441     if(isset($_POST['outside_groups_dialog'])){
1442       $this->outside_groups_dialog = TRUE;
1443       $this->dialog = TRUE;
1444     }
1445     
1446     if($this->outside_groups_dialog){
1448       /* Fix displayed dn syntax */ 
1449       $tmp = $this->outside_groups;
1450       foreach($tmp as $key => $data){
1451         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1452       }
1454       $smarty = get_smarty();
1455       $smarty->assign("ous",$this->get_all_group_ous());
1456       $smarty->assign("method","outside_groups");
1457       $smarty->assign("outside_groups",$tmp);
1458       $smarty->assign("group_details", $this->show_details);
1459       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1460     }
1461  
1462     /*************
1463      * User outside the people ou 
1464      *************/
1465     
1466     if(isset($_POST['outside_users_dialog_cancel'])){
1467       $this->outside_users_dialog = FALSE;
1468       $this->dialog = FALSE;
1469       $this->show_details = FALSE;
1470     }
1471    
1472     if(isset($_POST['outside_users_dialog_whats_done'])){
1473       $this->show_details= TRUE;
1474       $this->migrate_outside_users(FALSE);
1475     }
1476  
1477     if(isset($_POST['outside_users_dialog_perform'])){
1478       $this->migrate_outside_users(TRUE);
1479       $this->initialize_checks();
1480       $this->dialog = FALSE;
1481       $this->show_details = FALSE;
1482       $this->outside_users_dialog = FALSE;
1483     }
1485     if (isset($_POST['outside_users_dialog_refresh'])){
1486       $this->show_details= FALSE;
1487     }
1489     if(isset($_POST['outside_users_dialog'])){
1490       $this->outside_users_dialog = TRUE;
1491       $this->dialog = TRUE;
1492     }
1493     
1494     if($this->outside_users_dialog){
1496       /* Fix displayed dn syntax */ 
1497       $tmp = $this->outside_users;
1498       foreach($tmp as $key => $data){
1499         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1500       }
1502       $smarty = get_smarty();
1503       $smarty->assign("ous",$this->get_all_people_ous());
1504       $smarty->assign("method","outside_users");
1505       $smarty->assign("outside_users",$tmp);
1506       $smarty->assign("user_details", $this->show_details);
1507       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1508     }
1509  
1510     /*************
1511      * Root object check  
1512      *************/
1513   
1514     if(isset($_POST['retry_root_create'])){
1516       $state = $this->checks['root']['STATUS'];
1517       $this->checkBase(FALSE);
1518       if($state != $this->checks['root']['STATUS']){
1519         $this->initialize_checks();
1520       }
1521     }
1523     /*************
1524      * Root object class check  
1525      *************/
1526   
1527     if(isset($_POST['root_add_objectclasses'])){
1528       $this->rootOC_migrate_dialog = TRUE;
1529       $this->dialog = TRUE;
1530     }
1531     if(isset($_POST['rootOC_dialog_cancel'])){
1532       $this->rootOC_migrate_dialog = FALSE;
1533       $this->dialog = FALSE;
1534     }
1535     if(isset($_POST['rootOC_migrate_start'])){
1536       if($this->checkBaseOC(FALSE)){
1537         $this->checkBaseOC(); // Update overview info
1538         $this->dialog = FALSE;
1539         $this->rootOC_migrate_dialog = FALSE;
1540       }
1541     }
1544     if($this->rootOC_migrate_dialog){
1545       $smarty = get_smarty();
1546       $smarty->assign("details",$this->rootOC_details);
1547       $smarty->assign("method","rootOC_migrate_dialog");
1548       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1549     }
1551     /*************
1552      * Administrative Account -- Migrate/Create 
1553      *************/
1555     if(isset($_POST['retry_acls'])){
1556       $this->check_administrativeAccount();
1557     }
1559     /* Dialog handling */
1560     if(isset($_POST['create_acls'])){
1561       $this->acl_create_dialog = TRUE;
1562       $this->dialog = TRUE;
1563     }
1565     if(isset($_POST['migrate_acls'])){
1566       $this->acl_migrate_dialog = TRUE;
1567       $this->dialog = TRUE;
1568     }
1569   
1570     if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
1571       $this->acl_create_dialog = FALSE;
1572       $this->acl_migrate_dialog = FALSE;
1573       $this->dialog = FALSE;
1574       $this->show_details = FALSE;
1575     }
1577     /* Account creation */
1578     if(isset($_POST['create_acls_create'])){
1579       $this->create_admin(TRUE);
1580     }
1582     if(isset($_POST['create_admin_user'])){
1583       if($this->create_admin_user()){
1584         $this->dialog = FALSE;
1585       $this->show_details = FALSE;
1586       }
1587     }
1589     /* Add admin acls for the selected users to the ldap base.
1590      */
1591     if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
1593       /* Update ldap and reload check infos 
1594        */
1595       $this->migrate_selected_admin_users();
1597     }elseif($this->acl_migrate_dialog){
1599       /* Display admin migration dialog.
1600        */
1601       $this->migrate_users();
1602       $smarty = get_smarty();
1604       /* Do we have to display the changes
1605        */
1606       $details = isset($_POST['details']) && $_POST['details'];
1607       if(isset($_POST['migrate_acls_show_changes'])){
1608         $details = TRUE;
1609       }elseif(isset($_POST['migrate_acls_hide_changes'])){
1610         $details = FALSE;
1611       }
1613       $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
1614       $smarty->assign("details", $details);
1615       $smarty->assign("method","migrate_acls");
1616       $smarty->assign("migrateable_users",$this->migrate_users);
1617       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1618     }
1620     if($this->acl_create_dialog){
1621       $smarty = get_smarty();
1622       $uid = "admin";
1623       if(isset($_POST['new_user_uid'])){
1624         $uid = $_POST['new_user_uid'];
1625       }
1626       $smarty->assign("new_user_uid",$uid);
1627       $smarty->assign("new_user_password",@$_POST['new_user_password']);
1628       $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
1629       $smarty->assign("method","create_acls");
1630       $smarty->assign("acl_create_selected",$this->acl_create_selected);
1631       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
1632       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1633     }
1635     /*************
1636      * User Migration handling 
1637      *************/
1639     /* Refresh list of deparments */
1640     if(isset($_POST['users_visible_migrate_refresh'])){
1641       $this->check_gosaAccounts();
1642     }
1644     /* Open migration dialog */
1645     if(isset($_POST['users_visible_migrate'])){
1646       $this->show_details= FALSE;
1647       $this->users_migration_dialog = TRUE;
1648       $this->dialog =TRUE;
1649     }
1651     /* Close migration dialog */
1652     if(isset($_POST['users_visible_migrate_close'])){
1653       $this->users_migration_dialog = FALSE;
1654       $this->dialog =FALSE;
1655       $this->show_details = FALSE;
1656     }
1658     /* Start migration */
1659     if(isset($_POST['users_visible_migrate_migrate'])){
1660       if($this->migrate_gosaAccounts()){
1661         $this->initialize_checks();
1662         $this->dialog = FALSE;
1663         $this->show_details = FALSE;
1664         $this->users_migration_dialog = FALSE;
1665       }
1666     }
1668     /* Start migration */
1669     if(isset($_POST['users_visible_migrate_whatsdone'])){
1670       $this->migrate_gosaAccounts(TRUE);
1671     }
1673     /* Display migration dialog */
1674     if($this->users_migration_dialog){
1676       /* Fix displayed dn syntax */ 
1677       $tmp = $this->users_to_migrate;
1678       foreach($tmp as $key => $data){
1679         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1680       }
1682       $smarty = get_smarty();
1683       $smarty->assign("users_to_migrate",$tmp);
1684       $smarty->assign("method","migrate_users");
1685       $smarty->assign("user_details", $this->show_details);
1686       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1687     }
1690     /*************
1691      * Department Migration handling 
1692      *************/
1694     /* Refresh list of deparments */
1695     if(isset($_POST['deps_visible_migrate_refresh'])){
1696       $this->check_organizationalUnits();
1697       $this->show_details= FALSE;
1698     }
1700     /* Open migration dialog */
1701     if(isset($_POST['deps_visible_migrate'])){
1702       $this->dep_migration_dialog = TRUE;
1703       $this->dialog =TRUE;
1704     }
1706     /* Close migration dialog */
1707     if(isset($_POST['deps_visible_migrate_close'])){
1708       $this->dep_migration_dialog = FALSE;
1709       $this->dialog =FALSE;
1710       $this->show_details = FALSE;
1711     }
1713     /* Start migration */
1714     if(isset($_POST['deps_visible_migrate_migrate'])){
1715       if($this->migrate_organizationalUnits()){
1716         $this->show_details= FALSE;
1717         $this->check_organizationalUnits();
1718         $this->dialog = FALSE;
1719         $this->dep_migration_dialog = FALSE;
1720       }
1721     }
1723     /* Start migration */
1724     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1725       $this->migrate_organizationalUnits(TRUE);
1726     }
1728     /* Display migration dialog */
1729     if($this->dep_migration_dialog){
1730       $smarty = get_smarty();
1731    
1732       /* Fix displayed dn syntax */ 
1733       $tmp = $this->deps_to_migrate;
1734       foreach($tmp as $key => $data){
1735         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1736       }
1738       $smarty->assign("deps_to_migrate",$tmp);
1739       $smarty->assign("method","migrate_deps");
1740       $smarty->assign("deps_details", $this->show_details);
1741       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1742     }
1745     /*************
1746      * Device migration 
1747      *************/
1748    
1749     if($this->device_dialog) {
1750       $this->check_device_posts();
1751     }
1752  
1753     if(isset($_POST['device_dialog_cancel'])){
1754       $this->device_dialog = FALSE;
1755       $this->show_details = FALSE;
1756       $this->dialog = FALSE;
1757     }
1758    
1759     if(isset($_POST['device_dialog_whats_done'])){
1760       $this->show_details= TRUE;
1761     }
1762  
1763     if(isset($_POST['device_dialog_refresh'])){
1764       $this->show_details= FALSE;
1765     }
1767     if(isset($_POST['migrate_devices'])){
1768       $this->migrate_usb_devices();
1769 #      $this->dialog = FALSE;
1770  #     $this->show_details = FALSE;
1771   #    $this->device_dialog = FALSE;
1772    #   $this->initialize_checks();
1773     }
1775     if(isset($_POST['device_dialog'])){
1776       $this->device_dialog = TRUE;
1777       $this->dialog = TRUE;
1778     }
1779     
1780     if($this->device_dialog){
1781       $smarty = get_smarty();
1782       $smarty->assign("method","devices");
1783       $smarty->assign("devices",$this->device);
1784       $smarty->assign("device_details", $this->show_details);
1785       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1786     }
1789     /*************
1790      * Service migration 
1791      *************/
1792    
1793     if($this->service_dialog) {
1794       $this->check_service_posts();
1795     }
1796  
1797     if(isset($_POST['service_dialog_cancel'])){
1798       $this->service_dialog = FALSE;
1799       $this->show_details = FALSE;
1800       $this->dialog = FALSE;
1801     }
1802    
1803     if(isset($_POST['service_dialog_whats_done'])){
1804       $this->show_details= TRUE;
1805     }
1806  
1807     if(isset($_POST['service_dialog_refresh'])){
1808       $this->show_details= FALSE;
1809     }
1811     if(isset($_POST['migrate_services'])){
1812       $this->migrate_services();
1813 #      $this->dialog = FALSE;
1814  #     $this->show_details = FALSE;
1815   #    $this->service_dialog = FALSE;
1816    #   $this->initialize_checks();
1817     }
1819     if(isset($_POST['service_dialog'])){
1820       $this->service_dialog = TRUE;
1821       $this->dialog = TRUE;
1822     }
1823     
1824     if($this->service_dialog){
1825       $smarty = get_smarty();
1826       $smarty->assign("method","services");
1827       $smarty->assign("services",$this->service);
1828       $smarty->assign("service_details", $this->show_details);
1829       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1830     }
1833     /*************
1834      * Menu migration 
1835      *************/
1836    
1837     if($this->menu_dialog) {
1838       $this->check_menu_posts();
1839     }
1840  
1841     if(isset($_POST['menu_dialog_cancel'])){
1842       $this->menu_dialog = FALSE;
1843       $this->show_details = FALSE;
1844       $this->dialog = FALSE;
1845     }
1846    
1847     if(isset($_POST['menu_dialog_whats_done'])){
1848       $this->show_details= TRUE;
1849     }
1850  
1851     if(isset($_POST['menu_dialog_refresh'])){
1852       $this->show_details= FALSE;
1853     }
1855     if(isset($_POST['migrate_menus'])){
1856       $this->migrate_menus();
1857 #      $this->dialog = FALSE;
1858  #     $this->show_details = FALSE;
1859   #    $this->menu_dialog = FALSE;
1860    #   $this->initialize_checks();
1861     }
1863     if(isset($_POST['menu_dialog'])){
1864       $this->menu_dialog = TRUE;
1865       $this->dialog = TRUE;
1866     }
1867     
1868     if($this->menu_dialog){
1869       $smarty = get_smarty();
1870       $smarty->assign("method","menus");
1871       $smarty->assign("menus",$this->menu);
1872       $smarty->assign("menu_details", $this->show_details);
1873       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1874     }
1876     $smarty = get_smarty();
1877     $smarty->assign("checks",$this->checks);
1878     $smarty->assign("method","default");
1879     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1880   }
1883   function save_object()
1884   {
1885     $this->is_completed= TRUE;
1887     /* Capture all selected winstations from outside_winstations_dialog */
1888     if($this->outside_winstations_dialog){
1889       foreach($this->outside_winstations as $dn => $data){
1890         if(isset($_POST['select_winstation_'.$dn])){
1891           $this->outside_winstations[$dn]['selected'] = TRUE;
1892         }else{
1893           $this->outside_winstations[$dn]['selected'] = FALSE;
1894         }
1895       }
1896     }
1898     /* Capture all selected groups from outside_groups_dialog */
1899     if($this->outside_groups_dialog){
1900       foreach($this->outside_groups as $dn => $data){
1901         if(isset($_POST['select_group_'.$dn])){
1902           $this->outside_groups[$dn]['selected'] = TRUE;
1903         }else{
1904           $this->outside_groups[$dn]['selected'] = FALSE;
1905         }
1906       }
1907     }
1909     /* Capture all selected users from outside_users_dialog */
1910     if($this->outside_users_dialog){
1911       foreach($this->outside_users as $dn => $data){
1912         if(isset($_POST['select_user_'.$dn])){
1913           $this->outside_users[$dn]['selected'] = TRUE;
1914         }else{
1915           $this->outside_users[$dn]['selected'] = FALSE;
1916         }
1917       }
1918     }
1920     /* Get "create acl" dialog posts */
1921     if($this->acl_create_dialog){
1923       if(isset($_POST['create_acls_create_abort'])){
1924         $this->acl_create_selected = "";
1925       }
1926     }
1928     /* Get selected departments */
1929     if($this->dep_migration_dialog){
1930       foreach($this->deps_to_migrate as $id => $data){
1931         if(isset($_POST['migrate_'.$id])){
1932           $this->deps_to_migrate[$id]['checked'] = TRUE;
1933         }else{
1934           $this->deps_to_migrate[$id]['checked'] = FALSE;
1935         }
1936       }
1937     }
1939     /* Get selected users */
1940     if($this->users_migration_dialog){
1941       foreach($this->users_to_migrate as $id => $data){
1942         if(isset($_POST['migrate_'.$id])){
1943           $this->users_to_migrate[$id]['checked'] = TRUE;
1944         }else{
1945           $this->users_to_migrate[$id]['checked'] = FALSE;
1946         }
1947       }
1948     }
1949   }
1952   /* Check if the root object exists.
1953    * If the parameter just_check is true, then just check if the 
1954    *  root object is missing and update the info messages.
1955    * If the Parameter is false, try to create a new root object.
1956    */
1957   function checkBase($just_check = TRUE)
1958   {
1959     /* Establish ldap connection */
1960     $cv = $this->parent->captured_values;
1961     $ldap_l = new LDAP($cv['admin'],
1962         $cv['password'],
1963         $cv['connection'],
1964         FALSE,
1965         $cv['tls']);
1967     $ldap = new ldapMultiplexer($ldap_l);
1969     /* Check if root object exists */
1970     $ldap->cd($cv['base']);
1971     $ldap->set_size_limit(1);
1972     $res = $ldap->search("(objectClass=*)");
1973     $ldap->set_size_limit(0);
1974     $err = ldap_errno($ldap->cid); 
1976     if( !$res || 
1977         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1978         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1980       /* Root object doesn't exists 
1981        */
1982       if($just_check){
1983         $this->checks['root']['STATUS']    = FALSE;
1984         $this->checks['root']['STATUS_MSG']= _("Failed");
1985         $this->checks['root']['ERROR_MSG'] =  _("The LDAP root object is missing. It is required to use your LDAP service.").'&nbsp;';
1986         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1987         return(FALSE);
1988       }else{
1990         /* Add root object */ 
1991         $ldap->cd($cv['base']);
1992         $res = $ldap->create_missing_trees($cv['base']);
1994         /* If adding failed, tell the user */
1995         if(!$res){
1996           $this->checks['root']['STATUS']    = FALSE;
1997           $this->checks['root']['STATUS_MSG']= _("Failed");
1998           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1999           $this->checks['root']['ERROR_MSG'].= "&nbsp;<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
2000           return($res);;
2001         }
2002       }
2003     }
2005     /* Create & remove of dummy object was successful */
2006     $this->checks['root']['STATUS']    = TRUE;
2007     $this->checks['root']['STATUS_MSG']= _("Ok");
2008   }
2011   /* Check if the root object includes the required object classes, e.g. gosaDepartment is required for ACLs.
2012    * If the parameter just_check is true, then just check for the OCs. 
2013    * If the Parameter is false, try to add the required object classes.
2014    */
2015   function checkBaseOC($just_check = TRUE)
2016   {
2017     /* Establish ldap connection */
2018     $cv = $this->parent->captured_values;
2019     $ldap_l = new LDAP($cv['admin'],
2020         $cv['password'],
2021         $cv['connection'],
2022         FALSE,
2023         $cv['tls']);
2025     $ldap = new ldapMultiplexer($ldap_l);
2027     /* Check if root object exists */
2028     $ldap->cd($cv['base']);
2029     $ldap->cat($cv['base']);
2030     if(!$ldap->count()){
2031       $this->checks['rootOC']['STATUS']    = FALSE;
2032       $this->checks['rootOC']['STATUS_MSG']= _("LDAP query failed");
2033       $this->checks['rootOC']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2034       return;
2035     }
2037     $attrs = $ldap->fetch();
2039     /* Root object doesn't exists 
2040      */
2041     if(!in_array("gosaDepartment",$attrs['objectClass'])){
2042       if($just_check){
2044         $this->rootOC_details = array();        
2045         $mods = array();
2047         /* Get list of possible container objects, to be able to detect naming 
2048          *  attributes and missing attribute types.
2049          */
2050         if(!class_available("departmentManagement")){
2051           $this->checks['rootOC']['STATUS']    = FALSE;
2052           $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2053           $this->checks['rootOC']['ERROR_MSG'] = sprintf(_("Missing GOsa object class '%s'!"),"departmentManagement").
2054             "&nbsp;"._("Please check your installation.");
2055           return;
2056         }
2058         /* Try to detect base class type, e.g. is it a dcObject.
2059          */
2060         $dep_types = departmentManagement::get_support_departments();
2061         $dep_type ="";
2062         foreach($dep_types as $dep_name => $dep_class){
2063           if(in_array($dep_class['CLASS'], $attrs['objectClass'])){
2064             $dep_type = $dep_name;
2065             break;
2066           }
2067         }
2069         /* If no known base class was detect, abort with message
2070          */     
2071         if(empty($dep_type)){
2072           $this->checks['rootOC']['STATUS']    = FALSE;
2073           $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2074           $this->checks['rootOC']['ERROR_MSG'] = 
2075             sprintf(_("Cannot handle the structural object type of your root object. Please try to add the object class '%s' manually."),"gosaDepartment");
2076           return;
2077         }
2079         /* Create 'current' and 'target' object properties, to be able to display 
2080          *  a set of modifications required to create a valid GOsa department.
2081          */     
2082         $str = "dn: ".$cv['base']."\n";
2083         for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
2084           $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
2085         }
2086         $this->rootOC_details['current'] = $str;
2088         /* Create target infos 
2089          */
2090         $str = "dn: ".$cv['base']."\n";
2091         for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
2092           $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
2093           $mods['objectClass'][] = $attrs['objectClass'][$i];
2094         }
2095         $mods['objectClass'][] = "gosaDepartment";
2096         $str .= "<b>objectClass: gosaDepartment</b>\n";
2098         /* Append attribute 'ou', it is required by gosaDepartment
2099          */
2100         if(!isset($attrs['ou'])){
2101           $val = "GOsa";
2102           if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
2103             $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
2104           }
2105           $str .= "<b>ou: ".$val."</b>\n";
2106           $mods['ou'] =$val;
2107         }
2109         /*Append description, it is required by gosaDepartment too.
2110          */
2111         if(!isset($attrs['description'])){
2112           $val = "GOsa";
2113           if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
2114             $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
2115           }
2116           $str .= "<b>description: ".$val."</b>\n";
2117           $mods['description'] = $val;
2118         }
2119         $this->rootOC_details['target'] = $str;
2120         $this->rootOC_details['mods'] = $mods;
2122         /*  Add button that allows to open the migration details
2123          */
2124         $this->checks['rootOC']['STATUS']    = FALSE;
2125         $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2126         $this->checks['rootOC']['ERROR_MSG'] = "&nbsp;<input type='submit' 
2127           name='root_add_objectclasses' value='"._("Migrate")."'>";
2129         return(FALSE);
2130       }else{
2132         /* Add root object */ 
2133         $ldap->cd($cv['base']);
2134         if(isset($this->rootOC_details['mods'])){
2135           $res  = $ldap->modify($this->rootOC_details['mods']); 
2136           if(!$res){
2137             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_MOD, get_class()));
2138           }
2139           return($res);
2140         }else{
2141           trigger_error("No modifications to make... ");
2142         }
2143       }
2144       return(TRUE);
2145     }
2147     /* Create & remove of dummy object was successful */
2148     $this->checks['rootOC']['STATUS']    = TRUE;
2149     $this->checks['rootOC']['STATUS_MSG']= _("Ok");
2150     $this->checks['rootOC']['ERROR_MSG'] = "";
2151   }
2154   /* Return ldif information for a 
2155    * given attribute array 
2156    */
2157   function array_to_ldif($atts)
2158   {
2159     $ret = "";
2160     unset($atts['count']);
2161     unset($atts['dn']);
2162     foreach($atts as $name => $value){
2163       if(is_numeric($name)) {
2164         continue;
2165       }
2166       if(is_array($value)){
2167         unset($value['count']);
2168         foreach($value as $a_val){
2169           $ret .= $name.": ". $a_val."\n";
2170         }
2171       }else{
2172         $ret .= $name.": ". $value."\n";
2173       }
2174     }
2175     return(preg_replace("/\n$/","",$ret));
2176   }
2179   function get_user_list()
2180   {
2181     /* Establish ldap connection */
2182     $cv = $this->parent->captured_values;
2183     $ldap_l = new LDAP($cv['admin'],
2184         $cv['password'],
2185         $cv['connection'],
2186         FALSE,
2187         $cv['tls']);
2189     $ldap = new ldapMultiplexer($ldap_l);
2190     $ldap->cd($cv['base']);
2191     $ldap->search("(objectClass=gosaAccount)",array("dn"));
2192   
2193     $tmp = array();
2194     while($attrs = $ldap->fetch()){
2195       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2196     }
2197     return($tmp);
2198   }
2201  function get_all_people_ous()
2202   {
2203     /* Get collected configuration settings */
2204     $cv = $this->parent->captured_values;
2205     $people_ou = trim($cv['peopleou']);
2207     /* Establish ldap connection */
2208     $cv = $this->parent->captured_values;
2209     $ldap_l = new LDAP($cv['admin'],
2210         $cv['password'],
2211         $cv['connection'],
2212         FALSE,
2213         $cv['tls']);
2215     $ldap = new ldapMultiplexer($ldap_l);
2217     /*****************
2218      * If people ou is NOT empty
2219      * search for for all objects matching the given container
2220      *****************/
2221     if(!empty($people_ou)){
2222       $ldap->search("(".$people_ou.")",array("dn"));
2224       /* Create people ou if there is currently none */
2225       if($ldap->count() == 0 ){
2226         $add_dn = $cv['peopleou'].",".$cv['base'];
2227         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2228         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2229         $add = array();
2230         $add['objectClass'] = array("organizationalUnit");
2231         $add[$naming_attr] = $naming_value;
2232         $ldap->cd($cv['base']);
2233         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2234         $ldap->cd($add_dn);
2235         $ldap->add($add);
2236       }
2238       /* Create result */
2239       $ldap->search("(".$cv['peopleou'].")",array("dn"));
2240       $tmp = array();
2241       while($attrs= $ldap->fetch()){
2242         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2243           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2244         }
2245       }
2246     } else{
2248       /************
2249        * If people ou is empty
2250        * Get all valid gosaDepartments
2251        ************/
2252       $ldap->cd($cv['base']);
2253       $tmp = array();
2254       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2255       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2256       while($attrs = $ldap->fetch()){
2257         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2258       }
2259     }
2260     return($tmp);
2261   }
2264   function get_all_winstation_ous()
2265   {
2266     /* Establish ldap connection */
2267     $cv = $this->parent->captured_values;
2268     $ldap_l = new LDAP($cv['admin'],
2269         $cv['password'],
2270         $cv['connection'],
2271         FALSE,
2272         $cv['tls']);
2274     $ldap = new ldapMultiplexer($ldap_l);
2276     /* Get winstation ou */
2277     if($cv['generic_settings']['wws_ou_active']) {
2278       $winstation_ou = $cv['generic_settings']['wws_ou'];
2279     }else{
2280       $winstation_ou = "ou=winstations";
2281     }
2283     $ldap->cd($cv['base']);
2284     $ldap->search("(".$winstation_ou.")",array("dn"));
2285   
2286     if($ldap->count() == 0 ){
2287       $add_dn = $winstation_ou.",ou=systems,".$cv['base'];
2288       $naming_attr = preg_replace("/=.*$/","",$add_dn);
2289       $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2290       $add = array();
2291       $add['objectClass'] = array("organizationalUnit");
2292       $add[$naming_attr] = $naming_value;
2294       $ldap->cd($cv['base']);
2295       $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2296       $ldap->cd($add_dn);
2297       $ldap->add($add);
2298     }
2300     $ldap->search("(".$winstation_ou.")",array("dn"));
2301     $tmp = array();
2302     while($attrs= $ldap->fetch()){
2303       if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2304         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2305       }
2306     }
2307     return($tmp); 
2308   }
2311  function get_all_group_ous()
2312   {
2313     /* Establish ldap connection */
2314     $cv = $this->parent->captured_values;
2315     $ldap_l = new LDAP($cv['admin'],
2316         $cv['password'],
2317         $cv['connection'],
2318         FALSE,
2319         $cv['tls']);
2321     $ldap = new ldapMultiplexer($ldap_l);
2323     $group_ou = trim($cv['groupou']);
2324     if(!empty($group_ou)){
2325       $group_ou = trim($group_ou);
2326     }
2328     /************
2329      * If group ou is NOT empty
2330      * Get all valid group ous, create one if necessary
2331      ************/
2332     $ldap->cd($cv['base']);
2333     if(!empty($group_ou)){
2334       $ldap->search("(".$group_ou.")",array("dn"));
2335       if($ldap->count() == 0 ){
2336         $add_dn = $group_ou.$cv['base'];
2337         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2338         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2339         $add = array();
2340         $add['objectClass'] = array("organizationalUnit");
2341         $add[$naming_attr] = $naming_value;
2343         $ldap->cd($cv['base']);
2344         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2345         $ldap->cd($add_dn);
2346         $ldap->add($add);
2347       }
2348       $ldap->search("(".$group_ou.")",array("dn"));
2349       $tmp = array();
2350       while($attrs= $ldap->fetch()){
2351         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2352           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2353         }
2354       }
2355     }else{
2356       /************
2357        * If group ou is empty
2358        * Get all valid gosaDepartments
2359        ************/
2360       $ldap->cd($cv['base']);
2361       $tmp = array();
2362       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2363       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2364       while($attrs = $ldap->fetch()){
2365         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2366       }
2367     }
2368     return($tmp);
2369   }
2372   function get_group_list()
2373   {
2374     /* Establish ldap connection */
2375     $cv = $this->parent->captured_values;
2376     $ldap_l = new LDAP($cv['admin'],
2377         $cv['password'],
2378         $cv['connection'],
2379         FALSE,
2380         $cv['tls']);
2382     $ldap = new ldapMultiplexer($ldap_l);
2383     
2384     $ldap->cd($cv['base']);
2385     $ldap->search("(objectClass=posixGroup)",array("dn"));
2386   
2387     $tmp = array();
2388     while($attrs = $ldap->fetch()){
2389       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2390     }
2391     return($tmp);
2392   }
2395   function move($source,$destination)
2396   {
2397     /* Establish ldap connection */
2398     $cv = $this->parent->captured_values;
2399     $ldap_l = new LDAP($cv['admin'],
2400         $cv['password'],
2401         $cv['connection'],
2402         FALSE,
2403         $cv['tls']);
2405     $ldap = new ldapMultiplexer($ldap_l);
2407      /* Update object references in gosaGroupOfNames */
2408     $ogs_to_fix = array();
2409     $ldap->cd($cv['base']);
2410     $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($source).'))', array('cn','member'));
2411     while ($attrs= $ldap->fetch()){
2412       $dn = $attrs['dn'];
2413       $attrs = $this->cleanup_array($attrs);
2414       $member_new = array($destination);
2415       foreach($attrs['member'] as $member){
2416         if($member != $source){
2417           $member_new[] = $member;
2418         }
2419       }
2420       $attrs['member'] = $member_new;
2421       $ogs_to_fix[$dn] = $attrs;
2422     }
2424     /* Copy source to destination dn */
2425     $ldap->cat($source);
2426     $new_data = $this->cleanup_array($ldap->fetch());
2427     $ldap->cd($destination);
2428     $res = $ldap->add($new_data);
2430     /* Display warning if copy failed */
2431     if(!$res){
2432       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);
2433     }else{
2434       $res = $ldap->rmDir($source);
2435       if (!$ldap->success()){
2436         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_DEL, get_class()));
2437       }
2439       /* Object is copied, so update its references */
2440       foreach($ogs_to_fix as $dn => $data){
2441         $ldap->cd($dn);
2442         $ldap->modify($data);
2443       }
2444     }
2445   }
2448   /* Cleanup ldap result to be able to write it be to ldap */
2449   function cleanup_array($attrs)
2450   {
2451     foreach($attrs as $key => $value) {
2452       if(is_numeric($key) || in_array($key,array("count","dn"))){
2453         unset($attrs[$key]);
2454       }
2455       if(is_array($value) && isset($value['count'])){
2456         unset($attrs[$key]['count']);
2457       }
2458     }
2459     return($attrs);
2460   }
2463   /*! \brief  Act in posts from the device migration dialog 
2464    */
2465   function check_device_posts()
2466   {
2467     foreach($this->device as $key => $device){
2468       if(isset($_POST["migrate_".$key])){
2469         $this->device[$key]['DETAILS'] =TRUE;
2470       }else{
2471         $this->device[$key]['DETAILS'] =FALSE;
2472       }
2473     }
2474   }
2477   /*! \brief  Check for old style (gosa-2.5) devices.
2478               Save readable informations and a list of migratable devices 
2479                in $this->devices.
2480    */
2481   function check_usb_devices ()
2482   {
2483     /* Establish ldap connection */
2484     $cv = $this->parent->captured_values;
2485     $ldap_l = new LDAP($cv['admin'],
2486         $cv['password'],
2487         $cv['connection'],
2488         FALSE,
2489         $cv['tls']);
2491     $ldap = new ldapMultiplexer($ldap_l);
2492     $ldap->cd($cv['base']);
2493     $res = $ldap->search("(&(|(objectClass=posixAccount)(objectClass=posixGroup))(gotoHotplugDevice=*))",
2494         array("cn","gotoHotplugDevice","gosaUnitTag"));
2496     if(!$res){
2497       $this->checks['old_style_devices']['STATUS']    = FALSE;
2498       $this->checks['old_style_devices']['STATUS_MSG']= _("LDAP query failed");
2499       $this->checks['old_style_devices']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2500       return;
2501     }
2504     /* If adding failed, tell the user */
2505     if($ldap->count()){
2506   
2507       $this->device = array();
2508       while($attrs = $ldap->fetch()){
2510         for ($j= 0; $j < $attrs['gotoHotplugDevice']['count']; $j++){
2512           $after  = "";
2513           $current= "";
2515           $entry= $attrs['gotoHotplugDevice'][$j];
2517           @list($name,$desc,$serial,$vendor,$product) = explode('|', $entry);
2518   
2519           $add = 1;
2520           $new_name  = $name;
2521           while(isset($dest[$new_name])){
2522             $new_name = $name."_".$add;
2523             $add ++;
2524           }
2525           $name = $new_name;
2526           $newdn= "cn=$name,ou=devices,".preg_replace('/^[^,]+,/', '', $attrs['dn']);
2528           if (!isset($dest[$name])){
2529             $dest[$name]= $newdn;
2531             $current.= "dn: ".$attrs['dn']."\n"; 
2532     
2533             for ($c= 0; $c < $attrs['gotoHotplugDevice']['count']; $c++){
2534               if($c == $j){
2535                 $current.= "<b>gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."</b>\n"; 
2536               }else{
2537                 $current.= "gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."\n"; 
2538               }
2539             }
2541             $after.= "dn: $newdn\n";
2542             $after.= "changetype: add\n";
2543             $after.= "objectClass: top\n";
2544             $after.= "objectClass: gotoDevice\n";
2545             if (isset($attrs['gosaunittag'][0])){
2546               $after.= "objectClass: gosaAdminiafter\n";
2547               $after.= "gosaUnitTag: ".$attrs['gosaunittag'][0]."\n";
2548             }
2549             $after.= "cn: $name\n";
2550             $after.= "gotoHotplugDevice: $desc|$serial|$vendor|$product\n\n";
2552             $this->device[] = array(
2553                 'CURRENT'     =>  $current,
2554                 'AFTER'       => $after,
2555                 'OLD_DEVICE'  => $entry,
2556                 'DN'          => $attrs['dn'],
2557                 'NEW_DN'      => $newdn,
2558                 'DEVICE_NAME' => $name,
2559                 'DETAILS'     => FALSE);
2560           }
2561         }
2562       }
2564       $this->checks['old_style_devices']['STATUS']    = FALSE;
2565       $this->checks['old_style_devices']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2566       $this->checks['old_style_devices']['ERROR_MSG'] = 
2567         sprintf(_("There are %s devices that need to be migrated."),count($this->device)).
2568           "<input type='submit' name='device_dialog' value='"._("Migrate")."'>";
2569     }else{
2570       $this->checks['old_style_devices']['STATUS']    = TRUE;
2571       $this->checks['old_style_devices']['STATUS_MSG']= _("Ok");
2572       $this->checks['old_style_devices']['ERROR_MSG'] = "";
2573     }
2574   }
2577   /*! \brief  Migrate all selected devices. 
2578               Execute all required ldap actions to migrate the 
2579                selected devices.
2580    */
2581   function migrate_usb_devices ()
2582   {
2583     /* Establish ldap connection */
2584     $cv = $this->parent->captured_values;
2585     $ldap_l = new LDAP($cv['admin'],
2586         $cv['password'],
2587         $cv['connection'],
2588         FALSE,
2589         $cv['tls']);
2591     $ldap = new ldapMultiplexer($ldap_l);
2593     /* Walk through migrateable devices and initiate migration for all 
2594         devices that are checked (DETAILS==TRUE) 
2595      */
2596     foreach($this->device as $key => $device){
2597       if($device['DETAILS']){
2599         /* Get source object and verify that the specified device is a 
2600             member attribute of it. 
2601          */
2602         $ldap->cd($cv['base']);
2603         $ldap->cat($device['DN']);
2604         $attrs = $ldap->fetch();
2605         if(in_array($device['OLD_DEVICE'],$attrs['gotoHotplugDevice'])){
2607           /* Create new hotplug device object 'gotoDevice'
2608            */ 
2609           @list($name,$desc,$serial,$vendor,$product) = explode('|', $device['OLD_DEVICE']);    
2610           $newdn = $device['NEW_DN'];
2611           $new_attr = array();
2612           $new_attr['cn'] = $device['DEVICE_NAME'];
2613           $new_attr['objectClass'] = array('top','gotoDevice');
2614           $new_attr['gotoHotplugDevice'] = "$desc|$serial|$vendor|$product";
2616           /* Add new object 
2617            */
2618           $ldap->cd($cv['base']);
2619           $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$newdn));
2620           $ldap->cd($newdn);
2621           $ldap->add($new_attr);
2623           /* Throw an error message if the action failed. 
2624            */
2625           if(!$ldap->success()){
2626             msg_dialog::display(_("LDAP error"), 
2627                 sprintf(_("Adding '%s' to the LDAP failed: %s"),
2628                   "<b>".LDAP::fix($newdn)."</b>", 
2629                   "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
2630           }else{
2632             /* Remove old style device definition from source object. 
2633              */
2634             $update['gotoHotplugDevice'] = array();
2635             for($i = 0 ; $i < $attrs['gotoHotplugDevice']['count'] ; $i++){
2636               if($attrs['gotoHotplugDevice'][$i] == $device['OLD_DEVICE']){
2637                  continue;
2638               }
2639               $update['gotoHotplugDevice'][] = $attrs['gotoHotplugDevice'][$i];
2640             }
2642             $ldap->cd($device['DN']);
2643             $ldap->modify($update);
2644             $ldap->cat($device['DN'],array("gotoHotplugDevice"));
2645             if(!$ldap->success()){
2646               msg_dialog::display(_("LDAP error"), 
2647                   sprintf(_("Updating '%s' failed: %s"),
2648                     "<b>".LDAP::fix($device['DN'])."</b>", 
2649                     "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2650             }else{
2651               unset($this->device[$key]);
2652             }
2653           }
2654         }
2655       }
2656     }
2657     $this->check_usb_devices();
2658   }
2661   /*! \brief  Check for old style (gosa-2.5) services that have to be migrated
2662                to be useable in gosa-2.6.
2663               All required changes are stored in $this->service, also some
2664                readable informations describing the actions required 
2665                to migrate the service
2666    */
2667   function check_services()
2668   {
2669     /* Establish ldap connection */
2670     $cv = $this->parent->captured_values;
2671     $ldap_l = new LDAP($cv['admin'],
2672         $cv['password'],
2673         $cv['connection'],
2674         FALSE,
2675         $cv['tls']);
2677     $ldap = new ldapMultiplexer($ldap_l);
2678     $this->service = array();
2680     /* Check for Ldap services that must be migrated 
2681      */ 
2682     $ldap->cd($cv['base']);
2683     $res = $ldap->search("(objectClass=goLdapServer)", array("goLdapBase", "cn"));
2685     /* Check if we were able to query the ldap server 
2686      */
2687     if(!$res){
2688       $this->checks['old_style_services']['STATUS']    = FALSE;
2689       $this->checks['old_style_services']['STATUS_MSG']= _("LDAP query failed");
2690       $this->checks['old_style_services']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2691       return;
2692     }
2694     /* Walk through each configured ldap server 
2695         and check if it is configured correctly.
2696      */
2697     while($attrs = $ldap->fetch()){
2698       $dn= $attrs['dn'];
2699       $uri= $attrs['goLdapBase'][0];
2700       if (! preg_match("!^ldaps?://!", $uri)){
2701         $this->service[] = array(
2702             "TYPE"    => "modify" , 
2703             "DN"      => $dn, 
2704             "DETAILS" => FALSE, 
2705             "ATTRS"   => array("goLdapBase" => "ldap://".$attrs['cn'][0]."/$uri"),
2706             "CURRENT" => "goLdapBase: ".$uri,
2707             "AFTER"   => "goLdapBase: "."ldap://".$attrs['cn'][0]."/$uri");
2708       }
2709     }
2711     /* Other sevices following here later ...maybe
2712      */
2714     /*  Update status message
2715      */
2716     if(count($this->service)){
2717       $this->checks['old_style_services']['STATUS']    = FALSE;
2718       $this->checks['old_style_services']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2719       $this->checks['old_style_services']['ERROR_MSG'] =
2720         sprintf(_("There are %s services that need to be migrated."),
2721             count($this->service)).
2722         "<input type='submit' name='service_dialog' value='"._("Migrate")."'>";
2723     }else{
2724       $this->checks['old_style_services']['STATUS']    = TRUE;
2725       $this->checks['old_style_services']['STATUS_MSG']= _("Ok");
2726       $this->checks['old_style_services']['ERROR_MSG'] = "";
2727     }
2728   }
2731   
2732   /*! \brief  Migrate selected services.
2733               This function executes the commands collected by the 
2734                service_check() function.
2735    */
2736   function migrate_services()
2737   {
2738     /* Establish ldap connection 
2739      */
2740     $cv = $this->parent->captured_values;
2741     $ldap_l = new LDAP($cv['admin'],
2742         $cv['password'],
2743         $cv['connection'],
2744         FALSE,
2745         $cv['tls']);
2747     $ldap = new ldapMultiplexer($ldap_l);
2749     /* Handle each service 
2750      */
2751     foreach($this->service as $key => $service){
2752       if($service['DETAILS']){
2754         /* Handle modify requests 
2755          */
2756         if($service['TYPE'] == "modify"){
2757           $ldap->cd($service['DN']);
2758           $ldap->modify($service['ATTRS']);
2760           /* Check if everything done was successful 
2761            */
2762           if(!$ldap->success()){
2763             msg_dialog::display(_("LDAP error"), 
2764                 sprintf(_("Updating '%s' failed: %s"),
2765                   "<b>".LDAP::fix($service['DN'])."</b>", 
2766                   "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2767           }else{
2768         
2769             /* Remove action from list 
2770              */
2771             unset($this->service[$key]);
2772           }
2773         }
2774       }
2775     }
2777     /* Update the service migration status 
2778      */
2779     $this->check_services();
2780   }
2783   /*! \brief  Ensure that posts made on the service migration dialog 
2784                are processed.
2785    */
2786   function check_service_posts()
2787   {
2788     foreach($this->service as $key => $service){
2789       if(isset($_POST["migrate_".$key])){
2790         $this->service[$key]['DETAILS'] =TRUE;
2791       }else{
2792         $this->service[$key]['DETAILS'] =FALSE;
2793       }
2794     }
2795   }
2798   /*! \brief  This function checks the given ldap for old style (gosa-2.5) 
2799                menu entries and will prepare a list of actions that are required
2800                to migrate them to gosa-2.6.
2801               All required actions and some readable informations are stored in 
2802                $this->menu.
2803    */
2804   function check_menus()
2805   {
2806     /* Establish ldap connection
2807      */
2808     $cv = $this->parent->captured_values;
2809     $ldap_l = new LDAP($cv['admin'],
2810         $cv['password'],
2811         $cv['connection'],
2812         FALSE,
2813         $cv['tls']);
2815     $ldap = new ldapMultiplexer($ldap_l);
2817     /* First detect all release names 
2818      */
2819     $ldap->cd($cv['base']);
2820     $res = $ldap->search("(&(objectClass=organizational)(objectClass=FAIbranch))",array("ou","objectClass"));
2822     /* Check if we were able to query the ldap server
2823      */
2824     if(!$res){
2825       $this->checks['old_style_menus']['STATUS']    = FALSE;
2826       $this->checks['old_style_menus']['STATUS_MSG']= _("LDAP query failed");
2827       $this->checks['old_style_menus']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2828       return;
2829     }
2831     /* Create application -> parameter mapping, used later to detect 
2832         which configured parameter belongs to which application entry.
2833      */
2834     $amap= array();
2835     $todo = array();
2836     $ldap->cd($cv['base']);
2837     $ldap->search("(objectClass=gosaApplication)", array("cn", "gosaApplicationParameter"));
2838     while($info = $ldap->fetch()){
2839       if (isset($info['gosaApplicationParameter']['count'])){
2840         for ($j= 0; $j < $info['gosaApplicationParameter']['count']; $j++){
2841           $p= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$j]);
2843           if(!isset($amap[$info['cn'][0]]) || !in_array($p, $amap[$info['cn'][0]])){
2844             $amap[$info['cn'][0]][]= $p;
2845           }
2846         }
2847       } else {
2848         $amap[$info['cn'][0]]= array();
2849       }
2850     }
2852     /* Search for all groups that have an old style application menu configured.
2853      */  
2854     $appgroups = array();
2855     $ldap->cd($cv['base']);
2856     $ldap->search("(&(objectClass=gosaApplicationGroup)(objectClass=posixGroup)(FAIrelease=*))",
2857         array("gosaMemberApplication","gosaApplicationParameter","FAIrelease","objectClass","gosaUnitTag"));
2859     /* Create readable prefix for "What will be done" infos 
2860      */
2861     $s_add = "<i>"._("Add")."</i>\t";
2862     $s_del = "<i>"._("Remove")."</i>\t";
2864     /* Walk through all found old-style menu configurations.
2865         -Prepare ldap update list     $data   
2866         -Prepare printable changes    $after/$current
2867      */
2868     while($info = $ldap->fetch()){
2870       $data = array();
2871       $current = "";
2872       $after ="";
2874       /* Get unit tag 
2875        */
2876       $tag ="";
2877       if(isset($info['gosaUnitTag'])){
2878         $tag = $info['gosaUnitTag'][0];
2879       }
2881       /* Collect application parameter for this group
2882        */
2883       $params= array();
2884       if(isset($info['gosaApplicationParameter'])){
2885         for ($i= 0; $i < $info['gosaApplicationParameter']['count']; $i++){
2886           $name= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$i]);
2887           $params[$name]= $info['gosaApplicationParameter'][$i];
2888         }
2889       }
2891       /* Create release container for each release/subrelease.
2892          eg.   "sisa/1.0.0":
2893          .       "ou=siga, ..."
2894          .       "ou=1.0.0,ou=siga, .."
2895        */ 
2896       $release = "";
2897       $r = $info['FAIrelease'][0];
2898       $z = split("/",$r);
2899       foreach($z as $part){
2901         if(!empty($part)){
2902           $release = "ou=".$part.",".$release;
2904           /* Append release department information to "What will be done" info
2905            */
2906           $release_dn = $release.$info['dn'];
2907           $after   .=  $s_add."dn: $release_dn\n";
2908           $after   .=  $s_add."objectClass: top\n";
2909           $after   .=  $s_add."objectClass: FAIbranch\n";
2910           $after   .=  $s_add."objectClass: organizationalUnit\n";
2911          
2912           /* Append UnitTag 
2913            */ 
2914           if($tag != ""){ 
2915             $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2916             $after   .=  $s_add."gosaUnitTag: $tag\n";
2917           }
2918           $after   .=  $s_add."ou: $part\n";
2920           /* Append release data to ldap actions 
2921            */
2922           $d = array();
2923           $d['objectClass'] = array("top","FAIbranch","organizationalUnit");
2924           if(!empty($tag)){
2925             $d['objectClass'][] = "gosaAdministrativeUnitTag";
2926             $d['gosaUnitTag']   = $tag;
2927           }
2928           $d['ou']          = $part;
2929           $data['ADD'][$release_dn]= $d;
2930         }
2931       }
2933       /* Add member applications to the array.
2934        */ 
2935       $current .= "dn: ".$info['dn']."\n";
2936       $menu_structure = array();
2937       for ($i= 0; $i < $info['gosaMemberApplication']['count']; $i++){
2938         list($name, $location, $priority)= explode("|", $info['gosaMemberApplication'][$i]);
2940         /* Create location dn 
2941          */
2942         $location_dn ="";
2943         if(!empty($location)){
2944           $location_dn ="cn=".$location.",";
2945         }
2947         /* Append old style element to current detail informations 
2948          */      
2949         $current .= $s_del."gosaMemberApplication: ".$info['gosaMemberApplication'][$i]."\n";
2951         /* Append ldap update action to remove the old menu entry attributes 
2952          */
2953         unset($info['objectClass']['count']);
2954         $d = array();
2955         $d['gosaMemberApplication']      = array();
2956         $d['gosaApplicationParameter']  = array();
2957         if(isset($info['FAIrelease'])){
2958           $d['FAIrelease'] = array();
2959         }
2960         $d['objectClass']               = array_remove_entries(array("gosaApplicationGroup","FAIreleaseTag"),$info['objectClass']);
2961         $data['MODIFY'][$info['dn']]    = $d;
2963         /* Create new application menu structure 
2964          */
2965         if (isset($amap[$name])){
2967           /* Append missing menu structure to "What is done info"
2968            */
2969           if(!isset($menu_structure[$location]) && !empty($location)){
2970             $menu_structure[$location] = TRUE;
2971             $after .= "\n";
2972             $after .= $s_add."dn: $location_dn$release_dn\n";
2973             $after .= $s_add."objectClass: gotoSubmenuEntry\n";
2975             /* Append UnitTag
2976              */
2977             if($tag != ""){
2978               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2979               $after   .=  $s_add."gosaUnitTag: $tag\n";
2980             }
2981             $after .= $s_add."cn: $location\n";
2982   
2983             /* Create ldap entry to append 
2984              */
2985             $d = array();
2986             $d['cn'] = $location;
2987             $d['objectClass'] = array("gotoSubmenuEntry");
2988             if(!empty($tag)){
2989               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2990               $d['gosaUnitTag']   = $tag;
2991             }
2992             $data['ADD'][$location_dn.$release_dn] = $d;
2993           }
2996           /* Append missing menu entry for "What is done info".
2997            */
2998           if(!empty($name)){
2999             $after .= "\n";
3000             $after .= $s_add."dn: cn=$name,$location_dn$release_dn\n";
3001             $after .= $s_add."objectClass: gotoMenuEntry\n";
3002             if($tag != ""){
3003               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
3004               $after   .=  $s_add."gosaUnitTag: $tag\n";
3005             }
3006             $after .= $s_add."cn: $name\n";
3007             $after .= $s_add."gosaApplicationPriority: $priority\n";
3009             /* Create ldap entry 
3010              */
3011             $d= array();
3012             $d['objectClass'] = array("gotoMenuEntry");
3013             if(!empty($tag)){
3014               $d['objectClass'][] = "gosaAdministrativeUnitTag";
3015               $d['gosaUnitTag']   = $tag;
3016             }
3017             $d['cn']          = $name;
3018             $d['gosaApplicationPriority'] = $priority;
3020             foreach ($amap[$name] as $n){
3021               if (isset($params[$n])){
3022                 $after .= $s_add."gosaApplicationParameter: ".$params[$n]."\n";
3023                 $d['gosaApplicationParameter'][] = $params[$n];
3024               }
3025             }
3026             $data['ADD']["cn=$name,$location_dn$release_dn"] = $d;
3027           }         
3028         }
3029       }
3031       /* Updated todo list 
3032        */ 
3033       $todo[] = array(
3034           "DETAILS" => FALSE,
3035           "DN"      => $info['dn'],
3036           "AFTER"   => $after,
3037           "CURRENT" => $current,
3038           "TODO"    => $data
3039           );
3040     }
3042     /* Remember checks.
3043      */
3044     $this->menu = $todo;
3046     /* Check if we were able to query the ldap server
3047      */
3048     if(count($this->menu)){
3049       $this->checks['old_style_menus']['STATUS']    = FALSE;
3050       $this->checks['old_style_menus']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
3051       $this->checks['old_style_menus']['ERROR_MSG'] = sprintf(_("There are %s application menus which have to be migrated."),
3052                                                       count($this->menu))."<input type='submit' name='menu_dialog' value='"._("Migrate")."'>";
3053     }else{
3054       $this->checks['old_style_menus']['STATUS']    = TRUE;
3055       $this->checks['old_style_menus']['STATUS_MSG']= _("Ok");
3056       $this->checks['old_style_menus']['ERROR_MSG'] = "";
3057     }
3058   }
3060   
3061   /*! \brief  Handle posts for the menu_dialog 
3062               Ensure that checked checkboxes stay checked.
3063    */
3064   function check_menu_posts()
3065   {
3066     foreach($this->menu as $key => $menu){
3067       if(isset($_POST["migrate_".$key])){
3068         $this->menu[$key]['DETAILS'] =TRUE;
3069       }else{
3070         $this->menu[$key]['DETAILS'] =FALSE;
3071       }
3072     }
3073   }
3076   /*! \brief  This function updates old-style application menus to
3077                valid 2.6 application menus.
3078               All selected menus will be converted (DETAILS = TRUE). 
3079               The ldap actions collected by check_menus() will be executed. 
3080    */
3081   function migrate_menus()
3082   {
3084     /* Establish ldap connection
3085      */
3086     $cv = $this->parent->captured_values;
3087     $ldap_l = new LDAP($cv['admin'],
3088         $cv['password'],
3089         $cv['connection'],
3090         FALSE,
3091         $cv['tls']);
3093     $ldap = new ldapMultiplexer($ldap_l);
3094     $ldap->cd($cv['base']);
3096     /* Walk through menus and detect selected menu 
3097      */
3098     foreach($this->menu as $key => $menu){
3099       if($menu['DETAILS']) {
3101         /* Excute all LDAP-ADD actions 
3102          */
3103         $success = TRUE;
3104         foreach($menu['TODO']['ADD'] as $dn => $data){
3105           $ldap->cd($cv['base']);
3106           if(!$ldap->dn_exists($dn)){
3107             $ldap->cd($dn);
3108             $ldap->add($data);
3109             if (!$ldap->success()){
3110               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
3111               $success = FALSE;
3112             }
3113           }
3114         }
3116         /* Execute all LDAP-MODIFY actions 
3117          */
3118         foreach($menu['TODO']['MODIFY'] as $dn => $data){
3119           $ldap->cd($cv['base']);
3120           if($ldap->dn_exists($dn)){
3121             $ldap->cd($dn);
3122             $ldap->modify($data);
3123             if (!$ldap->success()){
3124               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
3125               $success = FALSE;
3126             }
3127           }
3128         }
3129   
3130         /* If every action was successful, remove this entry from the list 
3131          */
3132         if($success){
3133           unset($this->menu[$key]);
3134         }
3135       }
3136     }
3138     /* Udpate migration status for application menus
3139      */
3140     $this->check_menus();
3141   }
3144   function migrate_selected_admin_users()
3145   {
3146     /* Updated ui selection */
3147     $this->migrate_users();
3149     /* Establish ldap connection */
3150     $cv = $this->parent->captured_values;
3151     $ldap_l = new LDAP($cv['admin'],
3152         $cv['password'],
3153         $cv['connection'],
3154         FALSE,
3155         $cv['tls']);
3157     $ldap = new ldapMultiplexer($ldap_l);
3158     $ldap->cd($cv['base']);
3160     /* Get current ACL configuration for the ldap base 
3161      */
3162     $ldap->cat($cv['base']);
3163     $base_attrs = $ldap->fetch();
3164     $acl_entries= array();
3165     $acl_id = -1;
3166     if(isset($base_attrs['gosaAclEntry'])){
3167       for($i=0; $i < $base_attrs['gosaAclEntry']['count']; $i ++){
3168         $acl_entries[] = $base_attrs['gosaAclEntry'][$i];
3169         $cur_id = preg_replace("/^([0-9]*):.*$/","\\1",$base_attrs['gosaAclEntry'][$i]);
3170         if($cur_id > $acl_id){
3171           $acl_id = $cur_id;
3172         }
3173       }
3174     }
3176     /* Append ACLs selected in the migrate admin account dialog 
3177      */
3178     foreach($this->migrate_users as $entry){
3179       if($entry['checked']){
3180         $acl_id ++;
3181         $acl_entries[] = $acl_id.$entry['change'];
3182       }
3183     }
3184    
3185     /* Check if the required objectClasses are available 
3186      */
3187     $ocs = array();     
3188     for($i=0;$i< $base_attrs['objectClass']['count']; $i++){
3189       $ocs[] = $base_attrs['objectClass'][$i];
3190     }
3191     if(!in_array("gosaACL",$ocs)){
3192       $ocs[] = "gosaACL";
3193     }
3195     /* Try to write changes 
3196      */
3197     if(count($acl_entries)){
3198       $new_entry['gosaAclEntry'] = $acl_entries;
3199       $new_entry['objectClass'] = $ocs;
3200       $ldap->cd($cv['base']);
3201       $ldap->modify($new_entry);
3202       if(!$ldap->success()){
3203         $this->checks['acls']['TITLE']     = _("Checking for super administrator");
3204         $this->checks['acls']['STATUS']    = FALSE;
3205         $this->checks['acls']['STATUS_MSG']= _("Failed");
3206         $this->checks['acls']['ERROR_MSG'] = "<br>".msgPool::ldaperror($cv['base'],$ldap->get_error(),LDAP_MOD);
3207       }else{
3208         $this->check_administrativeAccount();
3209       }     
3210     }
3211   }
3212   
3214   function migrate_users()
3215   {
3216     /* Collect a list of available GOsa users and groups 
3217      */
3219     /* Establish ldap connection */
3220     $cv = $this->parent->captured_values;
3221     $ldap_l = new LDAP($cv['admin'],
3222         $cv['password'],
3223         $cv['connection'],
3224         FALSE,
3225         $cv['tls']);
3227     $ldap = new ldapMultiplexer($ldap_l);
3228     $ldap->cd($cv['base']);
3230     $users = array();
3231     $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
3232         "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
3233     while($user_attrs = $ldap->fetch()){
3234       $users[$user_attrs['dn']] = $user_attrs['uid'][0];
3235       $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
3236     }
3237     $groups = array();
3238     $ldap->search("objectClass=posixGroup",array("cn","dn"));
3239     while($group_attrs = $ldap->fetch()){
3240       $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
3241     }
3243     foreach($this->migrate_users as $id => $data){
3244       $this->migrate_users[$id]['checked'] = isset($_POST['migrate_admin_'.$id]);
3245     }
3247     /* Try to find an old GOsa 2.5 administrative account that may be migrated
3248      */
3249     if(!count($this->migrate_users)){
3250       $ldap->cat($cv['base']);
3251       $base_data = $ldap->fetch();
3252       $base_entry = "dn: ".$base_data['dn']."\n";
3253       for($i=0;$i<$base_data['objectClass']['count'];$i++){
3254         $base_entry .= "objectClass: ".$base_data['objectClass'][$i]."\n";
3255       }
3256       if(!in_array("gosaACL",$base_data['objectClass'])){
3257         $base_entry .= "<b>objectClass: gosaACL</b>\n";
3258       }
3259       if(isset($base_data['gosaAclEntry'])){
3260         for($i=0;$i<$base_data['gosaAclEntry']['count'];$i++){
3261           $base_entry .= "gosaAclEntry: ".$base_data['gosaAclEntry'][$i]."\n";
3262         }
3263       }
3264       $this->migrate_acl_base_entry = $base_entry;
3265       $ldap->cd($cv['base']);
3266       $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
3267       while($p_group = $ldap->fetch()){
3268         for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
3269           $user = $p_group['memberUid'][$e];
3270           if(isset($rusers[$user])){
3271             $bsp_acl_entry = "gosaAclEntry: #:psub:".base64_encode($rusers[$user]).":all;cmdrw\n";
3272             $entry = array();
3273             $entry['uid'] = $user; 
3274             $entry['dn'] = $rusers[$user]; 
3275             $entry['details'] = $bsp_acl_entry; 
3276             $entry['checked'] = FALSE;
3277             $entry['change'] = ":psub:".base64_encode($rusers[$user]).":all;cmdrw";
3278             $this->migrate_users[] = $entry;
3279           }
3280         }
3281       }
3282     }
3283   }
3285 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
3286 ?>