Code

'Updated ie workaround check
[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   function Step_Migrate()
117   {
118     $this->update_strings(); 
119   }
121   function update_strings()
122   {
123     $this->s_title      = _("LDAP inspection");
124     $this->s_title_long = _("LDAP inspection");
125     $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
126   }
128   function initialize_checks()
129   {
130     $this->checks = array();
131     $this->checks['root']['TITLE']     = _("Checking for root object");
132     $this->checks['root']['STATUS']    = FALSE;
133     $this->checks['root']['STATUS_MSG']= "";
134     $this->checks['root']['ERROR_MSG'] = "";
135     $this->checkBase();
137     $this->checks['permissions']['TITLE']     = _("Checking permissions on LDAP database");
138     $this->checks['permissions']['STATUS']    = FALSE;
139     $this->checks['permissions']['STATUS_MSG']= "";
140     $this->checks['permissions']['ERROR_MSG'] = "";
141     $this->check_ldap_permissions();
143     $this->checks['deps_visible']['TITLE']     = _("Checking for invisible departments");
144     $this->checks['deps_visible']['STATUS']    = FALSE;
145     $this->checks['deps_visible']['STATUS_MSG']= "";
146     $this->checks['deps_visible']['ERROR_MSG'] = "";
148     $this->checks['users_visible']['TITLE']     = _("Checking for invisible users");
149     $this->checks['users_visible']['STATUS']    = FALSE;
150     $this->checks['users_visible']['STATUS_MSG']= "";
151     $this->checks['users_visible']['ERROR_MSG'] = "";
152     $this->check_gosaAccounts();
154     $this->migrate_users = array();
155     $this->checks['acls']['TITLE']     = _("Checking for super administrator");
156     $this->checks['acls']['STATUS']    = FALSE;
157     $this->checks['acls']['STATUS_MSG']= "";
158     $this->checks['acls']['ERROR_MSG'] = "";
159     $this->check_administrativeAccount();
161     $this->checks['outside_users']['TITLE']     = _("Checking for users outside the people tree");
162     $this->checks['outside_users']['STATUS']    = FALSE;
163     $this->checks['outside_users']['STATUS_MSG']= "";
164     $this->checks['outside_users']['ERROR_MSG'] = "";
165     $this->search_outside_users();
167     $this->checks['outside_groups']['TITLE']     = _("Checking for groups outside the groups tree");
168     $this->checks['outside_groups']['STATUS']    = FALSE;
169     $this->checks['outside_groups']['STATUS_MSG']= "";
170     $this->checks['outside_groups']['ERROR_MSG'] = "";
171     $this->search_outside_groups();
172     $this->check_organizationalUnits();
174     $this->checks['outside_winstations']['TITLE']     = _("Checking for windows workstations outside the winstation tree");
175     $this->checks['outside_winstations']['STATUS']    = FALSE;
176     $this->checks['outside_winstations']['STATUS_MSG']= "";
177     $this->checks['outside_winstations']['ERROR_MSG'] = "";
178     $this->search_outside_winstations();
180     $this->checks['uidNumber_usage']['TITLE']     = _("Checking for duplicated UID numbers");
181     $this->checks['uidNumber_usage']['STATUS']    = FALSE;
182     $this->checks['uidNumber_usage']['STATUS_MSG']= "";
183     $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
184     $this->check_uidNumber();
186     $this->checks['gidNumber_usage']['TITLE']     = _("Checking for duplicate GID numbers");
187     $this->checks['gidNumber_usage']['STATUS']    = FALSE;
188     $this->checks['gidNumber_usage']['STATUS_MSG']= "";
189     $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
190     $this->check_gidNumber();
192     $this->checks['old_style_devices']['TITLE']     = _("Checking for old style USB devices");
193     $this->checks['old_style_devices']['STATUS']    = FALSE;
194     $this->checks['old_style_devices']['STATUS_MSG']= "";
195     $this->checks['old_style_devices']['ERROR_MSG'] = "";
196     $this->check_usb_devices();
198     $this->checks['old_style_services']['TITLE']     = _("Checking for old services that have to be migrated");
199     $this->checks['old_style_services']['STATUS']    = FALSE;
200     $this->checks['old_style_services']['STATUS_MSG']= "";
201     $this->checks['old_style_services']['ERROR_MSG'] = "";
202     $this->check_services();
204     $this->checks['old_style_menus']['TITLE']     = _("Checking for old style application menus");
205     $this->checks['old_style_menus']['STATUS']    = FALSE;
206     $this->checks['old_style_menus']['STATUS_MSG']= "";
207     $this->checks['old_style_menus']['ERROR_MSG'] = "";
208     $this->check_menus();
209   }
212   /* Check if there are uidNumbers which are used more than once. 
213    */
214   function check_uidNumber()
215   {
216     /* Establish ldap connection */
217     $cv = $this->parent->captured_values;
218     $ldap_l = new LDAP($cv['admin'],
219         $cv['password'],
220         $cv['connection'],
221         FALSE,
222         $cv['tls']);
224     $ldap = new ldapMultiplexer($ldap_l);
226     $ldap->cd($cv['base']);
227     $res = $ldap->search("(&(objectClass=posixAccount)(uidNumber=*))",array("dn","uidNumber"));
228     if(!$res){
229       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
230       $this->checks['uidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
231       $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
232       return(false);
233     }
235     $this->check_uidNumbers= array(); 
236     $tmp = array();
237     while($attrs = $ldap->fetch()){
238       $tmp[$attrs['uidNumber'][0]][] = $attrs;
239     }
241     foreach($tmp as $id => $entries){
242       if(count($entries) > 1){
243         foreach($entries as $entry){
244           $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
245         }
246       }
247     }
249     if($this->check_uidNumbers){
250       $this->checks['uidNumber_usage']['STATUS']    = FALSE;
251       $this->checks['uidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
252       $this->checks['uidNumber_usage']['ERROR_MSG'] =
253         sprintf(_("Found %s duplicate values for attribute 'uidNumber'."),count($this->check_uidNumbers));
254       return(false);
255     }else{
256       $this->checks['uidNumber_usage']['STATUS']    = TRUE;
257       $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
258       $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
259       return(TRUE);
260     }
261   }
263   
264   /* Check if there are duplicated gidNumbers present in ldap
265    */
266   function check_gidNumber()
267   {
268     /* Establish ldap connection */
269     $cv = $this->parent->captured_values;
270     $ldap_l = new LDAP($cv['admin'],
271         $cv['password'],
272         $cv['connection'],
273         FALSE,
274         $cv['tls']);
276     $ldap = new ldapMultiplexer($ldap_l);
278     $ldap->cd($cv['base']);
279     $res = $ldap->search("(&(objectClass=posixGroup)(gidNumber=*))",array("dn","gidNumber"));
280     if(!$res){
281       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
282       $this->checks['gidNumber_usage']['STATUS_MSG']= _("LDAP query failed");
283       $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
284       return(false);
285     }
287     $this->check_gidNumbers= array(); 
288     $tmp = array();
289     while($attrs = $ldap->fetch()){
290       $tmp[$attrs['gidNumber'][0]][] = $attrs;
291     }
293     foreach($tmp as $id => $entries){
294       if(count($entries) > 1){
295         foreach($entries as $entry){
296           $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
297         }
298       }
299     }
301     if($this->check_gidNumbers){
302       $this->checks['gidNumber_usage']['STATUS']    = FALSE;
303       $this->checks['gidNumber_usage']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
304       $this->checks['gidNumber_usage']['ERROR_MSG'] =
305         sprintf(_("Found %s duplicate values for attribute 'gidNumber'."),count($this->check_gidNumbers));
306       return(false);
307     }else{
308       $this->checks['gidNumber_usage']['STATUS']    = TRUE;
309       $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
310       $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
311       return(TRUE);
312     }
313   }
316   /* Search for winstations outside the winstation ou 
317    */
318   function search_outside_winstations()
319   {
320     /* Establish ldap connection */
321     $cv = $this->parent->captured_values;
322     $ldap_l = new LDAP($cv['admin'],
323         $cv['password'],
324         $cv['connection'],
325         FALSE,
326         $cv['tls']);
328     $ldap = new ldapMultiplexer($ldap_l);
330     /* Get winstation ou */
331     if($cv['generic_settings']['wws_ou_active']) {
332       $winstation_ou = $cv['generic_settings']['wws_ou'];
333     }else{
334       $winstation_ou = "ou=winstations";
335     }
337     if($cv['samba_version'] == 3){
338       $oc = "sambaSamAccount";
339     }else{
340       $oc = "sambaAccount";
341     }
342  
343     $ldap->cd($cv['base']);
344     $res = $ldap->search("(&(objectClass=".$oc.")(uid=*$))",array("dn","sambaSID"));
345     if(!$res){
346       $this->checks['outside_winstations']['STATUS']    = FALSE;
347       $this->checks['outside_winstations']['STATUS_MSG']= _("LDAP query failed");
348       $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
349       return(false);
350     }
352     $this->outside_winstations = array();
353     while($attrs = $ldap->fetch()){
354       if((!preg_match("/^[^,]+,".preg_quote($winstation_ou, '/')."/",$attrs['dn'])) && !preg_match("/,dc=addressbook,/",$attrs['dn'])){
355         $attrs['selected'] = FALSE;
356         $attrs['ldif']     = "";
357         $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
358       }
359     }
361     if(count($this->outside_winstations)){
362       $this->checks['outside_winstations']['STATUS']    = FALSE;
363       $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
364       $this->checks['outside_winstations']['ERROR_MSG'] = 
365         sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
366       $this->checks['outside_winstations']['ERROR_MSG'].= "<input type='submit' name='outside_winstations_dialog' value='"._("Migrate")."...'>";
367       return(false);
368     }else{
369       $this->checks['outside_winstations']['STATUS']    = TRUE;
370       $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
371       $this->checks['outside_winstations']['ERROR_MSG'] = "";
372       return(TRUE);
373     }
374   }
377   /* Search for groups outside the group ou 
378    */
379   function search_outside_groups()
380   {
381     /* Establish ldap connection */
382     $cv = $this->parent->captured_values;
383     $ldap_l = new LDAP($cv['admin'],
384         $cv['password'],
385         $cv['connection'],
386         FALSE,
387         $cv['tls']);
389     $ldap = new ldapMultiplexer($ldap_l);
391     $group_ou = $cv['groupou'];
392     $ldap->cd($cv['base']);
394     /***********
395      * Get all gosaDepartments to be able to
396      *  validate correct ldap tree position of every single user
397      ***********/
398     $valid_deps = array();
399     $valid_deps['/'] = $cv['base'];
400     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
401     while($attrs = $ldap->fetch()){
402       $valid_deps[] = $attrs['dn'];
403     }
405     /***********
406      * Get all groups
407      ***********/
408     $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
409     if(!$res){
410       $this->checks['outside_groups']['STATUS']    = FALSE;
411       $this->checks['outside_groups']['STATUS_MSG']= _("LDAP query failed");
412       $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
413       return(false);
414     }
416     $this->outside_groups = array();
417     $this->groups_list = array();;
418     while($attrs = $ldap->fetch()){
419       $group_db_base = preg_replace("/^[^,]+,".preg_quote($group_ou, '/')."+,/i","",$attrs['dn']);
421       /* Check if entry is not an addressbook only user
422        *  and verify that he is in a valid department
423        */
424       if( !preg_match("/".preg_quote("dc=addressbook,", '/')."/",$group_db_base) &&
425           !in_array($group_db_base,$valid_deps)
426         ){
427         $attrs['selected'] = FALSE;
428         $attrs['ldif']     = "";
429         $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
430       }
431       $this->group_list[] = $attrs['dn'];
432     }
434     if(count($this->outside_groups)){
435       $this->checks['outside_groups']['STATUS']    = FALSE;
436       $this->checks['outside_groups']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
437       $this->checks['outside_groups']['ERROR_MSG'] =
438         sprintf(_("Found %s groups outside the configured tree '%s'."),count($this->outside_groups),$group_ou);
439       $this->checks['outside_groups']['ERROR_MSG'].= "&nbsp;<input type='submit' name='outside_groups_dialog' value='"._("Move")."...'>";
440       return(false);
441     }else{
442       $this->checks['outside_groups']['STATUS']    = TRUE;
443       $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
444       $this->checks['outside_groups']['ERROR_MSG'] = "";
445       return(TRUE);
446     }
447   }
449  /* Search for users outside the people ou
450    */
451   function search_outside_users()
452   {
453     /* Establish ldap connection */
454     $cv = $this->parent->captured_values;
455     $ldap_l = new LDAP($cv['admin'],
456         $cv['password'],
457         $cv['connection'],
458         FALSE,
459         $cv['tls']);
461     $ldap = new ldapMultiplexer($ldap_l);
462     $ldap->cd($cv['base']);
465     /***********
466      * Get all gosaDepartments to be able to
467      *  validate correct ldap tree position of every single user
468      ***********/
469     $valid_deps = array();
470     $valid_deps['/'] = $cv['base'];
471     $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn","ou"));
472     while($attrs = $ldap->fetch()){
473       $valid_deps[] = $attrs['dn'];
474     }
476     /***********
477      * Search for all users
478      ***********/
479     $res = $ldap->search("(&(objectClass=gosaAccount)(!(uid=*$)))",array("dn"));
480     if(!$res){
481       $this->checks['outside_users']['STATUS']    = FALSE;
482       $this->checks['outside_users']['STATUS_MSG']= _("LDAP query failed");
483       $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
484       return(false);
485     }
487     /***********
488      * Check if returned users are within a valid GOsa deparmtment. (peopleou,gosaDepartment,base)
489      ***********/
490     $this->outside_users = array();
491     $people_ou = trim($cv['peopleou']);
492     if(!empty($people_ou)){
493       $people_ou = $people_ou.",";
494     }
496     while($attrs = $ldap->fetch()){
497       $people_db_base = preg_replace("/^[^,]+,".preg_quote($people_ou, '/')."/i","",$attrs['dn']);
499       /* Check if entry is not an addressbook only user
500        *  and verify that he is in a valid department
501        */
502       if( !preg_match("/dc=addressbook,/",$people_db_base) &&
503           !in_array($people_db_base,$valid_deps)
504          ){
505         $attrs['selected'] = FALSE;
506         $attrs['ldif']     = "";
507         $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
508       }
509     }
511     if(count($this->outside_users)){
512       $this->checks['outside_users']['STATUS']    = FALSE;
513       $this->checks['outside_users']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
514       $this->checks['outside_users']['ERROR_MSG'] =
515         sprintf(_("Found %s user(s) outside the configured tree '%s'."),count($this->outside_users),$people_ou);
516       $this->checks['outside_users']['ERROR_MSG'].= "<input type='submit' name='outside_users_dialog' value='"._("Move")."...'>";
517       return(false);
518     }else{
519       $this->checks['outside_users']['STATUS']    = TRUE;
520       $this->checks['outside_users']['STATUS_MSG']= _("Ok");
521       $this->checks['outside_users']['ERROR_MSG'] = "";
522       return(TRUE);
523     }
524   }
527   /* Check ldap accessibility 
528    * Create and remove a dummy object, 
529    *  to ensure that we have the necessary permissions
530    */
531   function check_ldap_permissions()
532   {
533     /* Establish ldap connection */
534     $cv = $this->parent->captured_values;
535     $ldap_l = new LDAP($cv['admin'],
536         $cv['password'],
537         $cv['connection'],
538         FALSE,
539         $cv['tls']);
541     $ldap = new ldapMultiplexer($ldap_l);
543     /* Create dummy entry 
544      */
545     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
546     $dn       = "ou=".$name.",".$cv['base'];
547     $testEntry= array();
548     $testEntry['objectClass'][]= "top";
549     $testEntry['objectClass'][]= "organizationalUnit";
550     $testEntry['objectClass'][]= "gosaDepartment";
551     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
552     $testEntry['ou']  = $name;
554     /* check if simple ldap cat will be successful 
555      */
556     $res = $ldap->cat($cv['base']);  
557     if(!$res){
558       $this->checks['permissions']['STATUS']    = FALSE;
559       $this->checks['permissions']['STATUS_MSG']= _("LDAP query failed");
560       $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
561       return(false);
562     }
563   
564     /* Try to create dummy object 
565      */ 
566     $ldap->cd ($dn);
567     $ldap->create_missing_trees($dn);
568     $res = $ldap->add($testEntry);
569     $ldap->cat($dn);
570     if(!$ldap->count()){
571       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
573       $this->checks['permissions']['STATUS']    = FALSE;
574       $this->checks['permissions']['STATUS_MSG']= _("Failed");
575       $this->checks['permissions']['ERROR_MSG'] = 
576         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
577       return(false);
578     }
580     /* Try to remove created entry 
581      */
582     $res = $ldap->rmDir($dn);
583     $ldap->cat($dn);
584     if($ldap->count()){
585       new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
586       $this->checks['permissions']['STATUS']    = FALSE;
587       $this->checks['permissions']['STATUS_MSG']= _("Failed");
588       $this->checks['permissions']['ERROR_MSG'] = 
589         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
590       return(false);
591     }
593     /* Create & remove of dummy object was successful */
594     $this->checks['permissions']['STATUS']    = TRUE;
595     $this->checks['permissions']['STATUS_MSG']= _("Ok");
596     $this->checks['permissions']['ERROR_MSG'] = "";
597     return(true);
598   } 
601   /* Check if there are users which will 
602    *  be invisible for GOsa 
603    */
604   function check_gosaAccounts()
605   {
606     /* Remember old list of ivisible users, to be able to set 
607      *  the 'html checked' status for the checkboxes again 
608      */
609     $cnt_ok = 0;
610     $old    = $this->users_to_migrate;
611     $this->users_to_migrate = array();
613     /* Establish ldap connection */
614     $cv = $this->parent->captured_values;
615     $ldap_l = new LDAP($cv['admin'],
616         $cv['password'],
617         $cv['connection'],
618         FALSE,
619         $cv['tls']);
621     $ldap = new ldapMultiplexer($ldap_l);
623     /* Get all invisible users 
624      */
625     $ldap->cd($cv['base']); 
626     $res =$ldap->search("(&(|(objectClass=posixAccount)(&(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))(!(objectClass=gosaAccount))(uid=*))",array("sn","givenName","cn","uid"));
627     while($attrs = $ldap->fetch()){
628       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
629         $attrs['checked'] = FALSE;
630         $attrs['before']  = "";
631         $attrs['after']   = "";
633         /* Set objects to selected, that were selected before reload */
634         if(isset($old[base64_encode($attrs['dn'])])){
635           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
636         }
637         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
638       }
639     }
641     /* No invisible */
642     if(!$res){
643       $this->checks['users_visible']['STATUS']    = FALSE;
644       $this->checks['users_visible']['STATUS_MSG']= _("LDAP query failed");
645       $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
646     }elseif(count($this->users_to_migrate) == 0){
647       $this->checks['users_visible']['STATUS']    = TRUE;
648       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
649       $this->checks['users_visible']['ERROR_MSG'] = "";
650     }else{
651       $this->checks['users_visible']['STATUS']    = FALSE;
652       $this->checks['users_visible']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
653       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s user(s) that will not be visible in GOsa."), 
654           count($this->users_to_migrate));
655       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."...'>";
656     }
657   }
660   /* Start user account migration 
661    */  
662   function migrate_gosaAccounts($only_ldif = FALSE)
663   {
664     $this->show_details= $only_ldif;
666     /* Establish ldap connection */
667     $cv = $this->parent->captured_values;
668     $ldap_l = new LDAP($cv['admin'],
669         $cv['password'],
670         $cv['connection'],
671         FALSE,
672         $cv['tls']);
674     $ldap = new ldapMultiplexer($ldap_l);
676     /* Add gosaAccount objectClass to the selected users  
677      */
678     foreach($this->users_to_migrate as $key => $dep){
679       if($dep['checked']){
681         /* Get old objectClasses */
682         $ldap->cat($dep['dn'],array("objectClass"));
683         $attrs      = $ldap->fetch();
685         /* Create new objectClass array */
686         $new_attrs  = array();
687         $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson","person");
688         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
689           if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
690             $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
691           }
692         }
694         /* Set info attributes for current object, 
695          *  or write changes to the ldap database 
696          */
697         if($only_ldif){
698           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
699           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
700         }else{
701           $ldap->cd($attrs['dn']);
702           if(!$ldap->modify($new_attrs)){
703             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']),$ldap->get_error()), ERROR_DIALOG);
704             return(false);
705           }
706         }
707       }
708     }
709     return(TRUE);
710   }
713   /* Check if there are invisible organizational Units 
714    */
715   function check_organizationalUnits()
716   {
717     $cnt_ok = 0;
718     $old = $this->deps_to_migrate;
719     $this->deps_to_migrate = array();
721     /* Establish ldap connection */
722     $cv = $this->parent->captured_values;
723     $ldap_l = new LDAP($cv['admin'],
724         $cv['password'],
725         $cv['connection'],
726         FALSE,
727         $cv['tls']);
729     $ldap = new ldapMultiplexer($ldap_l);
731     /* Skip GOsa internal departments */
732     $skip_dns = array("/".$cv['peopleou']."/","/".$cv['groupou']."/","/^ou=people,/","/^ou=groups,/","/^ou=sudoers,/",
733         "/(,|)ou=configs,/","/(,|)ou=systems,/",
734         "/(,|)ou=apps,/","/(,|)ou=mime,/","/(,|)ou=devices/","/^ou=aclroles,/","/^ou=incoming,/",
735         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
736         "/(,|)ou=winstations,/");
738     /* Get all invisible departments */
739     $ldap->cd($cv['base']); 
740     $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
741     while($attrs = $ldap->fetch()){
742       $attrs['checked'] = FALSE;
743       $attrs['before']  = "";
744       $attrs['after']   = "";
746       /* Set objects to selected, that were selected before reload */
747       if(isset($old[base64_encode($attrs['dn'])])){
748         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
749       }
750       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
751     }
753     /* Filter returned list of departments and ensure that 
754      *  GOsa internal departments will not be listed 
755      */
756     foreach($this->deps_to_migrate as $key => $attrs){
757       $dn = $attrs['dn'];
758       $skip = false;;
760       /* Check if this object is an application release object
761           e.g. groups-> application menus.
762        */
763       if(preg_match("/^.*,[ ]*cn=/",$dn)){
764         $cn_dn = preg_replace("/^.*,[ ]*cn=/","cn=",$dn);
765         if(in_array($cn_dn,$this->group_list)){
766           $skip = true;
767         }
768       }
769     
770       foreach($skip_dns as $skip_dn){
771         if(preg_match($skip_dn,$dn)){
772           $skip = true;
773         }
774       }
775       if($skip){
776         unset($this->deps_to_migrate[$key]);
777       }
778     }
780     /* If we have no invisible departments found  
781      *  tell the user that everything is ok 
782      */
783     if(!$res){
784       $this->checks['deps_visible']['STATUS']    = FALSE;
785       $this->checks['deps_visible']['STATUS_MSG']= _("LDAP query failed");
786       $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
787     }elseif(count($this->deps_to_migrate) == 0 ){
788       $this->checks['deps_visible']['STATUS']    = TRUE;
789       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
790       $this->checks['deps_visible']['ERROR_MSG'] = "";
791     }else{
792       $this->checks['deps_visible']['STATUS']    = TRUE;
793       $this->checks['deps_visible']['STATUS_MSG']= '<font style="color:#FFA500">'._("Warning").'</font>';
794       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s department(s) that will not be visible in GOsa."),count($this->deps_to_migrate));
795       $this->checks['deps_visible']['ERROR_MSG'] .= "&nbsp;<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."...'>";
796     }
797   }
801   /* Start deparmtment migration */  
802   function migrate_organizationalUnits($only_ldif = FALSE)
803   {
804     $this->show_details= $only_ldif;
806     /* Establish ldap connection */
807     $cv = $this->parent->captured_values;
808     $ldap_l = new LDAP($cv['admin'],
809         $cv['password'],
810         $cv['connection'],
811         FALSE,
812         $cv['tls']);
814     $ldap = new ldapMultiplexer($ldap_l);
816     /* Add gosaDepartment objectClass to each selected entry 
817      */
818     foreach($this->deps_to_migrate as $key => $dep){
819       if($dep['checked']){
821         /* Get current objectClasses */
822         $ldap->cat($dep['dn'],array("objectClass","description"));
823         $attrs      = $ldap->fetch();
825         /* Create new objectClass attribute including gosaDepartment*/
826         $new_attrs  = array();
827         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
828           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
829         }
830         $new_attrs['objectClass'][] = "gosaDepartment";
832         /* Append description it is missing */
833         if(!isset($attrs['description'])){
834           $new_attrs['description'][] = "GOsa department";
835         }
837         /* Depending on the parameter >only_diff< we save the changes as ldif
838          *  or we write our changes directly to the ldap database
839          */
840         if($only_ldif){
841           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
842           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
843         }else{
844           $ldap->cd($attrs['dn']);
845           if(!$ldap->modify($new_attrs)){
846             msg_dialog::display(_("Migration error"), sprintf(_("Cannot migrate department '%s':")."<br><br><i>%s</i>",LDAP::fix($attrs['dn']), $ldap->get_error()), ERROR_DIALOG);
847             return(false);
848           }
849         }
850       }
851     }
852     return(TRUE);
853   }
856   /* Check Acls if there is at least one object with acls defined 
857    */
858   function check_administrativeAccount()
859   {
860     /* Reset settings 
861      */ 
862     $this->migrate_users = array();
863     $this->acl_migrate_dialog = FALSE;
864     $this->migrate_acl_base_entry  = "";
866     /* Establish ldap connection */
867     $cv = $this->parent->captured_values;
868     $ldap_l = new LDAP($cv['admin'],
869         $cv['password'],
870         $cv['connection'],
871         FALSE,
872         $cv['tls']);
874     $ldap = new ldapMultiplexer($ldap_l);
875     $ldap->cd($cv['base']);
876     $res = $ldap->cat($cv['base']);
877     
878     if(!$res){
879       $this->checks['acls']['STATUS']    = FALSE;
880       $this->checks['acls']['STATUS_MSG']= _("LDAP query failed");
881       $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
882     }else{
883       $GOsa_26_found = false; // GOsa 2.6 Account found
884       $GOsa_25_found = false; // GOsa 2.5 Account found, allow migration
886       $username = "";
887       $attrs = $ldap->fetch();
889       /* Collect a list of available GOsa users and groups 
890        */
891       $users = array();
892       $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
893         "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
894       while($user_attrs = $ldap->fetch()){
895         $users[$user_attrs['dn']] = $user_attrs['uid'][0];
896         $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
897       }
898       $groups = array();
899       $ldap->search("objectClass=posixGroup",array("cn","dn"));
900       while($group_attrs = $ldap->fetch()){
901         $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
902       }
903       
904       /* Check if a valid GOsa 2.6 admin exists 
905           -> gosaAclEntry for an existing and accessible user.
906        */
907       $valid_users = "";
908       $valid_groups = "";
909       if(isset($attrs['gosaAclEntry'])){
910         $acls = $attrs['gosaAclEntry'];
911         for($i = 0 ; $i < $acls['count'] ; $i++){
912           $acl = $acls[$i];
913           $tmp = split(":",$acl);
915           if($tmp[1] == "psub"){
916             $members = split(",",$tmp[2]);
917             foreach($members as $member){
918               $member = base64_decode($member);
919               if(isset($users[$member])){
920                 if(preg_match("/all;cmdrw/i",$tmp[3])){
921                   $valid_users .= $users[$member].", ";
922                   $GOsa_26_found  = TRUE;
923                 }
924               }
925               if(isset($groups[$member])){
926                 if(preg_match("/all;cmdrw/i",$tmp[3])){
927                   $ldap->cat($member);
928                   $group_attrs = $ldap->fetch();
929                   $val_users = "";
930                   if(isset($group_attrs['memberUid'])){
931                     for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
932                       if(isset($rusers[$group_attrs['memberUid'][$e]])){
933                         $val_users .= $group_attrs['memberUid'][$e].", ";
934                       }
935                     }
936                   }
937                   if(!empty($val_users)){
938                     $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
939                     $GOsa_26_found  = TRUE;
940                   }
941                 }
942               }
943             }
944           }elseif($tmp[1] == "role"){
946             /* Check if acl owner is a valid GOsa user account */
947             $ldap->cat(base64_decode($tmp[2]),array("gosaAclTemplate"));
948             $ret = $ldap->fetch();
950             if(isset($ret['gosaAclTemplate'])){
951               $cnt = $ret['gosaAclTemplate']['count'];
952               for($e = 0 ; $e < $cnt ; $e++){
954                 $a_str = $ret['gosaAclTemplate'][$e];
955                 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all;cmdrw$/",$a_str)){
957                   $members = split(",",$tmp[3]);
958                   foreach($members as $member){
959                     $member = base64_decode($member);
961                     if(isset($users[$member])){
962                       $valid_users .= $users[$member].", ";
963                       $GOsa_26_found  = TRUE;
964                     }
965                     if(isset($groups[$member])){
966                       $ldap->cat($member);
967                       $group_attrs = $ldap->fetch();
968                       $val_users = "";
969                       if(isset($group_attrs['memberUid'])){
970                         for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
971                           if(isset($rusers[$group_attrs['memberUid'][$e]])){
972                             $val_users .= $group_attrs['memberUid'][$e].", ";
973                           }
974                         }
975                       }
976                       if(!empty($val_users)){
977                         $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
978                         $GOsa_26_found  = TRUE;
979                       }
980                     }
981                   }
982                 }
983               }
984             }
985           }
986         }
987       }
989       /* Try to find an old GOsa 2.5 administrative account that may be migrated 
990        */
991       if(!$GOsa_26_found){
992         $valid_users = "";
993         $valid_groups = "";
994         $ldap->cd($cv['base']);
995         $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
996         while($p_group = $ldap->fetch()){
997           $val_users = "";
998           for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
999             $user = $p_group['memberUid'][$e];
1000             if(isset($rusers[$user])){
1001               $val_users .= $user.", ";
1002             }  
1003           }
1004           if(!empty($val_users)){
1005             $valid_groups .= $groups[$p_group['dn']]."(<i>".trim($val_users,", ")."</i>), ";
1006             $GOsa_25_found  = TRUE;
1007           }
1008         }
1009       }
1012       /* Print out results 
1013        */
1014       if($GOsa_25_found){
1015         $str = "";
1016         if(!empty($valid_groups)){
1017           $str.= "<i>".sprintf(_("GOsa 2.5 adminitrative accounts found: %s."),trim($valid_groups,", "))."</i><br>";
1018         }
1019         $this->checks['acls']['STATUS']    = FALSE;
1020         $this->checks['acls']['STATUS_MSG']= _("Failed");
1021         $this->checks['acls']['ERROR_MSG'] = $str;
1022         $this->checks['acls']['ERROR_MSG'].= _("There is no valid GOsa 2.6 administrator account inside your LDAP.")."&nbsp;";
1023         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='migrate_acls' value='"._("Migrate")."'>";
1024         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
1025       }elseif($GOsa_26_found){
1026         $str = "";
1027         if(!empty($valid_users)){
1028           $str.= "<b>"._("Users")."</b>:&nbsp;".trim($valid_users,", ")."<br>";
1029         }
1030         if(!empty($valid_groups)){
1031           $str.= "<b>"._("Groups")."</b>:&nbsp;".trim($valid_groups,", ")."<br>";
1032         }
1033         $this->checks['acls']['STATUS']    = TRUE;
1034         $this->checks['acls']['STATUS_MSG']= _("Ok");
1035         $this->checks['acls']['ERROR_MSG'] = $str;
1036       }else{
1037         $this->checks['acls']['STATUS']    = FALSE;
1038         $this->checks['acls']['STATUS_MSG']= _("Failed");
1039         $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")."&nbsp;";
1040         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
1041       }
1042     }
1043     return($GOsa_26_found);
1044   }
1048   function create_admin($only_ldif = FALSE)
1049   {
1050     /* Reset '' */
1051     $this->acl_create_changes="";
1053     /* Object that should receive admin acls */
1054     $dn = $this->acl_create_selected;
1056     /* Get collected configuration settings */
1057     $cv = $this->parent->captured_values;
1059     /* On first call check for rid/sid base */
1060     $ldap_l = new LDAP($cv['admin'],
1061         $cv['password'],
1062         $cv['connection'],
1063         FALSE,
1064         $cv['tls']);
1066     $ldap = new ldapMultiplexer($ldap_l);
1068     /* Get current base attributes */
1069     $ldap->cd($cv['base']);
1070     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
1071     $attrs = $ldap->fetch();
1073     /* Add acls for the selcted user to the base */
1074     $attrs_new = array();
1075     $attrs_new['objectClass'] = array("gosaACL");
1077     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
1078       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
1079         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
1080       }
1081     }
1083     $acl = "0:psub:".base64_encode($dn).":all;cmdrw";    
1084     $attrs_new['gosaAclEntry'][] = $acl;
1085     if(isset($attrs['gosaAclEntry'])){
1086       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
1087           
1088         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
1089         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
1090  
1091         $data = ($prio+1).$rest;
1092         $attrs_new['gosaAclEntry'][] = $data;
1093       }
1094     }
1096     if($only_ldif){
1097       $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
1098       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
1099       $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
1100       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
1101     }else{
1102    
1103       $ldap->cd($cv['base']);
1104       if(!$ldap->modify($attrs_new)){
1105         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);
1106         return(FALSE);
1107       }else{
1108         return(TRUE);
1109       }
1110     }
1111   }
1112  
1113   
1114   function create_admin_user()
1115   {
1116     $pw1 = $pw2 = "";
1117     $uid = "";
1119     /* On first call check for rid/sid base */
1120     $cv = $this->parent->captured_values;
1121     $ldap_l = new LDAP($cv['admin'],
1122         $cv['password'],
1123         $cv['connection'],
1124         FALSE,
1125         $cv['tls']);
1127     $ldap = new ldapMultiplexer($ldap_l);
1128   
1129     if(isset($_POST['new_user_uid'])){
1130       $uid = $_POST['new_user_uid'];
1131     }
1132     if(isset($_POST['new_user_password'])){
1133       $pw1 = $_POST['new_user_password'];
1134     }
1135     if(isset($_POST['new_user_password2'])){
1136       $pw2 = $_POST['new_user_password2'];
1137     }
1138   
1139     
1140     $ldap->cd($cv['base']);
1141     $ldap->search("(uid=".$uid.")");
1142     if($ldap->count()){
1143       msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
1144       return false;
1145     }
1146     
1147     if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
1148       msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
1149       return false;
1150     }
1151  
1152     if(!tests::is_uid($uid) || empty($uid)){
1153       msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
1154       return false;
1155     }
1156  
1157  
1158     /* Get current base attributes */
1159     $ldap->cd($cv['base']);
1160   
1161     $people_ou = trim($cv['peopleou']);
1162     if(!empty($people_ou)){
1163       $people_ou = trim($people_ou).",";
1164     }
1166     if($cv['peopledn'] == "cn"){
1167       $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
1168     }else{
1169       $dn = "uid=".$uid.",".$people_ou.$cv['base'];
1170     }
1172     $hash = passwordMethod::make_hash($pw2, $cv['encryption']);
1174     $new_user=array();
1175     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
1176     $new_user['givenName']  = "System";
1177     $new_user['sn']  = "Administrator";
1178     $new_user['cn']  = "System Administrator-".$uid;
1179     $new_user['uid'] = $uid;
1180     $new_user['userPassword'] = $hash;
1181    
1182     $ldap->cd($cv['base']);
1183   
1184     $ldap->cat($dn,array("dn"));
1185     if($ldap->count()){
1186       msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
1187       return(FALSE);  
1188     }
1190     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
1191     $ldap->cd($dn);  
1192     $res = $ldap->add($new_user);
1193     $this->acl_create_selected = $dn;
1194     $this->create_admin();
1195     
1196     if(!$res){
1197       msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
1198       return(FALSE);
1199     }
1200   
1201     $this->acl_create_dialog=FALSE;        
1202     $this->check_administrativeAccount();
1203     return(TRUE);
1204   }
1205  
1207   function migrate_outside_winstations($perform = FALSE)
1208   {
1209     /* Establish ldap connection */
1210     $cv = $this->parent->captured_values;
1211     $ldap_l = new LDAP($cv['admin'],
1212         $cv['password'],
1213         $cv['connection'],
1214         FALSE,
1215         $cv['tls']);
1217     $ldap = new ldapMultiplexer($ldap_l);
1219     $ldap->cd($cv['base']);
1221     /* Check if there was a destination department posted */
1222     if(isset($_POST['move_winstation_to'])){
1223       $destination_dep = $_POST['move_winstation_to'];
1224     }else{
1225       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1226       return(false);
1227     }
1228  
1229     foreach($this->outside_winstations as $b_dn => $data){
1230       $this->outside_winstations[$b_dn]['ldif'] ="";
1231       if($data['selected']){
1232         $dn = base64_decode($b_dn);
1233         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1234         if(!$perform){
1235           $this->outside_winstations[$b_dn]['ldif'] = _("Winstation will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1238           /* Check if there are references to this object */
1239           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1240           $refs = "";
1241           while($attrs = $ldap->fetch()){
1242             $ref_dn = $attrs['dn'];
1243             $refs .= "<br />\t".$ref_dn;
1244           } 
1245           if(!empty($refs)){ 
1246             $this->outside_winstations[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1247           }
1249         }else{
1250           $this->move($dn,$d_dn);
1251         }
1252       }
1253     }
1254   }
1255   
1257   function migrate_outside_groups($perform = FALSE)
1258   {
1259     /* Establish ldap connection */
1260     $cv = $this->parent->captured_values;
1261     $ldap_l = new LDAP($cv['admin'],
1262         $cv['password'],
1263         $cv['connection'],
1264         FALSE,
1265         $cv['tls']);
1267     $ldap = new ldapMultiplexer($ldap_l);
1268     $ldap->cd($cv['base']);
1270     /* Check if there was a destination department posted */
1271     if(isset($_POST['move_group_to'])){
1272       $destination_dep = $_POST['move_group_to'];
1273     }else{
1274       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1275       return(false);
1276     }
1277  
1278     foreach($this->outside_groups as $b_dn => $data){
1279       $this->outside_groups[$b_dn]['ldif'] ="";
1280       if($data['selected']){
1281         $dn = base64_decode($b_dn);
1282         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1283         if(!$perform){
1285           $this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1287           /* Check if there are references to this object */
1288           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1289           $refs = "";
1290           while($attrs = $ldap->fetch()){
1291             $ref_dn = $attrs['dn'];
1292             $refs .= "<br />\t".$ref_dn;
1293           } 
1294           if(!empty($refs)){ 
1295             $this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1296           }
1298         }else{
1299           $this->move($dn,$d_dn);
1300         }
1301       }
1302     }
1303   }
1304   
1306   function migrate_outside_users($perform = FALSE)
1307   {
1308     /* Establish ldap connection */
1309     $cv = $this->parent->captured_values;
1310     $ldap_l = new LDAP($cv['admin'],
1311         $cv['password'],
1312         $cv['connection'],
1313         FALSE,
1314         $cv['tls']);
1316     $ldap = new ldapMultiplexer($ldap_l);
1317     $ldap->cd($cv['base']);
1319     /* Check if there was a destination department posted */
1320     if(isset($_POST['move_user_to'])){
1321       $destination_dep = $_POST['move_user_to'];
1322     }else{
1323       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1324       return(false);
1325     }
1326       
1327     foreach($this->outside_users as $b_dn => $data){
1328       $this->outside_users[$b_dn]['ldif'] ="";
1329       if($data['selected']){
1330         $dn = base64_decode($b_dn);
1331         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1332         if(!$perform){
1333           $this->outside_users[$b_dn]['ldif'] = _("User will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1335           /* Check if there are references to this object */
1336           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1337           $refs = "";
1338           while($attrs = $ldap->fetch()){
1339             $ref_dn = $attrs['dn'];
1340             $refs .= "<br />\t".$ref_dn;
1341           } 
1342           if(!empty($refs)){ 
1343             $this->outside_users[$b_dn]['ldif'] .= "<br /><br /><i>"._("The following references will be updated").":</i>".$refs;
1344           }
1346         }else{
1347           $this->move($dn,$d_dn);
1348         }
1349       }
1350     }
1351   }
1352   
1354   function execute()
1355   {
1356     /* Initialise checks if this is the first call */
1357     if(!$this->checks_initialised || isset($_POST['reload'])){
1358       $this->initialize_checks();
1359       $this->checks_initialised = TRUE;
1360     }
1362     /*************
1363      * Winstations outside the group ou 
1364      *************/
1365     
1366     if(isset($_POST['outside_winstations_dialog_cancel'])){
1367       $this->outside_winstations_dialog = FALSE;
1368       $this->dialog = FALSE;
1369       $this->show_details = FALSE;
1370     }
1371    
1372     if(isset($_POST['outside_winstations_dialog_whats_done'])){
1373       $this->migrate_outside_winstations(FALSE);
1374     }
1375  
1376     if(isset($_POST['outside_winstations_dialog_perform'])){
1377       $this->migrate_outside_winstations(TRUE);
1378       $this->search_outside_winstations();
1379       $this->dialog = FALSE;
1380       $this->show_details = FALSE;
1381       $this->outside_winstations_dialog = FALSE;
1382     }
1384     if(isset($_POST['outside_winstations_dialog'])){
1385       $this->outside_winstations_dialog = TRUE;
1386       $this->dialog = TRUE;
1387     }
1388     
1389     if($this->outside_winstations_dialog){
1391       /* Fix displayed dn syntax */ 
1392       $tmp = $this->outside_winstations;
1393       foreach($tmp as $key => $data){
1394         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1395       }
1397       $smarty = get_smarty();
1398       $smarty->assign("ous",$this->get_all_winstation_ous());
1399       $smarty->assign("method","outside_winstations");
1400       $smarty->assign("outside_winstations",$tmp);
1401       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1402     }
1403     /*************
1404      * Groups outside the group ou 
1405      *************/
1406     
1407     if(isset($_POST['outside_groups_dialog_cancel'])){
1408       $this->outside_groups_dialog = FALSE;
1409       $this->show_details = FALSE;
1410       $this->dialog = FALSE;
1411     }
1412    
1413     if(isset($_POST['outside_groups_dialog_whats_done'])){
1414       $this->show_details= TRUE;
1415       $this->migrate_outside_groups(FALSE);
1416     }
1417  
1418     if(isset($_POST['outside_groups_dialog_refresh'])){
1419       $this->show_details= FALSE;
1420     }
1422     if(isset($_POST['outside_groups_dialog_perform'])){
1423       $this->migrate_outside_groups(TRUE);
1424       $this->dialog = FALSE;
1425       $this->show_details = FALSE;
1426       $this->outside_groups_dialog = FALSE;
1427       $this->initialize_checks();
1428     }
1430     if(isset($_POST['outside_groups_dialog'])){
1431       $this->outside_groups_dialog = TRUE;
1432       $this->dialog = TRUE;
1433     }
1434     
1435     if($this->outside_groups_dialog){
1437       /* Fix displayed dn syntax */ 
1438       $tmp = $this->outside_groups;
1439       foreach($tmp as $key => $data){
1440         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1441       }
1443       $smarty = get_smarty();
1444       $smarty->assign("ous",$this->get_all_group_ous());
1445       $smarty->assign("method","outside_groups");
1446       $smarty->assign("outside_groups",$tmp);
1447       $smarty->assign("group_details", $this->show_details);
1448       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1449     }
1450  
1451     /*************
1452      * User outside the people ou 
1453      *************/
1454     
1455     if(isset($_POST['outside_users_dialog_cancel'])){
1456       $this->outside_users_dialog = FALSE;
1457       $this->dialog = FALSE;
1458       $this->show_details = FALSE;
1459     }
1460    
1461     if(isset($_POST['outside_users_dialog_whats_done'])){
1462       $this->show_details= TRUE;
1463       $this->migrate_outside_users(FALSE);
1464     }
1465  
1466     if(isset($_POST['outside_users_dialog_perform'])){
1467       $this->migrate_outside_users(TRUE);
1468       $this->initialize_checks();
1469       $this->dialog = FALSE;
1470       $this->show_details = FALSE;
1471       $this->outside_users_dialog = FALSE;
1472     }
1474     if (isset($_POST['outside_users_dialog_refresh'])){
1475       $this->show_details= FALSE;
1476     }
1478     if(isset($_POST['outside_users_dialog'])){
1479       $this->outside_users_dialog = TRUE;
1480       $this->dialog = TRUE;
1481     }
1482     
1483     if($this->outside_users_dialog){
1485       /* Fix displayed dn syntax */ 
1486       $tmp = $this->outside_users;
1487       foreach($tmp as $key => $data){
1488         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1489       }
1491       $smarty = get_smarty();
1492       $smarty->assign("ous",$this->get_all_people_ous());
1493       $smarty->assign("method","outside_users");
1494       $smarty->assign("outside_users",$tmp);
1495       $smarty->assign("user_details", $this->show_details);
1496       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1497     }
1498  
1499     /*************
1500      * Root object check  
1501      *************/
1502   
1503     if(isset($_POST['retry_root_create'])){
1505       $state = $this->checks['root']['STATUS'];
1506       $this->checkBase(FALSE);
1507       if($state != $this->checks['root']['STATUS']){
1508         $this->initialize_checks();
1509       }
1510     }
1511  
1512     /*************
1513      * Administrative Account -- Migrate/Create 
1514      *************/
1516     if(isset($_POST['retry_acls'])){
1517       $this->check_administrativeAccount();
1518     }
1520     /* Dialog handling */
1521     if(isset($_POST['create_acls'])){
1522       $this->acl_create_dialog = TRUE;
1523       $this->dialog = TRUE;
1524     }
1526     if(isset($_POST['migrate_acls'])){
1527       $this->acl_migrate_dialog = TRUE;
1528       $this->dialog = TRUE;
1529     }
1530   
1531     if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
1532       $this->acl_create_dialog = FALSE;
1533       $this->acl_migrate_dialog = FALSE;
1534       $this->dialog = FALSE;
1535       $this->show_details = FALSE;
1536     }
1538     /* Account creation */
1539     if(isset($_POST['create_acls_create'])){
1540       $this->create_admin(TRUE);
1541     }
1543     if(isset($_POST['create_admin_user'])){
1544       if($this->create_admin_user()){
1545         $this->dialog = FALSE;
1546       $this->show_details = FALSE;
1547       }
1548     }
1550     /* Add admin acls for the selected users to the ldap base.
1551      */
1552     if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
1554       /* Update ldap and reload check infos 
1555        */
1556       $this->migrate_selected_admin_users();
1558     }elseif($this->acl_migrate_dialog){
1560       /* Display admin migration dialog.
1561        */
1562       $this->migrate_users();
1563       $smarty = get_smarty();
1565       /* Do we have to display the changes
1566        */
1567       $details = isset($_POST['details']) && $_POST['details'];
1568       if(isset($_POST['migrate_acls_show_changes'])){
1569         $details = TRUE;
1570       }elseif(isset($_POST['migrate_acls_hide_changes'])){
1571         $details = FALSE;
1572       }
1574       $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
1575       $smarty->assign("details", $details);
1576       $smarty->assign("method","migrate_acls");
1577       $smarty->assign("migrateable_users",$this->migrate_users);
1578       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1579     }
1581     if($this->acl_create_dialog){
1582       $smarty = get_smarty();
1583       $uid = "admin";
1584       if(isset($_POST['new_user_uid'])){
1585         $uid = $_POST['new_user_uid'];
1586       }
1587       $smarty->assign("new_user_uid",$uid);
1588       $smarty->assign("new_user_password",@$_POST['new_user_password']);
1589       $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
1590       $smarty->assign("method","create_acls");
1591       $smarty->assign("acl_create_selected",$this->acl_create_selected);
1592       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
1593       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1594     }
1596     /*************
1597      * User Migration handling 
1598      *************/
1600     /* Refresh list of deparments */
1601     if(isset($_POST['users_visible_migrate_refresh'])){
1602       $this->check_gosaAccounts();
1603     }
1605     /* Open migration dialog */
1606     if(isset($_POST['users_visible_migrate'])){
1607       $this->show_details= FALSE;
1608       $this->users_migration_dialog = TRUE;
1609       $this->dialog =TRUE;
1610     }
1612     /* Close migration dialog */
1613     if(isset($_POST['users_visible_migrate_close'])){
1614       $this->users_migration_dialog = FALSE;
1615       $this->dialog =FALSE;
1616       $this->show_details = FALSE;
1617     }
1619     /* Start migration */
1620     if(isset($_POST['users_visible_migrate_migrate'])){
1621       if($this->migrate_gosaAccounts()){
1622         $this->initialize_checks();
1623         $this->dialog = FALSE;
1624         $this->show_details = FALSE;
1625         $this->users_migration_dialog = FALSE;
1626       }
1627     }
1629     /* Start migration */
1630     if(isset($_POST['users_visible_migrate_whatsdone'])){
1631       $this->migrate_gosaAccounts(TRUE);
1632     }
1634     /* Display migration dialog */
1635     if($this->users_migration_dialog){
1637       /* Fix displayed dn syntax */ 
1638       $tmp = $this->users_to_migrate;
1639       foreach($tmp as $key => $data){
1640         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1641       }
1643       $smarty = get_smarty();
1644       $smarty->assign("users_to_migrate",$tmp);
1645       $smarty->assign("method","migrate_users");
1646       $smarty->assign("user_details", $this->show_details);
1647       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1648     }
1651     /*************
1652      * Department Migration handling 
1653      *************/
1655     /* Refresh list of deparments */
1656     if(isset($_POST['deps_visible_migrate_refresh'])){
1657       $this->check_organizationalUnits();
1658       $this->show_details= FALSE;
1659     }
1661     /* Open migration dialog */
1662     if(isset($_POST['deps_visible_migrate'])){
1663       $this->dep_migration_dialog = TRUE;
1664       $this->dialog =TRUE;
1665     }
1667     /* Close migration dialog */
1668     if(isset($_POST['deps_visible_migrate_close'])){
1669       $this->dep_migration_dialog = FALSE;
1670       $this->dialog =FALSE;
1671       $this->show_details = FALSE;
1672     }
1674     /* Start migration */
1675     if(isset($_POST['deps_visible_migrate_migrate'])){
1676       if($this->migrate_organizationalUnits()){
1677         $this->show_details= FALSE;
1678         $this->check_organizationalUnits();
1679         $this->dialog = FALSE;
1680         $this->dep_migration_dialog = FALSE;
1681       }
1682     }
1684     /* Start migration */
1685     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1686       $this->migrate_organizationalUnits(TRUE);
1687     }
1689     /* Display migration dialog */
1690     if($this->dep_migration_dialog){
1691       $smarty = get_smarty();
1692    
1693       /* Fix displayed dn syntax */ 
1694       $tmp = $this->deps_to_migrate;
1695       foreach($tmp as $key => $data){
1696         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1697       }
1699       $smarty->assign("deps_to_migrate",$tmp);
1700       $smarty->assign("method","migrate_deps");
1701       $smarty->assign("deps_details", $this->show_details);
1702       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1703     }
1706     /*************
1707      * Device migration 
1708      *************/
1709    
1710     if($this->device_dialog) {
1711       $this->check_device_posts();
1712     }
1713  
1714     if(isset($_POST['device_dialog_cancel'])){
1715       $this->device_dialog = FALSE;
1716       $this->show_details = FALSE;
1717       $this->dialog = FALSE;
1718     }
1719    
1720     if(isset($_POST['device_dialog_whats_done'])){
1721       $this->show_details= TRUE;
1722     }
1723  
1724     if(isset($_POST['device_dialog_refresh'])){
1725       $this->show_details= FALSE;
1726     }
1728     if(isset($_POST['migrate_devices'])){
1729       $this->migrate_usb_devices();
1730 #      $this->dialog = FALSE;
1731  #     $this->show_details = FALSE;
1732   #    $this->device_dialog = FALSE;
1733    #   $this->initialize_checks();
1734     }
1736     if(isset($_POST['device_dialog'])){
1737       $this->device_dialog = TRUE;
1738       $this->dialog = TRUE;
1739     }
1740     
1741     if($this->device_dialog){
1742       $smarty = get_smarty();
1743       $smarty->assign("method","devices");
1744       $smarty->assign("devices",$this->device);
1745       $smarty->assign("device_details", $this->show_details);
1746       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1747     }
1750     /*************
1751      * Service migration 
1752      *************/
1753    
1754     if($this->service_dialog) {
1755       $this->check_service_posts();
1756     }
1757  
1758     if(isset($_POST['service_dialog_cancel'])){
1759       $this->service_dialog = FALSE;
1760       $this->show_details = FALSE;
1761       $this->dialog = FALSE;
1762     }
1763    
1764     if(isset($_POST['service_dialog_whats_done'])){
1765       $this->show_details= TRUE;
1766     }
1767  
1768     if(isset($_POST['service_dialog_refresh'])){
1769       $this->show_details= FALSE;
1770     }
1772     if(isset($_POST['migrate_services'])){
1773       $this->migrate_services();
1774 #      $this->dialog = FALSE;
1775  #     $this->show_details = FALSE;
1776   #    $this->service_dialog = FALSE;
1777    #   $this->initialize_checks();
1778     }
1780     if(isset($_POST['service_dialog'])){
1781       $this->service_dialog = TRUE;
1782       $this->dialog = TRUE;
1783     }
1784     
1785     if($this->service_dialog){
1786       $smarty = get_smarty();
1787       $smarty->assign("method","services");
1788       $smarty->assign("services",$this->service);
1789       $smarty->assign("service_details", $this->show_details);
1790       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1791     }
1794     /*************
1795      * Menu migration 
1796      *************/
1797    
1798     if($this->menu_dialog) {
1799       $this->check_menu_posts();
1800     }
1801  
1802     if(isset($_POST['menu_dialog_cancel'])){
1803       $this->menu_dialog = FALSE;
1804       $this->show_details = FALSE;
1805       $this->dialog = FALSE;
1806     }
1807    
1808     if(isset($_POST['menu_dialog_whats_done'])){
1809       $this->show_details= TRUE;
1810     }
1811  
1812     if(isset($_POST['menu_dialog_refresh'])){
1813       $this->show_details= FALSE;
1814     }
1816     if(isset($_POST['migrate_menus'])){
1817       $this->migrate_menus();
1818 #      $this->dialog = FALSE;
1819  #     $this->show_details = FALSE;
1820   #    $this->menu_dialog = FALSE;
1821    #   $this->initialize_checks();
1822     }
1824     if(isset($_POST['menu_dialog'])){
1825       $this->menu_dialog = TRUE;
1826       $this->dialog = TRUE;
1827     }
1828     
1829     if($this->menu_dialog){
1830       $smarty = get_smarty();
1831       $smarty->assign("method","menus");
1832       $smarty->assign("menus",$this->menu);
1833       $smarty->assign("menu_details", $this->show_details);
1834       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1835     }
1837     $smarty = get_smarty();
1838     $smarty->assign("checks",$this->checks);
1839     $smarty->assign("method","default");
1840     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1841   }
1844   function save_object()
1845   {
1846     $this->is_completed= TRUE;
1848     /* Capture all selected winstations from outside_winstations_dialog */
1849     if($this->outside_winstations_dialog){
1850       foreach($this->outside_winstations as $dn => $data){
1851         if(isset($_POST['select_winstation_'.$dn])){
1852           $this->outside_winstations[$dn]['selected'] = TRUE;
1853         }else{
1854           $this->outside_winstations[$dn]['selected'] = FALSE;
1855         }
1856       }
1857     }
1859     /* Capture all selected groups from outside_groups_dialog */
1860     if($this->outside_groups_dialog){
1861       foreach($this->outside_groups as $dn => $data){
1862         if(isset($_POST['select_group_'.$dn])){
1863           $this->outside_groups[$dn]['selected'] = TRUE;
1864         }else{
1865           $this->outside_groups[$dn]['selected'] = FALSE;
1866         }
1867       }
1868     }
1870     /* Capture all selected users from outside_users_dialog */
1871     if($this->outside_users_dialog){
1872       foreach($this->outside_users as $dn => $data){
1873         if(isset($_POST['select_user_'.$dn])){
1874           $this->outside_users[$dn]['selected'] = TRUE;
1875         }else{
1876           $this->outside_users[$dn]['selected'] = FALSE;
1877         }
1878       }
1879     }
1881     /* Get "create acl" dialog posts */
1882     if($this->acl_create_dialog){
1884       if(isset($_POST['create_acls_create_abort'])){
1885         $this->acl_create_selected = "";
1886       }
1887     }
1889     /* Get selected departments */
1890     if($this->dep_migration_dialog){
1891       foreach($this->deps_to_migrate as $id => $data){
1892         if(isset($_POST['migrate_'.$id])){
1893           $this->deps_to_migrate[$id]['checked'] = TRUE;
1894         }else{
1895           $this->deps_to_migrate[$id]['checked'] = FALSE;
1896         }
1897       }
1898     }
1900     /* Get selected users */
1901     if($this->users_migration_dialog){
1902       foreach($this->users_to_migrate as $id => $data){
1903         if(isset($_POST['migrate_'.$id])){
1904           $this->users_to_migrate[$id]['checked'] = TRUE;
1905         }else{
1906           $this->users_to_migrate[$id]['checked'] = FALSE;
1907         }
1908       }
1909     }
1910   }
1913   /* Check if the root object exists.
1914    * If the parameter just_check is true, then just check if the 
1915    *  root object is missing and update the info messages.
1916    * If the Parameter is false, try to create a new root object.
1917    */
1918   function checkBase($just_check = TRUE)
1919   {
1920     /* Establish ldap connection */
1921     $cv = $this->parent->captured_values;
1922     $ldap_l = new LDAP($cv['admin'],
1923         $cv['password'],
1924         $cv['connection'],
1925         FALSE,
1926         $cv['tls']);
1928     $ldap = new ldapMultiplexer($ldap_l);
1930     /* Check if root object exists */
1931     $ldap->cd($cv['base']);
1932     $ldap->set_size_limit(1);
1933     $res = $ldap->search("(objectClass=*)");
1934     $ldap->set_size_limit(0);
1935     $err = ldap_errno($ldap->cid); 
1937     if( !$res || 
1938         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1939         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1941       /* Root object doesn't exists 
1942        */
1943       if($just_check){
1944         $this->checks['root']['STATUS']    = FALSE;
1945         $this->checks['root']['STATUS_MSG']= _("Failed");
1946         $this->checks['root']['ERROR_MSG'] =  _("The LDAP root object is missing. It is required to use your LDAP service.").'&nbsp;';
1947         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1948         return(FALSE);
1949       }else{
1951         /* Add root object */ 
1952         $ldap->cd($cv['base']);
1953         $res = $ldap->create_missing_trees($cv['base']);
1955         /* If adding failed, tell the user */
1956         if(!$res){
1957           $this->checks['root']['STATUS']    = FALSE;
1958           $this->checks['root']['STATUS_MSG']= _("Failed");
1959           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1960           $this->checks['root']['ERROR_MSG'].= "&nbsp;<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1961           return($res);;
1962         }
1963       }
1964     }
1966     /* Create & remove of dummy object was successful */
1967     $this->checks['root']['STATUS']    = TRUE;
1968     $this->checks['root']['STATUS_MSG']= _("Ok");
1969   }
1972   /* Return ldif information for a 
1973    * given attribute array 
1974    */
1975   function array_to_ldif($atts)
1976   {
1977     $ret = "";
1978     unset($atts['count']);
1979     unset($atts['dn']);
1980     foreach($atts as $name => $value){
1981       if(is_numeric($name)) {
1982         continue;
1983       }
1984       if(is_array($value)){
1985         unset($value['count']);
1986         foreach($value as $a_val){
1987           $ret .= $name.": ". $a_val."\n";
1988         }
1989       }else{
1990         $ret .= $name.": ". $value."\n";
1991       }
1992     }
1993     return(preg_replace("/\n$/","",$ret));
1994   }
1997   function get_user_list()
1998   {
1999     /* Establish ldap connection */
2000     $cv = $this->parent->captured_values;
2001     $ldap_l = new LDAP($cv['admin'],
2002         $cv['password'],
2003         $cv['connection'],
2004         FALSE,
2005         $cv['tls']);
2007     $ldap = new ldapMultiplexer($ldap_l);
2008     $ldap->cd($cv['base']);
2009     $ldap->search("(objectClass=gosaAccount)",array("dn"));
2010   
2011     $tmp = array();
2012     while($attrs = $ldap->fetch()){
2013       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2014     }
2015     return($tmp);
2016   }
2019  function get_all_people_ous()
2020   {
2021     /* Get collected configuration settings */
2022     $cv = $this->parent->captured_values;
2023     $people_ou = trim($cv['peopleou']);
2025     /* Establish ldap connection */
2026     $cv = $this->parent->captured_values;
2027     $ldap_l = new LDAP($cv['admin'],
2028         $cv['password'],
2029         $cv['connection'],
2030         FALSE,
2031         $cv['tls']);
2033     $ldap = new ldapMultiplexer($ldap_l);
2035     /*****************
2036      * If people ou is NOT empty
2037      * search for for all objects matching the given container
2038      *****************/
2039     if(!empty($people_ou)){
2040       $ldap->search("(".$people_ou.")",array("dn"));
2042       /* Create people ou if there is currently none */
2043       if($ldap->count() == 0 ){
2044         $add_dn = $cv['peopleou'].",".$cv['base'];
2045         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2046         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2047         $add = array();
2048         $add['objectClass'] = array("organizationalUnit");
2049         $add[$naming_attr] = $naming_value;
2050         $ldap->cd($cv['base']);
2051         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2052         $ldap->cd($add_dn);
2053         $ldap->add($add);
2054       }
2056       /* Create result */
2057       $ldap->search("(".$cv['peopleou'].")",array("dn"));
2058       $tmp = array();
2059       while($attrs= $ldap->fetch()){
2060         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2061           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2062         }
2063       }
2064     } else{
2066       /************
2067        * If people ou is empty
2068        * Get all valid gosaDepartments
2069        ************/
2070       $ldap->cd($cv['base']);
2071       $tmp = array();
2072       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2073       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2074       while($attrs = $ldap->fetch()){
2075         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2076       }
2077     }
2078     return($tmp);
2079   }
2082   function get_all_winstation_ous()
2083   {
2084     /* Establish ldap connection */
2085     $cv = $this->parent->captured_values;
2086     $ldap_l = new LDAP($cv['admin'],
2087         $cv['password'],
2088         $cv['connection'],
2089         FALSE,
2090         $cv['tls']);
2092     $ldap = new ldapMultiplexer($ldap_l);
2094     /* Get winstation ou */
2095     if($cv['generic_settings']['wws_ou_active']) {
2096       $winstation_ou = $cv['generic_settings']['wws_ou'];
2097     }else{
2098       $winstation_ou = "ou=winstations";
2099     }
2101     $ldap->cd($cv['base']);
2102     $ldap->search("(".$winstation_ou.")",array("dn"));
2103   
2104     if($ldap->count() == 0 ){
2105       $add_dn = $winstation_ou.",ou=systems,".$cv['base'];
2106       $naming_attr = preg_replace("/=.*$/","",$add_dn);
2107       $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2108       $add = array();
2109       $add['objectClass'] = array("organizationalUnit");
2110       $add[$naming_attr] = $naming_value;
2112       $ldap->cd($cv['base']);
2113       $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2114       $ldap->cd($add_dn);
2115       $ldap->add($add);
2116     }
2118     $ldap->search("(".$winstation_ou.")",array("dn"));
2119     $tmp = array();
2120     while($attrs= $ldap->fetch()){
2121       if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2122         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2123       }
2124     }
2125     return($tmp); 
2126   }
2129  function get_all_group_ous()
2130   {
2131     /* Establish ldap connection */
2132     $cv = $this->parent->captured_values;
2133     $ldap_l = new LDAP($cv['admin'],
2134         $cv['password'],
2135         $cv['connection'],
2136         FALSE,
2137         $cv['tls']);
2139     $ldap = new ldapMultiplexer($ldap_l);
2141     $group_ou = trim($cv['groupou']);
2142     if(!empty($group_ou)){
2143       $group_ou = trim($group_ou);
2144     }
2146     /************
2147      * If group ou is NOT empty
2148      * Get all valid group ous, create one if necessary
2149      ************/
2150     $ldap->cd($cv['base']);
2151     if(!empty($group_ou)){
2152       $ldap->search("(".$group_ou.")",array("dn"));
2153       if($ldap->count() == 0 ){
2154         $add_dn = $group_ou.$cv['base'];
2155         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2156         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2157         $add = array();
2158         $add['objectClass'] = array("organizationalUnit");
2159         $add[$naming_attr] = $naming_value;
2161         $ldap->cd($cv['base']);
2162         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2163         $ldap->cd($add_dn);
2164         $ldap->add($add);
2165       }
2166       $ldap->search("(".$group_ou.")",array("dn"));
2167       $tmp = array();
2168       while($attrs= $ldap->fetch()){
2169         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2170           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2171         }
2172       }
2173     }else{
2174       /************
2175        * If group ou is empty
2176        * Get all valid gosaDepartments
2177        ************/
2178       $ldap->cd($cv['base']);
2179       $tmp = array();
2180       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2181       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2182       while($attrs = $ldap->fetch()){
2183         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2184       }
2185     }
2186     return($tmp);
2187   }
2190   function get_group_list()
2191   {
2192     /* Establish ldap connection */
2193     $cv = $this->parent->captured_values;
2194     $ldap_l = new LDAP($cv['admin'],
2195         $cv['password'],
2196         $cv['connection'],
2197         FALSE,
2198         $cv['tls']);
2200     $ldap = new ldapMultiplexer($ldap_l);
2201     
2202     $ldap->cd($cv['base']);
2203     $ldap->search("(objectClass=posixGroup)",array("dn"));
2204   
2205     $tmp = array();
2206     while($attrs = $ldap->fetch()){
2207       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2208     }
2209     return($tmp);
2210   }
2213   function move($source,$destination)
2214   {
2215     /* Establish ldap connection */
2216     $cv = $this->parent->captured_values;
2217     $ldap_l = new LDAP($cv['admin'],
2218         $cv['password'],
2219         $cv['connection'],
2220         FALSE,
2221         $cv['tls']);
2223     $ldap = new ldapMultiplexer($ldap_l);
2225      /* Update object references in gosaGroupOfNames */
2226     $ogs_to_fix = array();
2227     $ldap->cd($cv['base']);
2228     $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($source).'))', array('cn','member'));
2229     while ($attrs= $ldap->fetch()){
2230       $dn = $attrs['dn'];
2231       $attrs = $this->cleanup_array($attrs);
2232       $member_new = array($destination);
2233       foreach($attrs['member'] as $member){
2234         if($member != $source){
2235           $member_new[] = $member;
2236         }
2237       }
2238       $attrs['member'] = $member_new;
2239       $ogs_to_fix[$dn] = $attrs;
2240     }
2242     /* Copy source to destination dn */
2243     $ldap->cat($source);
2244     $new_data = $this->cleanup_array($ldap->fetch());
2245     $ldap->cd($destination);
2246     $res = $ldap->add($new_data);
2248     /* Display warning if copy failed */
2249     if(!$res){
2250       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);
2251     }else{
2252       $res = $ldap->rmDir($source);
2253       if (!$ldap->success()){
2254         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_DEL, get_class()));
2255       }
2257       /* Object is copied, so update its references */
2258       foreach($ogs_to_fix as $dn => $data){
2259         $ldap->cd($dn);
2260         $ldap->modify($data);
2261       }
2262     }
2263   }
2266   /* Cleanup ldap result to be able to write it be to ldap */
2267   function cleanup_array($attrs)
2268   {
2269     foreach($attrs as $key => $value) {
2270       if(is_numeric($key) || in_array($key,array("count","dn"))){
2271         unset($attrs[$key]);
2272       }
2273       if(is_array($value) && isset($value['count'])){
2274         unset($attrs[$key]['count']);
2275       }
2276     }
2277     return($attrs);
2278   }
2281   /*! \brief  Act in posts from the device migration dialog 
2282    */
2283   function check_device_posts()
2284   {
2285     foreach($this->device as $key => $device){
2286       if(isset($_POST["migrate_".$key])){
2287         $this->device[$key]['DETAILS'] =TRUE;
2288       }else{
2289         $this->device[$key]['DETAILS'] =FALSE;
2290       }
2291     }
2292   }
2295   /*! \brief  Check for old style (gosa-2.5) devices.
2296               Save readable informations and a list of migratable devices 
2297                in $this->devices.
2298    */
2299   function check_usb_devices ()
2300   {
2301     /* Establish ldap connection */
2302     $cv = $this->parent->captured_values;
2303     $ldap_l = new LDAP($cv['admin'],
2304         $cv['password'],
2305         $cv['connection'],
2306         FALSE,
2307         $cv['tls']);
2309     $ldap = new ldapMultiplexer($ldap_l);
2310     $ldap->cd($cv['base']);
2311     $res = $ldap->search("(&(|(objectClass=posixAccount)(objectClass=posixGroup))(gotoHotplugDevice=*))",
2312         array("cn","gotoHotplugDevice","gosaUnitTag"));
2314     if(!$res){
2315       $this->checks['old_style_devices']['STATUS']    = FALSE;
2316       $this->checks['old_style_devices']['STATUS_MSG']= _("LDAP query failed");
2317       $this->checks['old_style_devices']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2318       return;
2319     }
2322     /* If adding failed, tell the user */
2323     if($ldap->count()){
2324   
2325       $this->device = array();
2326       while($attrs = $ldap->fetch()){
2328         for ($j= 0; $j < $attrs['gotoHotplugDevice']['count']; $j++){
2330           $after  = "";
2331           $current= "";
2333           $entry= $attrs['gotoHotplugDevice'][$j];
2335           @list($name,$desc,$serial,$vendor,$product) = explode('|', $entry);
2336   
2337           $add = 1;
2338           $new_name  = $name;
2339           while(isset($dest[$new_name])){
2340             $new_name = $name."_".$add;
2341             $add ++;
2342           }
2343           $name = $new_name;
2344           $newdn= "cn=$name,ou=devices,".preg_replace('/^[^,]+,/', '', $attrs['dn']);
2346           if (!isset($dest[$name])){
2347             $dest[$name]= $newdn;
2349             $current.= "dn: ".$attrs['dn']."\n"; 
2350     
2351             for ($c= 0; $c < $attrs['gotoHotplugDevice']['count']; $c++){
2352               if($c == $j){
2353                 $current.= "<b>gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."</b>\n"; 
2354               }else{
2355                 $current.= "gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."\n"; 
2356               }
2357             }
2359             $after.= "dn: $newdn\n";
2360             $after.= "changetype: add\n";
2361             $after.= "objectClass: top\n";
2362             $after.= "objectClass: gotoDevice\n";
2363             if (isset($attrs['gosaunittag'][0])){
2364               $after.= "objectClass: gosaAdminiafter\n";
2365               $after.= "gosaUnitTag: ".$attrs['gosaunittag'][0]."\n";
2366             }
2367             $after.= "cn: $name\n";
2368             $after.= "gotoHotplugDevice: $desc|$serial|$vendor|$product\n\n";
2370             $this->device[] = array(
2371                 'CURRENT'     =>  $current,
2372                 'AFTER'       => $after,
2373                 'OLD_DEVICE'  => $entry,
2374                 'DN'          => $attrs['dn'],
2375                 'NEW_DN'      => $newdn,
2376                 'DEVICE_NAME' => $name,
2377                 'DETAILS'     => FALSE);
2378           }
2379         }
2380       }
2382       $this->checks['old_style_devices']['STATUS']    = FALSE;
2383       $this->checks['old_style_devices']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2384       $this->checks['old_style_devices']['ERROR_MSG'] = 
2385         sprintf(_("There are %s devices that need to be migrated."),count($this->device)).
2386           "<input type='submit' name='device_dialog' value='"._("Migrate")."'>";
2387     }else{
2388       $this->checks['old_style_devices']['STATUS']    = TRUE;
2389       $this->checks['old_style_devices']['STATUS_MSG']= _("Ok");
2390       $this->checks['old_style_devices']['ERROR_MSG'] = "";
2391     }
2392   }
2395   /*! \brief  Migrate all selected devices. 
2396               Execute all required ldap actions to migrate the 
2397                selected devices.
2398    */
2399   function migrate_usb_devices ()
2400   {
2401     /* Establish ldap connection */
2402     $cv = $this->parent->captured_values;
2403     $ldap_l = new LDAP($cv['admin'],
2404         $cv['password'],
2405         $cv['connection'],
2406         FALSE,
2407         $cv['tls']);
2409     $ldap = new ldapMultiplexer($ldap_l);
2411     /* Walk through migrateable devices and initiate migration for all 
2412         devices that are checked (DETAILS==TRUE) 
2413      */
2414     foreach($this->device as $key => $device){
2415       if($device['DETAILS']){
2417         /* Get source object and verify that the specified device is a 
2418             member attribute of it. 
2419          */
2420         $ldap->cd($cv['base']);
2421         $ldap->cat($device['DN']);
2422         $attrs = $ldap->fetch();
2423         if(in_array($device['OLD_DEVICE'],$attrs['gotoHotplugDevice'])){
2425           /* Create new hotplug device object 'gotoDevice'
2426            */ 
2427           @list($name,$desc,$serial,$vendor,$product) = explode('|', $device['OLD_DEVICE']);    
2428           $newdn = $device['NEW_DN'];
2429           $new_attr = array();
2430           $new_attr['cn'] = $device['DEVICE_NAME'];
2431           $new_attr['objectClass'] = array('top','gotoDevice');
2432           $new_attr['gotoHotplugDevice'] = "$desc|$serial|$vendor|$product";
2434           /* Add new object 
2435            */
2436           $ldap->cd($cv['base']);
2437           $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$newdn));
2438           $ldap->cd($newdn);
2439           $ldap->add($new_attr);
2441           /* Throw an error message if the action failed. 
2442            */
2443           if(!$ldap->success()){
2444             msg_dialog::display(_("LDAP error"), 
2445                 sprintf(_("Adding '%s' to the LDAP failed: %s"),
2446                   "<b>".LDAP::fix($newdn)."</b>", 
2447                   "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
2448           }else{
2450             /* Remove old style device definition from source object. 
2451              */
2452             $update['gotoHotplugDevice'] = array();
2453             for($i = 0 ; $i < $attrs['gotoHotplugDevice']['count'] ; $i++){
2454               if($attrs['gotoHotplugDevice'][$i] == $device['OLD_DEVICE']){
2455                  continue;
2456               }
2457               $update['gotoHotplugDevice'][] = $attrs['gotoHotplugDevice'][$i];
2458             }
2460             $ldap->cd($device['DN']);
2461             $ldap->modify($update);
2462             $ldap->cat($device['DN'],array("gotoHotplugDevice"));
2463             if(!$ldap->success()){
2464               msg_dialog::display(_("LDAP error"), 
2465                   sprintf(_("Updating '%s' failed: %s"),
2466                     "<b>".LDAP::fix($device['DN'])."</b>", 
2467                     "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2468             }else{
2469               unset($this->device[$key]);
2470             }
2471           }
2472         }
2473       }
2474     }
2475     $this->check_usb_devices();
2476   }
2479   /*! \brief  Check for old style (gosa-2.5) services that have to be migrated
2480                to be useable in gosa-2.6.
2481               All required changes are stored in $this->service, also some
2482                readable informations describing the actions required 
2483                to migrate the service
2484    */
2485   function check_services()
2486   {
2487     /* Establish ldap connection */
2488     $cv = $this->parent->captured_values;
2489     $ldap_l = new LDAP($cv['admin'],
2490         $cv['password'],
2491         $cv['connection'],
2492         FALSE,
2493         $cv['tls']);
2495     $ldap = new ldapMultiplexer($ldap_l);
2496     $this->service = array();
2498     /* Check for Ldap services that must be migrated 
2499      */ 
2500     $ldap->cd($cv['base']);
2501     $res = $ldap->search("(objectClass=goLdapServer)", array("goLdapBase", "cn"));
2503     /* Check if we were able to query the ldap server 
2504      */
2505     if(!$res){
2506       $this->checks['old_style_services']['STATUS']    = FALSE;
2507       $this->checks['old_style_services']['STATUS_MSG']= _("LDAP query failed");
2508       $this->checks['old_style_services']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2509       return;
2510     }
2512     /* Walk through each configured ldap server 
2513         and check if it is configured correctly.
2514      */
2515     while($attrs = $ldap->fetch()){
2516       $dn= $attrs['dn'];
2517       $uri= $attrs['goLdapBase'][0];
2518       if (! preg_match("!^ldaps?://!", $uri)){
2519         $this->service[] = array(
2520             "TYPE"    => "modify" , 
2521             "DN"      => $dn, 
2522             "DETAILS" => FALSE, 
2523             "ATTRS"   => array("goLdapBase" => "ldap://".$attrs['cn'][0]."/$uri"),
2524             "CURRENT" => "goLdapBase: ".$uri,
2525             "AFTER"   => "goLdapBase: "."ldap://".$attrs['cn'][0]."/$uri");
2526       }
2527     }
2529     /* Other sevices following here later ...maybe
2530      */
2532     /*  Update status message
2533      */
2534     if(count($this->service)){
2535       $this->checks['old_style_services']['STATUS']    = FALSE;
2536       $this->checks['old_style_services']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2537       $this->checks['old_style_services']['ERROR_MSG'] =
2538         sprintf(_("There are %s services that need to be migrated."),
2539             count($this->service)).
2540         "<input type='submit' name='service_dialog' value='"._("Migrate")."'>";
2541     }else{
2542       $this->checks['old_style_services']['STATUS']    = TRUE;
2543       $this->checks['old_style_services']['STATUS_MSG']= _("Ok");
2544       $this->checks['old_style_services']['ERROR_MSG'] = "";
2545     }
2546   }
2549   
2550   /*! \brief  Migrate selected services.
2551               This function executes the commands collected by the 
2552                service_check() function.
2553    */
2554   function migrate_services()
2555   {
2556     /* Establish ldap connection 
2557      */
2558     $cv = $this->parent->captured_values;
2559     $ldap_l = new LDAP($cv['admin'],
2560         $cv['password'],
2561         $cv['connection'],
2562         FALSE,
2563         $cv['tls']);
2565     $ldap = new ldapMultiplexer($ldap_l);
2567     /* Handle each service 
2568      */
2569     foreach($this->service as $key => $service){
2570       if($service['DETAILS']){
2572         /* Handle modify requests 
2573          */
2574         if($service['TYPE'] == "modify"){
2575           $ldap->cd($service['DN']);
2576           $ldap->modify($service['ATTRS']);
2578           /* Check if everything done was successful 
2579            */
2580           if(!$ldap->success()){
2581             msg_dialog::display(_("LDAP error"), 
2582                 sprintf(_("Updating '%s' failed: %s"),
2583                   "<b>".LDAP::fix($service['DN'])."</b>", 
2584                   "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2585           }else{
2586         
2587             /* Remove action from list 
2588              */
2589             unset($this->service[$key]);
2590           }
2591         }
2592       }
2593     }
2595     /* Update the service migration status 
2596      */
2597     $this->check_services();
2598   }
2601   /*! \brief  Ensure that posts made on the service migration dialog 
2602                are processed.
2603    */
2604   function check_service_posts()
2605   {
2606     foreach($this->service as $key => $service){
2607       if(isset($_POST["migrate_".$key])){
2608         $this->service[$key]['DETAILS'] =TRUE;
2609       }else{
2610         $this->service[$key]['DETAILS'] =FALSE;
2611       }
2612     }
2613   }
2616   /*! \brief  This function checks the given ldap for old style (gosa-2.5) 
2617                menu entries and will prepare a list of actions that are required
2618                to migrate them to gosa-2.6.
2619               All required actions and some readable informations are stored in 
2620                $this->menu.
2621    */
2622   function check_menus()
2623   {
2624     /* Establish ldap connection
2625      */
2626     $cv = $this->parent->captured_values;
2627     $ldap_l = new LDAP($cv['admin'],
2628         $cv['password'],
2629         $cv['connection'],
2630         FALSE,
2631         $cv['tls']);
2633     $ldap = new ldapMultiplexer($ldap_l);
2635     /* First detect all release names 
2636      */
2637     $ldap->cd($cv['base']);
2638     $res = $ldap->search("(&(objectClass=organizational)(objectClass=FAIbranch))",array("ou","objectClass"));
2640     /* Check if we were able to query the ldap server
2641      */
2642     if(!$res){
2643       $this->checks['old_style_menus']['STATUS']    = FALSE;
2644       $this->checks['old_style_menus']['STATUS_MSG']= _("LDAP query failed");
2645       $this->checks['old_style_menus']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2646       return;
2647     }
2649     /* Create application -> parameter mapping, used later to detect 
2650         which configured parameter belongs to which application entry.
2651      */
2652     $amap= array();
2653     $todo = array();
2654     $ldap->cd($cv['base']);
2655     $ldap->search("(objectClass=gosaApplication)", array("cn", "gosaApplicationParameter"));
2656     while($info = $ldap->fetch()){
2657       if (isset($info['gosaApplicationParameter']['count'])){
2658         for ($j= 0; $j < $info['gosaApplicationParameter']['count']; $j++){
2659           $p= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$j]);
2661           if(!isset($amap[$info['cn'][0]]) || !in_array($p, $amap[$info['cn'][0]])){
2662             $amap[$info['cn'][0]][]= $p;
2663           }
2664         }
2665       } else {
2666         $amap[$info['cn'][0]]= array();
2667       }
2668     }
2670     /* Search for all groups that have an old style application menu configured.
2671      */  
2672     $appgroups = array();
2673     $ldap->cd($cv['base']);
2674     $ldap->search("(&(objectClass=gosaApplicationGroup)(objectClass=posixGroup)(FAIrelease=*))",
2675         array("gosaMemberApplication","gosaApplicationParameter","FAIrelease","objectClass","gosaUnitTag"));
2677     /* Create readable prefix for "What will be done" infos 
2678      */
2679     $s_add = "<i>"._("Add")."</i>\t";
2680     $s_del = "<i>"._("Remove")."</i>\t";
2682     /* Walk through all found old-style menu configurations.
2683         -Prepare ldap update list     $data   
2684         -Prepare printable changes    $after/$current
2685      */
2686     while($info = $ldap->fetch()){
2688       $data = array();
2689       $current = "";
2690       $after ="";
2692       /* Get unit tag 
2693        */
2694       $tag ="";
2695       if(isset($info['gosaUnitTag'])){
2696         $tag = $info['gosaUnitTag'][0];
2697       }
2699       /* Collect application parameter for this group
2700        */
2701       $params= array();
2702       if(isset($info['gosaApplicationParameter'])){
2703         for ($i= 0; $i < $info['gosaApplicationParameter']['count']; $i++){
2704           $name= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$i]);
2705           $params[$name]= $info['gosaApplicationParameter'][$i];
2706         }
2707       }
2709       /* Create release container for each release/subrelease.
2710          eg.   "sisa/1.0.0":
2711          .       "ou=siga, ..."
2712          .       "ou=1.0.0,ou=siga, .."
2713        */ 
2714       $release = "";
2715       $r = $info['FAIrelease'][0];
2716       $z = split("/",$r);
2717       foreach($z as $part){
2719         if(!empty($part)){
2720           $release = "ou=".$part.",".$release;
2722           /* Append release department information to "What will be done" info
2723            */
2724           $release_dn = $release.$info['dn'];
2725           $after   .=  $s_add."dn: $release_dn\n";
2726           $after   .=  $s_add."objectClass: top\n";
2727           $after   .=  $s_add."objectClass: FAIbranch\n";
2728           $after   .=  $s_add."objectClass: organizationalUnit\n";
2729          
2730           /* Append UnitTag 
2731            */ 
2732           if($tag != ""){ 
2733             $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2734             $after   .=  $s_add."gosaUnitTag: $tag\n";
2735           }
2736           $after   .=  $s_add."ou: $part\n";
2738           /* Append release data to ldap actions 
2739            */
2740           $d = array();
2741           $d['objectClass'] = array("top","FAIbranch","organizationalUnit");
2742           if(!empty($tag)){
2743             $d['objectClass'][] = "gosaAdministrativeUnitTag";
2744             $d['gosaUnitTag']   = $tag;
2745           }
2746           $d['ou']          = $part;
2747           $data['ADD'][$release_dn]= $d;
2748         }
2749       }
2751       /* Add member applications to the array.
2752        */ 
2753       $current .= "dn: ".$info['dn']."\n";
2754       $menu_structure = array();
2755       for ($i= 0; $i < $info['gosaMemberApplication']['count']; $i++){
2756         list($name, $location, $priority)= explode("|", $info['gosaMemberApplication'][$i]);
2758         /* Create location dn 
2759          */
2760         $location_dn ="";
2761         if(!empty($location)){
2762           $location_dn ="cn=".$location.",";
2763         }
2765         /* Append old style element to current detail informations 
2766          */      
2767         $current .= $s_del."gosaMemberApplication: ".$info['gosaMemberApplication'][$i]."\n";
2769         /* Append ldap update action to remove the old menu entry attributes 
2770          */
2771         unset($info['objectClass']['count']);
2772         $d = array();
2773         $d['gosaMemberApplication']      = array();
2774         $d['gosaApplicationParameter']  = array();
2775         if(isset($info['FAIrelease'])){
2776           $d['FAIrelease'] = array();
2777         }
2778         $d['objectClass']               = array_remove_entries(array("gosaApplicationGroup","FAIreleaseTag"),$info['objectClass']);
2779         $data['MODIFY'][$info['dn']]    = $d;
2781         /* Create new application menu structure 
2782          */
2783         if (isset($amap[$name])){
2785           /* Append missing menu structure to "What is done info"
2786            */
2787           if(!isset($menu_structure[$location]) && !empty($location)){
2788             $menu_structure[$location] = TRUE;
2789             $after .= "\n";
2790             $after .= $s_add."dn: $location_dn$release_dn\n";
2791             $after .= $s_add."objectClass: gotoSubmenuEntry\n";
2793             /* Append UnitTag
2794              */
2795             if($tag != ""){
2796               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2797               $after   .=  $s_add."gosaUnitTag: $tag\n";
2798             }
2799             $after .= $s_add."cn: $location\n";
2800   
2801             /* Create ldap entry to append 
2802              */
2803             $d = array();
2804             $d['cn'] = $location;
2805             $d['objectClass'] = array("gotoSubmenuEntry");
2806             if(!empty($tag)){
2807               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2808               $d['gosaUnitTag']   = $tag;
2809             }
2810             $data['ADD'][$location_dn.$release_dn] = $d;
2811           }
2814           /* Append missing menu entry for "What is done info".
2815            */
2816           if(!empty($name)){
2817             $after .= "\n";
2818             $after .= $s_add."dn: cn=$name,$location_dn$release_dn\n";
2819             $after .= $s_add."objectClass: gotoMenuEntry\n";
2820             if($tag != ""){
2821               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2822               $after   .=  $s_add."gosaUnitTag: $tag\n";
2823             }
2824             $after .= $s_add."cn: $name\n";
2825             $after .= $s_add."gosaApplicationPriority: $priority\n";
2827             /* Create ldap entry 
2828              */
2829             $d= array();
2830             $d['objectClass'] = array("gotoMenuEntry");
2831             if(!empty($tag)){
2832               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2833               $d['gosaUnitTag']   = $tag;
2834             }
2835             $d['cn']          = $name;
2836             $d['gosaApplicationPriority'] = $priority;
2838             foreach ($amap[$name] as $n){
2839               if (isset($params[$n])){
2840                 $after .= $s_add."gosaApplicationParameter: ".$params[$n]."\n";
2841                 $d['gosaApplicationParameter'][] = $params[$n];
2842               }
2843             }
2844             $data['ADD']["cn=$name,$location_dn$release_dn"] = $d;
2845           }         
2846         }
2847       }
2849       /* Updated todo list 
2850        */ 
2851       $todo[] = array(
2852           "DETAILS" => FALSE,
2853           "DN"      => $info['dn'],
2854           "AFTER"   => $after,
2855           "CURRENT" => $current,
2856           "TODO"    => $data
2857           );
2858     }
2860     /* Remember checks.
2861      */
2862     $this->menu = $todo;
2864     /* Check if we were able to query the ldap server
2865      */
2866     if(count($this->menu)){
2867       $this->checks['old_style_menus']['STATUS']    = FALSE;
2868       $this->checks['old_style_menus']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2869       $this->checks['old_style_menus']['ERROR_MSG'] = sprintf(_("There are %s application menus which have to be migrated."),
2870                                                       count($this->menu))."<input type='submit' name='menu_dialog' value='"._("Migrate")."'>";
2871     }else{
2872       $this->checks['old_style_menus']['STATUS']    = TRUE;
2873       $this->checks['old_style_menus']['STATUS_MSG']= _("Ok");
2874       $this->checks['old_style_menus']['ERROR_MSG'] = "";
2875     }
2876   }
2878   
2879   /*! \brief  Handle posts for the menu_dialog 
2880               Ensure that checked checkboxes stay checked.
2881    */
2882   function check_menu_posts()
2883   {
2884     foreach($this->menu as $key => $menu){
2885       if(isset($_POST["migrate_".$key])){
2886         $this->menu[$key]['DETAILS'] =TRUE;
2887       }else{
2888         $this->menu[$key]['DETAILS'] =FALSE;
2889       }
2890     }
2891   }
2894   /*! \brief  This function updates old-style application menus to
2895                valid 2.6 application menus.
2896               All selected menus will be converted (DETAILS = TRUE). 
2897               The ldap actions collected by check_menus() will be executed. 
2898    */
2899   function migrate_menus()
2900   {
2902     /* Establish ldap connection
2903      */
2904     $cv = $this->parent->captured_values;
2905     $ldap_l = new LDAP($cv['admin'],
2906         $cv['password'],
2907         $cv['connection'],
2908         FALSE,
2909         $cv['tls']);
2911     $ldap = new ldapMultiplexer($ldap_l);
2912     $ldap->cd($cv['base']);
2914     /* Walk through menus and detect selected menu 
2915      */
2916     foreach($this->menu as $key => $menu){
2917       if($menu['DETAILS']) {
2919         /* Excute all LDAP-ADD actions 
2920          */
2921         $success = TRUE;
2922         foreach($menu['TODO']['ADD'] as $dn => $data){
2923           $ldap->cd($cv['base']);
2924           if(!$ldap->dn_exists($dn)){
2925             $ldap->cd($dn);
2926             $ldap->add($data);
2927             if (!$ldap->success()){
2928               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
2929               $success = FALSE;
2930             }
2931           }
2932         }
2934         /* Execute all LDAP-MODIFY actions 
2935          */
2936         foreach($menu['TODO']['MODIFY'] as $dn => $data){
2937           $ldap->cd($cv['base']);
2938           if($ldap->dn_exists($dn)){
2939             $ldap->cd($dn);
2940             $ldap->modify($data);
2941             if (!$ldap->success()){
2942               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
2943               $success = FALSE;
2944             }
2945           }
2946         }
2947   
2948         /* If every action was successful, remove this entry from the list 
2949          */
2950         if($success){
2951           unset($this->menu[$key]);
2952         }
2953       }
2954     }
2956     /* Udpate migration status for application menus
2957      */
2958     $this->check_menus();
2959   }
2962   function migrate_selected_admin_users()
2963   {
2964     /* Updated ui selection */
2965     $this->migrate_users();
2967     /* Establish ldap connection */
2968     $cv = $this->parent->captured_values;
2969     $ldap_l = new LDAP($cv['admin'],
2970         $cv['password'],
2971         $cv['connection'],
2972         FALSE,
2973         $cv['tls']);
2975     $ldap = new ldapMultiplexer($ldap_l);
2976     $ldap->cd($cv['base']);
2978     /* Get current ACL configuration for the ldap base 
2979      */
2980     $ldap->cat($cv['base']);
2981     $base_attrs = $ldap->fetch();
2982     $acl_entries= array();
2983     $acl_id = -1;
2984     if(isset($base_attrs['gosaAclEntry'])){
2985       for($i=0; $i < $base_attrs['gosaAclEntry']['count']; $i ++){
2986         $acl_entries[] = $base_attrs['gosaAclEntry'][$i];
2987         $cur_id = preg_replace("/^([0-9]*):.*$/","\\1",$base_attrs['gosaAclEntry'][$i]);
2988         if($cur_id > $acl_id){
2989           $acl_id = $cur_id;
2990         }
2991       }
2992     }
2994     /* Append ACLs selected in the migrate admin account dialog 
2995      */
2996     foreach($this->migrate_users as $entry){
2997       if($entry['checked']){
2998         $acl_id ++;
2999         $acl_entries[] = $acl_id.$entry['change'];
3000       }
3001     }
3002    
3003     /* Check if the required objectClasses are available 
3004      */
3005     $ocs = array();     
3006     for($i=0;$i< $base_attrs['objectClass']['count']; $i++){
3007       $ocs[] = $base_attrs['objectClass'][$i];
3008     }
3009     if(!in_array("gosaACL",$ocs)){
3010       $ocs[] = "gosaACL";
3011     }
3013     /* Try to write changes 
3014      */
3015     if(count($acl_entries)){
3016       $new_entry['gosaAclEntry'] = $acl_entries;
3017       $new_entry['objectClass'] = $ocs;
3018       $ldap->cd($cv['base']);
3019       $ldap->modify($new_entry);
3020       if(!$ldap->success()){
3021         $this->checks['acls']['TITLE']     = _("Checking for super administrator");
3022         $this->checks['acls']['STATUS']    = FALSE;
3023         $this->checks['acls']['STATUS_MSG']= _("Failed");
3024         $this->checks['acls']['ERROR_MSG'] = "<br>".msgPool::ldaperror($cv['base'],$ldap->get_error(),LDAP_MOD);
3025       }else{
3026         $this->check_administrativeAccount();
3027       }     
3028     }
3029   }
3030   
3032   function migrate_users()
3033   {
3034     /* Collect a list of available GOsa users and groups 
3035      */
3037     /* Establish ldap connection */
3038     $cv = $this->parent->captured_values;
3039     $ldap_l = new LDAP($cv['admin'],
3040         $cv['password'],
3041         $cv['connection'],
3042         FALSE,
3043         $cv['tls']);
3045     $ldap = new ldapMultiplexer($ldap_l);
3046     $ldap->cd($cv['base']);
3048     $users = array();
3049     $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
3050         "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
3051     while($user_attrs = $ldap->fetch()){
3052       $users[$user_attrs['dn']] = $user_attrs['uid'][0];
3053       $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
3054     }
3055     $groups = array();
3056     $ldap->search("objectClass=posixGroup",array("cn","dn"));
3057     while($group_attrs = $ldap->fetch()){
3058       $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
3059     }
3061     foreach($this->migrate_users as $id => $data){
3062       $this->migrate_users[$id]['checked'] = isset($_POST['migrate_admin_'.$id]);
3063     }
3065     /* Try to find an old GOsa 2.5 administrative account that may be migrated
3066      */
3067     if(!count($this->migrate_users)){
3068       $ldap->cat($cv['base']);
3069       $base_data = $ldap->fetch();
3070       $base_entry = "dn: ".$base_data['dn']."\n";
3071       for($i=0;$i<$base_data['objectClass']['count'];$i++){
3072         $base_entry .= "objectClass: ".$base_data['objectClass'][$i]."\n";
3073       }
3074       if(!in_array("gosaACL",$base_data['objectClass'])){
3075         $base_entry .= "<b>objectClass: gosaACL</b>\n";
3076       }
3077       if(isset($base_data['gosaAclEntry'])){
3078         for($i=0;$i<$base_data['gosaAclEntry']['count'];$i++){
3079           $base_entry .= "gosaAclEntry: ".$base_data['gosaAclEntry'][$i]."\n";
3080         }
3081       }
3082       $this->migrate_acl_base_entry = $base_entry;
3083       $ldap->cd($cv['base']);
3084       $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
3085       while($p_group = $ldap->fetch()){
3086         for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
3087           $user = $p_group['memberUid'][$e];
3088           if(isset($rusers[$user])){
3089             $bsp_acl_entry = "gosaAclEntry: #:psub:".base64_encode($rusers[$user]).":all;cmdrw\n";
3090             $entry = array();
3091             $entry['uid'] = $user; 
3092             $entry['dn'] = $rusers[$user]; 
3093             $entry['details'] = $bsp_acl_entry; 
3094             $entry['checked'] = FALSE;
3095             $entry['change'] = ":psub:".base64_encode($rusers[$user]).":all;cmdrw";
3096             $this->migrate_users[] = $entry;
3097           }
3098         }
3099       }
3100     }
3101   }
3103 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
3104 ?>