Code

Updated password methods.
[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       }
1011       /* Print out results 
1012        */
1013       if($GOsa_25_found){
1014         $str = "";
1015         if(!empty($valid_groups)){
1016           $str.= "<i>".sprintf(_("GOsa 2.5 adminitrative accounts found: %s."),trim($valid_groups,", "))."</i><br>";
1017         }
1018         $this->checks['acls']['STATUS']    = FALSE;
1019         $this->checks['acls']['STATUS_MSG']= _("Failed");
1020         $this->checks['acls']['ERROR_MSG'] = $str;
1021         $this->checks['acls']['ERROR_MSG'].= _("There is no valid GOsa 2.6 administrator account inside your LDAP.")."&nbsp;";
1022         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='migrate_acls' value='"._("Migrate")."'>";
1023         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create new")."'>";
1024       }elseif($GOsa_26_found){
1025         $str = "";
1026         if(!empty($valid_users)){
1027           $str.= "<b>"._("Users")."</b>:&nbsp;".trim($valid_users,", ")."<br>";
1028         }
1029         if(!empty($valid_groups)){
1030           $str.= "<b>"._("Groups")."</b>:&nbsp;".trim($valid_groups,", ")."<br>";
1031         }
1032         $this->checks['acls']['STATUS']    = TRUE;
1033         $this->checks['acls']['STATUS_MSG']= _("Ok");
1034         $this->checks['acls']['ERROR_MSG'] = $str;
1035       }elseif($GOsa_25_found){
1036         $this->checks['acls']['STATUS']    = FALSE;
1037         $this->checks['acls']['STATUS_MSG']= _("Failed");
1038         $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")."&nbsp;";
1039         $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create")."'>";
1040       }
1041     }
1042     return($ldap->count()>=1);
1043   }
1047   function create_admin($only_ldif = FALSE)
1048   {
1049     /* Reset '' */
1050     $this->acl_create_changes="";
1052     /* Object that should receive admin acls */
1053     $dn = $this->acl_create_selected;
1055     /* Get collected configuration settings */
1056     $cv = $this->parent->captured_values;
1058     /* On first call check for rid/sid base */
1059     $ldap_l = new LDAP($cv['admin'],
1060         $cv['password'],
1061         $cv['connection'],
1062         FALSE,
1063         $cv['tls']);
1065     $ldap = new ldapMultiplexer($ldap_l);
1067     /* Get current base attributes */
1068     $ldap->cd($cv['base']);
1069     $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
1070     $attrs = $ldap->fetch();
1072     /* Add acls for the selcted user to the base */
1073     $attrs_new = array();
1074     $attrs_new['objectClass'] = array("gosaACL");
1076     for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
1077       if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
1078         $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
1079       }
1080     }
1082     $acl = "0:psub:".base64_encode($dn).":all;cmdrw";    
1083     $attrs_new['gosaAclEntry'][] = $acl;
1084     if(isset($attrs['gosaAclEntry'])){
1085       for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
1086           
1087         $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
1088         $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
1089  
1090         $data = ($prio+1).$rest;
1091         $attrs_new['gosaAclEntry'][] = $data;
1092       }
1093     }
1095     if($only_ldif){
1096       $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
1097       $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
1098       $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
1099       $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
1100     }else{
1101    
1102       $ldap->cd($cv['base']);
1103       if(!$ldap->modify($attrs_new)){
1104         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);
1105         return(FALSE);
1106       }else{
1107         return(TRUE);
1108       }
1109     }
1110   }
1111  
1112   
1113   function create_admin_user()
1114   {
1115     $pw1 = $pw2 = "";
1116     $uid = "";
1118     /* On first call check for rid/sid base */
1119     $cv = $this->parent->captured_values;
1120     $ldap_l = new LDAP($cv['admin'],
1121         $cv['password'],
1122         $cv['connection'],
1123         FALSE,
1124         $cv['tls']);
1126     $ldap = new ldapMultiplexer($ldap_l);
1127   
1128     if(isset($_POST['new_user_uid'])){
1129       $uid = $_POST['new_user_uid'];
1130     }
1131     if(isset($_POST['new_user_password'])){
1132       $pw1 = $_POST['new_user_password'];
1133     }
1134     if(isset($_POST['new_user_password2'])){
1135       $pw2 = $_POST['new_user_password2'];
1136     }
1137   
1138     
1139     $ldap->cd($cv['base']);
1140     $ldap->search("(uid=".$uid.")");
1141     if($ldap->count()){
1142       msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
1143       return false;
1144     }
1145     
1146     if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
1147       msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
1148       return false;
1149     }
1150  
1151     if(!tests::is_uid($uid) || empty($uid)){
1152       msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
1153       return false;
1154     }
1155  
1156  
1157     /* Get current base attributes */
1158     $ldap->cd($cv['base']);
1159   
1160     $people_ou = trim($cv['peopleou']);
1161     if(!empty($people_ou)){
1162       $people_ou = trim($people_ou).",";
1163     }
1165     if($cv['peopledn'] == "cn"){
1166       $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
1167     }else{
1168       $dn = "uid=".$uid.",".$people_ou.$cv['base'];
1169     }
1171     $hash = passwordMethod::make_hash($pw2, $cv['encryption']);
1173     $new_user=array();
1174     $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
1175     $new_user['givenName']  = "System";
1176     $new_user['sn']  = "Administrator";
1177     $new_user['cn']  = "System Administrator-".$uid;
1178     $new_user['uid'] = $uid;
1179     $new_user['userPassword'] = $hash;
1180    
1181     $ldap->cd($cv['base']);
1182   
1183     $ldap->cat($dn,array("dn"));
1184     if($ldap->count()){
1185       msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
1186       return(FALSE);  
1187     }
1189     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
1190     $ldap->cd($dn);  
1191     $res = $ldap->add($new_user);
1192     $this->acl_create_selected = $dn;
1193     $this->create_admin();
1194     
1195     if(!$res){
1196       msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
1197       return(FALSE);
1198     }
1199   
1200     $this->acl_create_dialog=FALSE;        
1201     $this->check_administrativeAccount();
1202     return(TRUE);
1203   }
1204  
1206   function migrate_outside_winstations($perform = FALSE)
1207   {
1208     /* Establish ldap connection */
1209     $cv = $this->parent->captured_values;
1210     $ldap_l = new LDAP($cv['admin'],
1211         $cv['password'],
1212         $cv['connection'],
1213         FALSE,
1214         $cv['tls']);
1216     $ldap = new ldapMultiplexer($ldap_l);
1218     $ldap->cd($cv['base']);
1220     /* Check if there was a destination department posted */
1221     if(isset($_POST['move_winstation_to'])){
1222       $destination_dep = $_POST['move_winstation_to'];
1223     }else{
1224       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1225       return(false);
1226     }
1227  
1228     foreach($this->outside_winstations as $b_dn => $data){
1229       $this->outside_winstations[$b_dn]['ldif'] ="";
1230       if($data['selected']){
1231         $dn = base64_decode($b_dn);
1232         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1233         if(!$perform){
1234           $this->outside_winstations[$b_dn]['ldif'] = _("Winstation will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1237           /* Check if there are references to this object */
1238           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1239           $refs = "";
1240           while($attrs = $ldap->fetch()){
1241             $ref_dn = $attrs['dn'];
1242             $refs .= "<br />\t".$ref_dn;
1243           } 
1244           if(!empty($refs)){ 
1245             $this->outside_winstations[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1246           }
1248         }else{
1249           $this->move($dn,$d_dn);
1250         }
1251       }
1252     }
1253   }
1254   
1256   function migrate_outside_groups($perform = FALSE)
1257   {
1258     /* Establish ldap connection */
1259     $cv = $this->parent->captured_values;
1260     $ldap_l = new LDAP($cv['admin'],
1261         $cv['password'],
1262         $cv['connection'],
1263         FALSE,
1264         $cv['tls']);
1266     $ldap = new ldapMultiplexer($ldap_l);
1267     $ldap->cd($cv['base']);
1269     /* Check if there was a destination department posted */
1270     if(isset($_POST['move_group_to'])){
1271       $destination_dep = $_POST['move_group_to'];
1272     }else{
1273       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1274       return(false);
1275     }
1276  
1277     foreach($this->outside_groups as $b_dn => $data){
1278       $this->outside_groups[$b_dn]['ldif'] ="";
1279       if($data['selected']){
1280         $dn = base64_decode($b_dn);
1281         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1282         if(!$perform){
1284           $this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1286           /* Check if there are references to this object */
1287           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1288           $refs = "";
1289           while($attrs = $ldap->fetch()){
1290             $ref_dn = $attrs['dn'];
1291             $refs .= "<br />\t".$ref_dn;
1292           } 
1293           if(!empty($refs)){ 
1294             $this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1295           }
1297         }else{
1298           $this->move($dn,$d_dn);
1299         }
1300       }
1301     }
1302   }
1303   
1305   function migrate_outside_users($perform = FALSE)
1306   {
1307     /* Establish ldap connection */
1308     $cv = $this->parent->captured_values;
1309     $ldap_l = new LDAP($cv['admin'],
1310         $cv['password'],
1311         $cv['connection'],
1312         FALSE,
1313         $cv['tls']);
1315     $ldap = new ldapMultiplexer($ldap_l);
1316     $ldap->cd($cv['base']);
1318     /* Check if there was a destination department posted */
1319     if(isset($_POST['move_user_to'])){
1320       $destination_dep = $_POST['move_user_to'];
1321     }else{
1322       msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1323       return(false);
1324     }
1325       
1326     foreach($this->outside_users as $b_dn => $data){
1327       $this->outside_users[$b_dn]['ldif'] ="";
1328       if($data['selected']){
1329         $dn = base64_decode($b_dn);
1330         $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1331         if(!$perform){
1332           $this->outside_users[$b_dn]['ldif'] = _("User will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1334           /* Check if there are references to this object */
1335           $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1336           $refs = "";
1337           while($attrs = $ldap->fetch()){
1338             $ref_dn = $attrs['dn'];
1339             $refs .= "<br />\t".$ref_dn;
1340           } 
1341           if(!empty($refs)){ 
1342             $this->outside_users[$b_dn]['ldif'] .= "<br /><br /><i>"._("The following references will be updated").":</i>".$refs;
1343           }
1345         }else{
1346           $this->move($dn,$d_dn);
1347         }
1348       }
1349     }
1350   }
1351   
1353   function execute()
1354   {
1355     /* Initialise checks if this is the first call */
1356     if(!$this->checks_initialised || isset($_POST['reload'])){
1357       $this->initialize_checks();
1358       $this->checks_initialised = TRUE;
1359     }
1361     /*************
1362      * Winstations outside the group ou 
1363      *************/
1364     
1365     if(isset($_POST['outside_winstations_dialog_cancel'])){
1366       $this->outside_winstations_dialog = FALSE;
1367       $this->dialog = FALSE;
1368       $this->show_details = FALSE;
1369     }
1370    
1371     if(isset($_POST['outside_winstations_dialog_whats_done'])){
1372       $this->migrate_outside_winstations(FALSE);
1373     }
1374  
1375     if(isset($_POST['outside_winstations_dialog_perform'])){
1376       $this->migrate_outside_winstations(TRUE);
1377       $this->search_outside_winstations();
1378       $this->dialog = FALSE;
1379       $this->show_details = FALSE;
1380       $this->outside_winstations_dialog = FALSE;
1381     }
1383     if(isset($_POST['outside_winstations_dialog'])){
1384       $this->outside_winstations_dialog = TRUE;
1385       $this->dialog = TRUE;
1386     }
1387     
1388     if($this->outside_winstations_dialog){
1390       /* Fix displayed dn syntax */ 
1391       $tmp = $this->outside_winstations;
1392       foreach($tmp as $key => $data){
1393         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1394       }
1396       $smarty = get_smarty();
1397       $smarty->assign("ous",$this->get_all_winstation_ous());
1398       $smarty->assign("method","outside_winstations");
1399       $smarty->assign("outside_winstations",$tmp);
1400       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1401     }
1402     /*************
1403      * Groups outside the group ou 
1404      *************/
1405     
1406     if(isset($_POST['outside_groups_dialog_cancel'])){
1407       $this->outside_groups_dialog = FALSE;
1408       $this->show_details = FALSE;
1409       $this->dialog = FALSE;
1410     }
1411    
1412     if(isset($_POST['outside_groups_dialog_whats_done'])){
1413       $this->show_details= TRUE;
1414       $this->migrate_outside_groups(FALSE);
1415     }
1416  
1417     if(isset($_POST['outside_groups_dialog_refresh'])){
1418       $this->show_details= FALSE;
1419     }
1421     if(isset($_POST['outside_groups_dialog_perform'])){
1422       $this->migrate_outside_groups(TRUE);
1423       $this->dialog = FALSE;
1424       $this->show_details = FALSE;
1425       $this->outside_groups_dialog = FALSE;
1426       $this->initialize_checks();
1427     }
1429     if(isset($_POST['outside_groups_dialog'])){
1430       $this->outside_groups_dialog = TRUE;
1431       $this->dialog = TRUE;
1432     }
1433     
1434     if($this->outside_groups_dialog){
1436       /* Fix displayed dn syntax */ 
1437       $tmp = $this->outside_groups;
1438       foreach($tmp as $key => $data){
1439         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1440       }
1442       $smarty = get_smarty();
1443       $smarty->assign("ous",$this->get_all_group_ous());
1444       $smarty->assign("method","outside_groups");
1445       $smarty->assign("outside_groups",$tmp);
1446       $smarty->assign("group_details", $this->show_details);
1447       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1448     }
1449  
1450     /*************
1451      * User outside the people ou 
1452      *************/
1453     
1454     if(isset($_POST['outside_users_dialog_cancel'])){
1455       $this->outside_users_dialog = FALSE;
1456       $this->dialog = FALSE;
1457       $this->show_details = FALSE;
1458     }
1459    
1460     if(isset($_POST['outside_users_dialog_whats_done'])){
1461       $this->show_details= TRUE;
1462       $this->migrate_outside_users(FALSE);
1463     }
1464  
1465     if(isset($_POST['outside_users_dialog_perform'])){
1466       $this->migrate_outside_users(TRUE);
1467       $this->initialize_checks();
1468       $this->dialog = FALSE;
1469       $this->show_details = FALSE;
1470       $this->outside_users_dialog = FALSE;
1471     }
1473     if (isset($_POST['outside_users_dialog_refresh'])){
1474       $this->show_details= FALSE;
1475     }
1477     if(isset($_POST['outside_users_dialog'])){
1478       $this->outside_users_dialog = TRUE;
1479       $this->dialog = TRUE;
1480     }
1481     
1482     if($this->outside_users_dialog){
1484       /* Fix displayed dn syntax */ 
1485       $tmp = $this->outside_users;
1486       foreach($tmp as $key => $data){
1487         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1488       }
1490       $smarty = get_smarty();
1491       $smarty->assign("ous",$this->get_all_people_ous());
1492       $smarty->assign("method","outside_users");
1493       $smarty->assign("outside_users",$tmp);
1494       $smarty->assign("user_details", $this->show_details);
1495       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1496     }
1497  
1498     /*************
1499      * Root object check  
1500      *************/
1501   
1502     if(isset($_POST['retry_root_create'])){
1504       $state = $this->checks['root']['STATUS'];
1505       $this->checkBase(FALSE);
1506       if($state != $this->checks['root']['STATUS']){
1507         $this->initialize_checks();
1508       }
1509     }
1510  
1511     /*************
1512      * Administrative Account -- Migrate/Create 
1513      *************/
1515     if(isset($_POST['retry_acls'])){
1516       $this->check_administrativeAccount();
1517     }
1519     /* Dialog handling */
1520     if(isset($_POST['create_acls'])){
1521       $this->acl_create_dialog = TRUE;
1522       $this->dialog = TRUE;
1523     }
1525     if(isset($_POST['migrate_acls'])){
1526       $this->acl_migrate_dialog = TRUE;
1527       $this->dialog = TRUE;
1528     }
1529   
1530     if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
1531       $this->acl_create_dialog = FALSE;
1532       $this->acl_migrate_dialog = FALSE;
1533       $this->dialog = FALSE;
1534       $this->show_details = FALSE;
1535     }
1537     /* Account creation */
1538     if(isset($_POST['create_acls_create'])){
1539       $this->create_admin(TRUE);
1540     }
1542     if(isset($_POST['create_admin_user'])){
1543       if($this->create_admin_user()){
1544         $this->dialog = FALSE;
1545       $this->show_details = FALSE;
1546       }
1547     }
1549     /* Add admin acls for the selected users to the ldap base.
1550      */
1551     if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
1553       /* Update ldap and reload check infos 
1554        */
1555       $this->migrate_selected_admin_users();
1557     }elseif($this->acl_migrate_dialog){
1559       /* Display admin migration dialog.
1560        */
1561       $this->migrate_users();
1562       $smarty = get_smarty();
1564       /* Do we have to display the changes
1565        */
1566       $details = isset($_POST['details']) && $_POST['details'];
1567       if(isset($_POST['migrate_acls_show_changes'])){
1568         $details = TRUE;
1569       }elseif(isset($_POST['migrate_acls_hide_changes'])){
1570         $details = FALSE;
1571       }
1573       $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
1574       $smarty->assign("details", $details);
1575       $smarty->assign("method","migrate_acls");
1576       $smarty->assign("migrateable_users",$this->migrate_users);
1577       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1578     }
1580     if($this->acl_create_dialog){
1581       $smarty = get_smarty();
1582       $uid = "admin";
1583       if(isset($_POST['new_user_uid'])){
1584         $uid = $_POST['new_user_uid'];
1585       }
1586       $smarty->assign("new_user_uid",$uid);
1587       $smarty->assign("new_user_password",@$_POST['new_user_password']);
1588       $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
1589       $smarty->assign("method","create_acls");
1590       $smarty->assign("acl_create_selected",$this->acl_create_selected);
1591       $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
1592       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1593     }
1595     /*************
1596      * User Migration handling 
1597      *************/
1599     /* Refresh list of deparments */
1600     if(isset($_POST['users_visible_migrate_refresh'])){
1601       $this->check_gosaAccounts();
1602     }
1604     /* Open migration dialog */
1605     if(isset($_POST['users_visible_migrate'])){
1606       $this->show_details= FALSE;
1607       $this->users_migration_dialog = TRUE;
1608       $this->dialog =TRUE;
1609     }
1611     /* Close migration dialog */
1612     if(isset($_POST['users_visible_migrate_close'])){
1613       $this->users_migration_dialog = FALSE;
1614       $this->dialog =FALSE;
1615       $this->show_details = FALSE;
1616     }
1618     /* Start migration */
1619     if(isset($_POST['users_visible_migrate_migrate'])){
1620       if($this->migrate_gosaAccounts()){
1621         $this->initialize_checks();
1622         $this->dialog = FALSE;
1623         $this->show_details = FALSE;
1624         $this->users_migration_dialog = FALSE;
1625       }
1626     }
1628     /* Start migration */
1629     if(isset($_POST['users_visible_migrate_whatsdone'])){
1630       $this->migrate_gosaAccounts(TRUE);
1631     }
1633     /* Display migration dialog */
1634     if($this->users_migration_dialog){
1636       /* Fix displayed dn syntax */ 
1637       $tmp = $this->users_to_migrate;
1638       foreach($tmp as $key => $data){
1639         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1640       }
1642       $smarty = get_smarty();
1643       $smarty->assign("users_to_migrate",$tmp);
1644       $smarty->assign("method","migrate_users");
1645       $smarty->assign("user_details", $this->show_details);
1646       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1647     }
1650     /*************
1651      * Department Migration handling 
1652      *************/
1654     /* Refresh list of deparments */
1655     if(isset($_POST['deps_visible_migrate_refresh'])){
1656       $this->check_organizationalUnits();
1657       $this->show_details= FALSE;
1658     }
1660     /* Open migration dialog */
1661     if(isset($_POST['deps_visible_migrate'])){
1662       $this->dep_migration_dialog = TRUE;
1663       $this->dialog =TRUE;
1664     }
1666     /* Close migration dialog */
1667     if(isset($_POST['deps_visible_migrate_close'])){
1668       $this->dep_migration_dialog = FALSE;
1669       $this->dialog =FALSE;
1670       $this->show_details = FALSE;
1671     }
1673     /* Start migration */
1674     if(isset($_POST['deps_visible_migrate_migrate'])){
1675       if($this->migrate_organizationalUnits()){
1676         $this->show_details= FALSE;
1677         $this->check_organizationalUnits();
1678         $this->dialog = FALSE;
1679         $this->dep_migration_dialog = FALSE;
1680       }
1681     }
1683     /* Start migration */
1684     if(isset($_POST['deps_visible_migrate_whatsdone'])){
1685       $this->migrate_organizationalUnits(TRUE);
1686     }
1688     /* Display migration dialog */
1689     if($this->dep_migration_dialog){
1690       $smarty = get_smarty();
1691    
1692       /* Fix displayed dn syntax */ 
1693       $tmp = $this->deps_to_migrate;
1694       foreach($tmp as $key => $data){
1695         $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1696       }
1698       $smarty->assign("deps_to_migrate",$tmp);
1699       $smarty->assign("method","migrate_deps");
1700       $smarty->assign("deps_details", $this->show_details);
1701       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1702     }
1705     /*************
1706      * Device migration 
1707      *************/
1708    
1709     if($this->device_dialog) {
1710       $this->check_device_posts();
1711     }
1712  
1713     if(isset($_POST['device_dialog_cancel'])){
1714       $this->device_dialog = FALSE;
1715       $this->show_details = FALSE;
1716       $this->dialog = FALSE;
1717     }
1718    
1719     if(isset($_POST['device_dialog_whats_done'])){
1720       $this->show_details= TRUE;
1721     }
1722  
1723     if(isset($_POST['device_dialog_refresh'])){
1724       $this->show_details= FALSE;
1725     }
1727     if(isset($_POST['migrate_devices'])){
1728       $this->migrate_usb_devices();
1729 #      $this->dialog = FALSE;
1730  #     $this->show_details = FALSE;
1731   #    $this->device_dialog = FALSE;
1732    #   $this->initialize_checks();
1733     }
1735     if(isset($_POST['device_dialog'])){
1736       $this->device_dialog = TRUE;
1737       $this->dialog = TRUE;
1738     }
1739     
1740     if($this->device_dialog){
1741       $smarty = get_smarty();
1742       $smarty->assign("method","devices");
1743       $smarty->assign("devices",$this->device);
1744       $smarty->assign("device_details", $this->show_details);
1745       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1746     }
1749     /*************
1750      * Service migration 
1751      *************/
1752    
1753     if($this->service_dialog) {
1754       $this->check_service_posts();
1755     }
1756  
1757     if(isset($_POST['service_dialog_cancel'])){
1758       $this->service_dialog = FALSE;
1759       $this->show_details = FALSE;
1760       $this->dialog = FALSE;
1761     }
1762    
1763     if(isset($_POST['service_dialog_whats_done'])){
1764       $this->show_details= TRUE;
1765     }
1766  
1767     if(isset($_POST['service_dialog_refresh'])){
1768       $this->show_details= FALSE;
1769     }
1771     if(isset($_POST['migrate_services'])){
1772       $this->migrate_services();
1773 #      $this->dialog = FALSE;
1774  #     $this->show_details = FALSE;
1775   #    $this->service_dialog = FALSE;
1776    #   $this->initialize_checks();
1777     }
1779     if(isset($_POST['service_dialog'])){
1780       $this->service_dialog = TRUE;
1781       $this->dialog = TRUE;
1782     }
1783     
1784     if($this->service_dialog){
1785       $smarty = get_smarty();
1786       $smarty->assign("method","services");
1787       $smarty->assign("services",$this->service);
1788       $smarty->assign("service_details", $this->show_details);
1789       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1790     }
1793     /*************
1794      * Menu migration 
1795      *************/
1796    
1797     if($this->menu_dialog) {
1798       $this->check_menu_posts();
1799     }
1800  
1801     if(isset($_POST['menu_dialog_cancel'])){
1802       $this->menu_dialog = FALSE;
1803       $this->show_details = FALSE;
1804       $this->dialog = FALSE;
1805     }
1806    
1807     if(isset($_POST['menu_dialog_whats_done'])){
1808       $this->show_details= TRUE;
1809     }
1810  
1811     if(isset($_POST['menu_dialog_refresh'])){
1812       $this->show_details= FALSE;
1813     }
1815     if(isset($_POST['migrate_menus'])){
1816       $this->migrate_menus();
1817 #      $this->dialog = FALSE;
1818  #     $this->show_details = FALSE;
1819   #    $this->menu_dialog = FALSE;
1820    #   $this->initialize_checks();
1821     }
1823     if(isset($_POST['menu_dialog'])){
1824       $this->menu_dialog = TRUE;
1825       $this->dialog = TRUE;
1826     }
1827     
1828     if($this->menu_dialog){
1829       $smarty = get_smarty();
1830       $smarty->assign("method","menus");
1831       $smarty->assign("menus",$this->menu);
1832       $smarty->assign("menu_details", $this->show_details);
1833       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1834     }
1836     $smarty = get_smarty();
1837     $smarty->assign("checks",$this->checks);
1838     $smarty->assign("method","default");
1839     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1840   }
1843   function save_object()
1844   {
1845     $this->is_completed= TRUE;
1847     /* Capture all selected winstations from outside_winstations_dialog */
1848     if($this->outside_winstations_dialog){
1849       foreach($this->outside_winstations as $dn => $data){
1850         if(isset($_POST['select_winstation_'.$dn])){
1851           $this->outside_winstations[$dn]['selected'] = TRUE;
1852         }else{
1853           $this->outside_winstations[$dn]['selected'] = FALSE;
1854         }
1855       }
1856     }
1858     /* Capture all selected groups from outside_groups_dialog */
1859     if($this->outside_groups_dialog){
1860       foreach($this->outside_groups as $dn => $data){
1861         if(isset($_POST['select_group_'.$dn])){
1862           $this->outside_groups[$dn]['selected'] = TRUE;
1863         }else{
1864           $this->outside_groups[$dn]['selected'] = FALSE;
1865         }
1866       }
1867     }
1869     /* Capture all selected users from outside_users_dialog */
1870     if($this->outside_users_dialog){
1871       foreach($this->outside_users as $dn => $data){
1872         if(isset($_POST['select_user_'.$dn])){
1873           $this->outside_users[$dn]['selected'] = TRUE;
1874         }else{
1875           $this->outside_users[$dn]['selected'] = FALSE;
1876         }
1877       }
1878     }
1880     /* Get "create acl" dialog posts */
1881     if($this->acl_create_dialog){
1883       if(isset($_POST['create_acls_create_abort'])){
1884         $this->acl_create_selected = "";
1885       }
1886     }
1888     /* Get selected departments */
1889     if($this->dep_migration_dialog){
1890       foreach($this->deps_to_migrate as $id => $data){
1891         if(isset($_POST['migrate_'.$id])){
1892           $this->deps_to_migrate[$id]['checked'] = TRUE;
1893         }else{
1894           $this->deps_to_migrate[$id]['checked'] = FALSE;
1895         }
1896       }
1897     }
1899     /* Get selected users */
1900     if($this->users_migration_dialog){
1901       foreach($this->users_to_migrate as $id => $data){
1902         if(isset($_POST['migrate_'.$id])){
1903           $this->users_to_migrate[$id]['checked'] = TRUE;
1904         }else{
1905           $this->users_to_migrate[$id]['checked'] = FALSE;
1906         }
1907       }
1908     }
1909   }
1912   /* Check if the root object exists.
1913    * If the parameter just_check is true, then just check if the 
1914    *  root object is missing and update the info messages.
1915    * If the Parameter is false, try to create a new root object.
1916    */
1917   function checkBase($just_check = TRUE)
1918   {
1919     /* Establish ldap connection */
1920     $cv = $this->parent->captured_values;
1921     $ldap_l = new LDAP($cv['admin'],
1922         $cv['password'],
1923         $cv['connection'],
1924         FALSE,
1925         $cv['tls']);
1927     $ldap = new ldapMultiplexer($ldap_l);
1929     /* Check if root object exists */
1930     $ldap->cd($cv['base']);
1931     $ldap->set_size_limit(1);
1932     $res = $ldap->search("(objectClass=*)");
1933     $ldap->set_size_limit(0);
1934     $err = ldap_errno($ldap->cid); 
1936     if( !$res || 
1937         $err == 0x20 ||  # LDAP_NO_SUCH_OBJECT
1938         $err == 0x40) {  # LDAP_NAMING_VIOLATION
1940       /* Root object doesn't exists 
1941        */
1942       if($just_check){
1943         $this->checks['root']['STATUS']    = FALSE;
1944         $this->checks['root']['STATUS_MSG']= _("Failed");
1945         $this->checks['root']['ERROR_MSG'] =  _("The LDAP root object is missing. It is required to use your LDAP service.").'&nbsp;';
1946         $this->checks['root']['ERROR_MSG'].=  "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1947         return(FALSE);
1948       }else{
1950         /* Add root object */ 
1951         $ldap->cd($cv['base']);
1952         $res = $ldap->create_missing_trees($cv['base']);
1954         /* If adding failed, tell the user */
1955         if(!$res){
1956           $this->checks['root']['STATUS']    = FALSE;
1957           $this->checks['root']['STATUS_MSG']= _("Failed");
1958           $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1959           $this->checks['root']['ERROR_MSG'].= "&nbsp;<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1960           return($res);;
1961         }
1962       }
1963     }
1965     /* Create & remove of dummy object was successful */
1966     $this->checks['root']['STATUS']    = TRUE;
1967     $this->checks['root']['STATUS_MSG']= _("Ok");
1968   }
1971   /* Return ldif information for a 
1972    * given attribute array 
1973    */
1974   function array_to_ldif($atts)
1975   {
1976     $ret = "";
1977     unset($atts['count']);
1978     unset($atts['dn']);
1979     foreach($atts as $name => $value){
1980       if(is_numeric($name)) {
1981         continue;
1982       }
1983       if(is_array($value)){
1984         unset($value['count']);
1985         foreach($value as $a_val){
1986           $ret .= $name.": ". $a_val."\n";
1987         }
1988       }else{
1989         $ret .= $name.": ". $value."\n";
1990       }
1991     }
1992     return(preg_replace("/\n$/","",$ret));
1993   }
1996   function get_user_list()
1997   {
1998     /* Establish ldap connection */
1999     $cv = $this->parent->captured_values;
2000     $ldap_l = new LDAP($cv['admin'],
2001         $cv['password'],
2002         $cv['connection'],
2003         FALSE,
2004         $cv['tls']);
2006     $ldap = new ldapMultiplexer($ldap_l);
2007     $ldap->cd($cv['base']);
2008     $ldap->search("(objectClass=gosaAccount)",array("dn"));
2009   
2010     $tmp = array();
2011     while($attrs = $ldap->fetch()){
2012       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2013     }
2014     return($tmp);
2015   }
2018  function get_all_people_ous()
2019   {
2020     /* Get collected configuration settings */
2021     $cv = $this->parent->captured_values;
2022     $people_ou = trim($cv['peopleou']);
2024     /* Establish ldap connection */
2025     $cv = $this->parent->captured_values;
2026     $ldap_l = new LDAP($cv['admin'],
2027         $cv['password'],
2028         $cv['connection'],
2029         FALSE,
2030         $cv['tls']);
2032     $ldap = new ldapMultiplexer($ldap_l);
2034     /*****************
2035      * If people ou is NOT empty
2036      * search for for all objects matching the given container
2037      *****************/
2038     if(!empty($people_ou)){
2039       $ldap->search("(".$people_ou.")",array("dn"));
2041       /* Create people ou if there is currently none */
2042       if($ldap->count() == 0 ){
2043         $add_dn = $cv['peopleou'].",".$cv['base'];
2044         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2045         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2046         $add = array();
2047         $add['objectClass'] = array("organizationalUnit");
2048         $add[$naming_attr] = $naming_value;
2049         $ldap->cd($cv['base']);
2050         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2051         $ldap->cd($add_dn);
2052         $ldap->add($add);
2053       }
2055       /* Create result */
2056       $ldap->search("(".$cv['peopleou'].")",array("dn"));
2057       $tmp = array();
2058       while($attrs= $ldap->fetch()){
2059         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2060           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2061         }
2062       }
2063     } else{
2065       /************
2066        * If people ou is empty
2067        * Get all valid gosaDepartments
2068        ************/
2069       $ldap->cd($cv['base']);
2070       $tmp = array();
2071       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2072       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2073       while($attrs = $ldap->fetch()){
2074         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2075       }
2076     }
2077     return($tmp);
2078   }
2081   function get_all_winstation_ous()
2082   {
2083     /* Establish ldap connection */
2084     $cv = $this->parent->captured_values;
2085     $ldap_l = new LDAP($cv['admin'],
2086         $cv['password'],
2087         $cv['connection'],
2088         FALSE,
2089         $cv['tls']);
2091     $ldap = new ldapMultiplexer($ldap_l);
2093     /* Get winstation ou */
2094     if($cv['generic_settings']['wws_ou_active']) {
2095       $winstation_ou = $cv['generic_settings']['wws_ou'];
2096     }else{
2097       $winstation_ou = "ou=winstations";
2098     }
2100     $ldap->cd($cv['base']);
2101     $ldap->search("(".$winstation_ou.")",array("dn"));
2102   
2103     if($ldap->count() == 0 ){
2104       $add_dn = $winstation_ou.",ou=systems,".$cv['base'];
2105       $naming_attr = preg_replace("/=.*$/","",$add_dn);
2106       $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2107       $add = array();
2108       $add['objectClass'] = array("organizationalUnit");
2109       $add[$naming_attr] = $naming_value;
2111       $ldap->cd($cv['base']);
2112       $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2113       $ldap->cd($add_dn);
2114       $ldap->add($add);
2115     }
2117     $ldap->search("(".$winstation_ou.")",array("dn"));
2118     $tmp = array();
2119     while($attrs= $ldap->fetch()){
2120       if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2121         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2122       }
2123     }
2124     return($tmp); 
2125   }
2128  function get_all_group_ous()
2129   {
2130     /* Establish ldap connection */
2131     $cv = $this->parent->captured_values;
2132     $ldap_l = new LDAP($cv['admin'],
2133         $cv['password'],
2134         $cv['connection'],
2135         FALSE,
2136         $cv['tls']);
2138     $ldap = new ldapMultiplexer($ldap_l);
2140     $group_ou = trim($cv['groupou']);
2141     if(!empty($group_ou)){
2142       $group_ou = trim($group_ou);
2143     }
2145     /************
2146      * If group ou is NOT empty
2147      * Get all valid group ous, create one if necessary
2148      ************/
2149     $ldap->cd($cv['base']);
2150     if(!empty($group_ou)){
2151       $ldap->search("(".$group_ou.")",array("dn"));
2152       if($ldap->count() == 0 ){
2153         $add_dn = $group_ou.$cv['base'];
2154         $naming_attr = preg_replace("/=.*$/","",$add_dn);
2155         $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2156         $add = array();
2157         $add['objectClass'] = array("organizationalUnit");
2158         $add[$naming_attr] = $naming_value;
2160         $ldap->cd($cv['base']);
2161         $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2162         $ldap->cd($add_dn);
2163         $ldap->add($add);
2164       }
2165       $ldap->search("(".$group_ou.")",array("dn"));
2166       $tmp = array();
2167       while($attrs= $ldap->fetch()){
2168         if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2169           $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2170         }
2171       }
2172     }else{
2173       /************
2174        * If group ou is empty
2175        * Get all valid gosaDepartments
2176        ************/
2177       $ldap->cd($cv['base']);
2178       $tmp = array();
2179       $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2180       $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2181       while($attrs = $ldap->fetch()){
2182         $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2183       }
2184     }
2185     return($tmp);
2186   }
2189   function get_group_list()
2190   {
2191     /* Establish ldap connection */
2192     $cv = $this->parent->captured_values;
2193     $ldap_l = new LDAP($cv['admin'],
2194         $cv['password'],
2195         $cv['connection'],
2196         FALSE,
2197         $cv['tls']);
2199     $ldap = new ldapMultiplexer($ldap_l);
2200     
2201     $ldap->cd($cv['base']);
2202     $ldap->search("(objectClass=posixGroup)",array("dn"));
2203   
2204     $tmp = array();
2205     while($attrs = $ldap->fetch()){
2206       $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2207     }
2208     return($tmp);
2209   }
2212   function move($source,$destination)
2213   {
2214     /* Establish ldap connection */
2215     $cv = $this->parent->captured_values;
2216     $ldap_l = new LDAP($cv['admin'],
2217         $cv['password'],
2218         $cv['connection'],
2219         FALSE,
2220         $cv['tls']);
2222     $ldap = new ldapMultiplexer($ldap_l);
2224      /* Update object references in gosaGroupOfNames */
2225     $ogs_to_fix = array();
2226     $ldap->cd($cv['base']);
2227     $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($source).'))', array('cn','member'));
2228     while ($attrs= $ldap->fetch()){
2229       $dn = $attrs['dn'];
2230       $attrs = $this->cleanup_array($attrs);
2231       $member_new = array($destination);
2232       foreach($attrs['member'] as $member){
2233         if($member != $source){
2234           $member_new[] = $member;
2235         }
2236       }
2237       $attrs['member'] = $member_new;
2238       $ogs_to_fix[$dn] = $attrs;
2239     }
2241     /* Copy source to destination dn */
2242     $ldap->cat($source);
2243     $new_data = $this->cleanup_array($ldap->fetch());
2244     $ldap->cd($destination);
2245     $res = $ldap->add($new_data);
2247     /* Display warning if copy failed */
2248     if(!$res){
2249       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);
2250     }else{
2251       $res = $ldap->rmDir($source);
2252       if (!$ldap->success()){
2253         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_DEL, get_class()));
2254       }
2256       /* Object is copied, so update its references */
2257       foreach($ogs_to_fix as $dn => $data){
2258         $ldap->cd($dn);
2259         $ldap->modify($data);
2260       }
2261     }
2262   }
2265   /* Cleanup ldap result to be able to write it be to ldap */
2266   function cleanup_array($attrs)
2267   {
2268     foreach($attrs as $key => $value) {
2269       if(is_numeric($key) || in_array($key,array("count","dn"))){
2270         unset($attrs[$key]);
2271       }
2272       if(is_array($value) && isset($value['count'])){
2273         unset($attrs[$key]['count']);
2274       }
2275     }
2276     return($attrs);
2277   }
2280   /*! \brief  Act in posts from the device migration dialog 
2281    */
2282   function check_device_posts()
2283   {
2284     foreach($this->device as $key => $device){
2285       if(isset($_POST["migrate_".$key])){
2286         $this->device[$key]['DETAILS'] =TRUE;
2287       }else{
2288         $this->device[$key]['DETAILS'] =FALSE;
2289       }
2290     }
2291   }
2294   /*! \brief  Check for old style (gosa-2.5) devices.
2295               Save readable informations and a list of migratable devices 
2296                in $this->devices.
2297    */
2298   function check_usb_devices ()
2299   {
2300     /* Establish ldap connection */
2301     $cv = $this->parent->captured_values;
2302     $ldap_l = new LDAP($cv['admin'],
2303         $cv['password'],
2304         $cv['connection'],
2305         FALSE,
2306         $cv['tls']);
2308     $ldap = new ldapMultiplexer($ldap_l);
2309     $ldap->cd($cv['base']);
2310     $res = $ldap->search("(&(|(objectClass=posixAccount)(objectClass=posixGroup))(gotoHotplugDevice=*))",
2311         array("cn","gotoHotplugDevice","gosaUnitTag"));
2313     if(!$res){
2314       $this->checks['old_style_devices']['STATUS']    = FALSE;
2315       $this->checks['old_style_devices']['STATUS_MSG']= _("LDAP query failed");
2316       $this->checks['old_style_devices']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2317       return;
2318     }
2321     /* If adding failed, tell the user */
2322     if($ldap->count()){
2323   
2324       $this->device = array();
2325       while($attrs = $ldap->fetch()){
2327         for ($j= 0; $j < $attrs['gotoHotplugDevice']['count']; $j++){
2329           $after  = "";
2330           $current= "";
2332           $entry= $attrs['gotoHotplugDevice'][$j];
2334           @list($name,$desc,$serial,$vendor,$product) = explode('|', $entry);
2335   
2336           $add = 1;
2337           $new_name  = $name;
2338           while(isset($dest[$new_name])){
2339             $new_name = $name."_".$add;
2340             $add ++;
2341           }
2342           $name = $new_name;
2343           $newdn= "cn=$name,ou=devices,".preg_replace('/^[^,]+,/', '', $attrs['dn']);
2345           if (!isset($dest[$name])){
2346             $dest[$name]= $newdn;
2348             $current.= "dn: ".$attrs['dn']."\n"; 
2349     
2350             for ($c= 0; $c < $attrs['gotoHotplugDevice']['count']; $c++){
2351               if($c == $j){
2352                 $current.= "<b>gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."</b>\n"; 
2353               }else{
2354                 $current.= "gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."\n"; 
2355               }
2356             }
2358             $after.= "dn: $newdn\n";
2359             $after.= "changetype: add\n";
2360             $after.= "objectClass: top\n";
2361             $after.= "objectClass: gotoDevice\n";
2362             if (isset($attrs['gosaunittag'][0])){
2363               $after.= "objectClass: gosaAdminiafter\n";
2364               $after.= "gosaUnitTag: ".$attrs['gosaunittag'][0]."\n";
2365             }
2366             $after.= "cn: $name\n";
2367             $after.= "gotoHotplugDevice: $desc|$serial|$vendor|$product\n\n";
2369             $this->device[] = array(
2370                 'CURRENT'     =>  $current,
2371                 'AFTER'       => $after,
2372                 'OLD_DEVICE'  => $entry,
2373                 'DN'          => $attrs['dn'],
2374                 'NEW_DN'      => $newdn,
2375                 'DEVICE_NAME' => $name,
2376                 'DETAILS'     => FALSE);
2377           }
2378         }
2379       }
2381       $this->checks['old_style_devices']['STATUS']    = FALSE;
2382       $this->checks['old_style_devices']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2383       $this->checks['old_style_devices']['ERROR_MSG'] = 
2384         sprintf(_("There are %s devices that need to be migrated."),count($this->device)).
2385           "<input type='submit' name='device_dialog' value='"._("Migrate")."'>";
2386     }else{
2387       $this->checks['old_style_devices']['STATUS']    = TRUE;
2388       $this->checks['old_style_devices']['STATUS_MSG']= _("Ok");
2389       $this->checks['old_style_devices']['ERROR_MSG'] = "";
2390     }
2391   }
2394   /*! \brief  Migrate all selected devices. 
2395               Execute all required ldap actions to migrate the 
2396                selected devices.
2397    */
2398   function migrate_usb_devices ()
2399   {
2400     /* Establish ldap connection */
2401     $cv = $this->parent->captured_values;
2402     $ldap_l = new LDAP($cv['admin'],
2403         $cv['password'],
2404         $cv['connection'],
2405         FALSE,
2406         $cv['tls']);
2408     $ldap = new ldapMultiplexer($ldap_l);
2410     /* Walk through migrateable devices and initiate migration for all 
2411         devices that are checked (DETAILS==TRUE) 
2412      */
2413     foreach($this->device as $key => $device){
2414       if($device['DETAILS']){
2416         /* Get source object and verify that the specified device is a 
2417             member attribute of it. 
2418          */
2419         $ldap->cd($cv['base']);
2420         $ldap->cat($device['DN']);
2421         $attrs = $ldap->fetch();
2422         if(in_array($device['OLD_DEVICE'],$attrs['gotoHotplugDevice'])){
2424           /* Create new hotplug device object 'gotoDevice'
2425            */ 
2426           @list($name,$desc,$serial,$vendor,$product) = explode('|', $device['OLD_DEVICE']);    
2427           $newdn = $device['NEW_DN'];
2428           $new_attr = array();
2429           $new_attr['cn'] = $device['DEVICE_NAME'];
2430           $new_attr['objectClass'] = array('top','gotoDevice');
2431           $new_attr['gotoHotplugDevice'] = "$desc|$serial|$vendor|$product";
2433           /* Add new object 
2434            */
2435           $ldap->cd($cv['base']);
2436           $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$newdn));
2437           $ldap->cd($newdn);
2438           $ldap->add($new_attr);
2440           /* Throw an error message if the action failed. 
2441            */
2442           if(!$ldap->success()){
2443             msg_dialog::display(_("LDAP error"), 
2444                 sprintf(_("Adding '%s' to the LDAP failed: %s"),
2445                   "<b>".LDAP::fix($newdn)."</b>", 
2446                   "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
2447           }else{
2449             /* Remove old style device definition from source object. 
2450              */
2451             $update['gotoHotplugDevice'] = array();
2452             for($i = 0 ; $i < $attrs['gotoHotplugDevice']['count'] ; $i++){
2453               if($attrs['gotoHotplugDevice'][$i] == $device['OLD_DEVICE']){
2454                  continue;
2455               }
2456               $update['gotoHotplugDevice'][] = $attrs['gotoHotplugDevice'][$i];
2457             }
2459             $ldap->cd($device['DN']);
2460             $ldap->modify($update);
2461             $ldap->cat($device['DN'],array("gotoHotplugDevice"));
2462             if(!$ldap->success()){
2463               msg_dialog::display(_("LDAP error"), 
2464                   sprintf(_("Updating '%s' failed: %s"),
2465                     "<b>".LDAP::fix($device['DN'])."</b>", 
2466                     "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2467             }else{
2468               unset($this->device[$key]);
2469             }
2470           }
2471         }
2472       }
2473     }
2474     $this->check_usb_devices();
2475   }
2478   /*! \brief  Check for old style (gosa-2.5) services that have to be migrated
2479                to be useable in gosa-2.6.
2480               All required changes are stored in $this->service, also some
2481                readable informations describing the actions required 
2482                to migrate the service
2483    */
2484   function check_services()
2485   {
2486     /* Establish ldap connection */
2487     $cv = $this->parent->captured_values;
2488     $ldap_l = new LDAP($cv['admin'],
2489         $cv['password'],
2490         $cv['connection'],
2491         FALSE,
2492         $cv['tls']);
2494     $ldap = new ldapMultiplexer($ldap_l);
2495     $this->service = array();
2497     /* Check for Ldap services that must be migrated 
2498      */ 
2499     $ldap->cd($cv['base']);
2500     $res = $ldap->search("(objectClass=goLdapServer)", array("goLdapBase", "cn"));
2502     /* Check if we were able to query the ldap server 
2503      */
2504     if(!$res){
2505       $this->checks['old_style_services']['STATUS']    = FALSE;
2506       $this->checks['old_style_services']['STATUS_MSG']= _("LDAP query failed");
2507       $this->checks['old_style_services']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2508       return;
2509     }
2511     /* Walk through each configured ldap server 
2512         and check if it is configured correctly.
2513      */
2514     while($attrs = $ldap->fetch()){
2515       $dn= $attrs['dn'];
2516       $uri= $attrs['goLdapBase'][0];
2517       if (! preg_match("!^ldaps?://!", $uri)){
2518         $this->service[] = array(
2519             "TYPE"    => "modify" , 
2520             "DN"      => $dn, 
2521             "DETAILS" => FALSE, 
2522             "ATTRS"   => array("goLdapBase" => "ldap://".$attrs['cn'][0]."/$uri"),
2523             "CURRENT" => "goLdapBase: ".$uri,
2524             "AFTER"   => "goLdapBase: "."ldap://".$attrs['cn'][0]."/$uri");
2525       }
2526     }
2528     /* Other sevices following here later ...maybe
2529      */
2531     /*  Update status message
2532      */
2533     if(count($this->service)){
2534       $this->checks['old_style_services']['STATUS']    = FALSE;
2535       $this->checks['old_style_services']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2536       $this->checks['old_style_services']['ERROR_MSG'] =
2537         sprintf(_("There are %s services that need to be migrated."),
2538             count($this->service)).
2539         "<input type='submit' name='service_dialog' value='"._("Migrate")."'>";
2540     }else{
2541       $this->checks['old_style_services']['STATUS']    = TRUE;
2542       $this->checks['old_style_services']['STATUS_MSG']= _("Ok");
2543       $this->checks['old_style_services']['ERROR_MSG'] = "";
2544     }
2545   }
2548   
2549   /*! \brief  Migrate selected services.
2550               This function executes the commands collected by the 
2551                service_check() function.
2552    */
2553   function migrate_services()
2554   {
2555     /* Establish ldap connection 
2556      */
2557     $cv = $this->parent->captured_values;
2558     $ldap_l = new LDAP($cv['admin'],
2559         $cv['password'],
2560         $cv['connection'],
2561         FALSE,
2562         $cv['tls']);
2564     $ldap = new ldapMultiplexer($ldap_l);
2566     /* Handle each service 
2567      */
2568     foreach($this->service as $key => $service){
2569       if($service['DETAILS']){
2571         /* Handle modify requests 
2572          */
2573         if($service['TYPE'] == "modify"){
2574           $ldap->cd($service['DN']);
2575           $ldap->modify($service['ATTRS']);
2577           /* Check if everything done was successful 
2578            */
2579           if(!$ldap->success()){
2580             msg_dialog::display(_("LDAP error"), 
2581                 sprintf(_("Updating '%s' failed: %s"),
2582                   "<b>".LDAP::fix($service['DN'])."</b>", 
2583                   "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2584           }else{
2585         
2586             /* Remove action from list 
2587              */
2588             unset($this->service[$key]);
2589           }
2590         }
2591       }
2592     }
2594     /* Update the service migration status 
2595      */
2596     $this->check_services();
2597   }
2600   /*! \brief  Ensure that posts made on the service migration dialog 
2601                are processed.
2602    */
2603   function check_service_posts()
2604   {
2605     foreach($this->service as $key => $service){
2606       if(isset($_POST["migrate_".$key])){
2607         $this->service[$key]['DETAILS'] =TRUE;
2608       }else{
2609         $this->service[$key]['DETAILS'] =FALSE;
2610       }
2611     }
2612   }
2615   /*! \brief  This function checks the given ldap for old style (gosa-2.5) 
2616                menu entries and will prepare a list of actions that are required
2617                to migrate them to gosa-2.6.
2618               All required actions and some readable informations are stored in 
2619                $this->menu.
2620    */
2621   function check_menus()
2622   {
2623     /* Establish ldap connection
2624      */
2625     $cv = $this->parent->captured_values;
2626     $ldap_l = new LDAP($cv['admin'],
2627         $cv['password'],
2628         $cv['connection'],
2629         FALSE,
2630         $cv['tls']);
2632     $ldap = new ldapMultiplexer($ldap_l);
2634     /* First detect all release names 
2635      */
2636     $ldap->cd($cv['base']);
2637     $res = $ldap->search("(&(objectClass=organizational)(objectClass=FAIbranch))",array("ou","objectClass"));
2639     /* Check if we were able to query the ldap server
2640      */
2641     if(!$res){
2642       $this->checks['old_style_menus']['STATUS']    = FALSE;
2643       $this->checks['old_style_menus']['STATUS_MSG']= _("LDAP query failed");
2644       $this->checks['old_style_menus']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2645       return;
2646     }
2648     /* Create application -> parameter mapping, used later to detect 
2649         which configured parameter belongs to which application entry.
2650      */
2651     $amap= array();
2652     $todo = array();
2653     $ldap->cd($cv['base']);
2654     $ldap->search("(objectClass=gosaApplication)", array("cn", "gosaApplicationParameter"));
2655     while($info = $ldap->fetch()){
2656       if (isset($info['gosaApplicationParameter']['count'])){
2657         for ($j= 0; $j < $info['gosaApplicationParameter']['count']; $j++){
2658           $p= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$j]);
2660           if(!isset($amap[$info['cn'][0]]) || !in_array($p, $amap[$info['cn'][0]])){
2661             $amap[$info['cn'][0]][]= $p;
2662           }
2663         }
2664       } else {
2665         $amap[$info['cn'][0]]= array();
2666       }
2667     }
2669     /* Search for all groups that have an old style application menu configured.
2670      */  
2671     $appgroups = array();
2672     $ldap->cd($cv['base']);
2673     $ldap->search("(&(objectClass=gosaApplicationGroup)(objectClass=posixGroup)(FAIrelease=*))",
2674         array("gosaMemberApplication","gosaApplicationParameter","FAIrelease","objectClass","gosaUnitTag"));
2676     /* Create readable prefix for "What will be done" infos 
2677      */
2678     $s_add = "<i>"._("Add")."</i>\t";
2679     $s_del = "<i>"._("Remove")."</i>\t";
2681     /* Walk through all found old-style menu configurations.
2682         -Prepare ldap update list     $data   
2683         -Prepare printable changes    $after/$current
2684      */
2685     while($info = $ldap->fetch()){
2687       $data = array();
2688       $current = "";
2689       $after ="";
2691       /* Get unit tag 
2692        */
2693       $tag ="";
2694       if(isset($info['gosaUnitTag'])){
2695         $tag = $info['gosaUnitTag'][0];
2696       }
2698       /* Collect application parameter for this group
2699        */
2700       $params= array();
2701       if(isset($info['gosaApplicationParameter'])){
2702         for ($i= 0; $i < $info['gosaApplicationParameter']['count']; $i++){
2703           $name= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$i]);
2704           $params[$name]= $info['gosaApplicationParameter'][$i];
2705         }
2706       }
2708       /* Create release container for each release/subrelease.
2709          eg.   "sisa/1.0.0":
2710          .       "ou=siga, ..."
2711          .       "ou=1.0.0,ou=siga, .."
2712        */ 
2713       $release = "";
2714       $r = $info['FAIrelease'][0];
2715       $z = split("/",$r);
2716       foreach($z as $part){
2718         if(!empty($part)){
2719           $release = "ou=".$part.",".$release;
2721           /* Append release department information to "What will be done" info
2722            */
2723           $release_dn = $release.$info['dn'];
2724           $after   .=  $s_add."dn: $release_dn\n";
2725           $after   .=  $s_add."objectClass: top\n";
2726           $after   .=  $s_add."objectClass: FAIbranch\n";
2727           $after   .=  $s_add."objectClass: organizationalUnit\n";
2728          
2729           /* Append UnitTag 
2730            */ 
2731           if($tag != ""){ 
2732             $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2733             $after   .=  $s_add."gosaUnitTag: $tag\n";
2734           }
2735           $after   .=  $s_add."ou: $part\n";
2737           /* Append release data to ldap actions 
2738            */
2739           $d = array();
2740           $d['objectClass'] = array("top","FAIbranch","organizationalUnit");
2741           if(!empty($tag)){
2742             $d['objectClass'][] = "gosaAdministrativeUnitTag";
2743             $d['gosaUnitTag']   = $tag;
2744           }
2745           $d['ou']          = $part;
2746           $data['ADD'][$release_dn]= $d;
2747         }
2748       }
2750       /* Add member applications to the array.
2751        */ 
2752       $current .= "dn: ".$info['dn']."\n";
2753       $menu_structure = array();
2754       for ($i= 0; $i < $info['gosaMemberApplication']['count']; $i++){
2755         list($name, $location, $priority)= explode("|", $info['gosaMemberApplication'][$i]);
2757         /* Create location dn 
2758          */
2759         $location_dn ="";
2760         if(!empty($location)){
2761           $location_dn ="cn=".$location.",";
2762         }
2764         /* Append old style element to current detail informations 
2765          */      
2766         $current .= $s_del."gosaMemberApplication: ".$info['gosaMemberApplication'][$i]."\n";
2768         /* Append ldap update action to remove the old menu entry attributes 
2769          */
2770         unset($info['objectClass']['count']);
2771         $d = array();
2772         $d['gosaMemberApplication']      = array();
2773         $d['gosaApplicationParameter']  = array();
2774         if(isset($info['FAIrelease'])){
2775           $d['FAIrelease'] = array();
2776         }
2777         $d['objectClass']               = array_remove_entries(array("gosaApplicationGroup","FAIreleaseTag"),$info['objectClass']);
2778         $data['MODIFY'][$info['dn']]    = $d;
2780         /* Create new application menu structure 
2781          */
2782         if (isset($amap[$name])){
2784           /* Append missing menu structure to "What is done info"
2785            */
2786           if(!isset($menu_structure[$location]) && !empty($location)){
2787             $menu_structure[$location] = TRUE;
2788             $after .= "\n";
2789             $after .= $s_add."dn: $location_dn$release_dn\n";
2790             $after .= $s_add."objectClass: gotoSubmenuEntry\n";
2792             /* Append UnitTag
2793              */
2794             if($tag != ""){
2795               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2796               $after   .=  $s_add."gosaUnitTag: $tag\n";
2797             }
2798             $after .= $s_add."cn: $location\n";
2799   
2800             /* Create ldap entry to append 
2801              */
2802             $d = array();
2803             $d['cn'] = $location;
2804             $d['objectClass'] = array("gotoSubmenuEntry");
2805             if(!empty($tag)){
2806               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2807               $d['gosaUnitTag']   = $tag;
2808             }
2809             $data['ADD'][$location_dn.$release_dn] = $d;
2810           }
2813           /* Append missing menu entry for "What is done info".
2814            */
2815           if(!empty($name)){
2816             $after .= "\n";
2817             $after .= $s_add."dn: cn=$name,$location_dn$release_dn\n";
2818             $after .= $s_add."objectClass: gotoMenuEntry\n";
2819             if($tag != ""){
2820               $after   .=  $s_add."objectClass: gosaAdministrativeUnitTag\n";
2821               $after   .=  $s_add."gosaUnitTag: $tag\n";
2822             }
2823             $after .= $s_add."cn: $name\n";
2824             $after .= $s_add."gosaApplicationPriority: $priority\n";
2826             /* Create ldap entry 
2827              */
2828             $d= array();
2829             $d['objectClass'] = array("gotoMenuEntry");
2830             if(!empty($tag)){
2831               $d['objectClass'][] = "gosaAdministrativeUnitTag";
2832               $d['gosaUnitTag']   = $tag;
2833             }
2834             $d['cn']          = $name;
2835             $d['gosaApplicationPriority'] = $priority;
2837             foreach ($amap[$name] as $n){
2838               if (isset($params[$n])){
2839                 $after .= $s_add."gosaApplicationParameter: ".$params[$n]."\n";
2840                 $d['gosaApplicationParameter'][] = $params[$n];
2841               }
2842             }
2843             $data['ADD']["cn=$name,$location_dn$release_dn"] = $d;
2844           }         
2845         }
2846       }
2848       /* Updated todo list 
2849        */ 
2850       $todo[] = array(
2851           "DETAILS" => FALSE,
2852           "DN"      => $info['dn'],
2853           "AFTER"   => $after,
2854           "CURRENT" => $current,
2855           "TODO"    => $data
2856           );
2857     }
2859     /* Remember checks.
2860      */
2861     $this->menu = $todo;
2863     /* Check if we were able to query the ldap server
2864      */
2865     if(count($this->menu)){
2866       $this->checks['old_style_menus']['STATUS']    = FALSE;
2867       $this->checks['old_style_menus']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2868       $this->checks['old_style_menus']['ERROR_MSG'] = sprintf(_("There are %s application menus which have to be migrated."),
2869                                                       count($this->menu))."<input type='submit' name='menu_dialog' value='"._("Migrate")."'>";
2870     }else{
2871       $this->checks['old_style_menus']['STATUS']    = TRUE;
2872       $this->checks['old_style_menus']['STATUS_MSG']= _("Ok");
2873       $this->checks['old_style_menus']['ERROR_MSG'] = "";
2874     }
2875   }
2877   
2878   /*! \brief  Handle posts for the menu_dialog 
2879               Ensure that checked checkboxes stay checked.
2880    */
2881   function check_menu_posts()
2882   {
2883     foreach($this->menu as $key => $menu){
2884       if(isset($_POST["migrate_".$key])){
2885         $this->menu[$key]['DETAILS'] =TRUE;
2886       }else{
2887         $this->menu[$key]['DETAILS'] =FALSE;
2888       }
2889     }
2890   }
2893   /*! \brief  This function updates old-style application menus to
2894                valid 2.6 application menus.
2895               All selected menus will be converted (DETAILS = TRUE). 
2896               The ldap actions collected by check_menus() will be executed. 
2897    */
2898   function migrate_menus()
2899   {
2901     /* Establish ldap connection
2902      */
2903     $cv = $this->parent->captured_values;
2904     $ldap_l = new LDAP($cv['admin'],
2905         $cv['password'],
2906         $cv['connection'],
2907         FALSE,
2908         $cv['tls']);
2910     $ldap = new ldapMultiplexer($ldap_l);
2911     $ldap->cd($cv['base']);
2913     /* Walk through menus and detect selected menu 
2914      */
2915     foreach($this->menu as $key => $menu){
2916       if($menu['DETAILS']) {
2918         /* Excute all LDAP-ADD actions 
2919          */
2920         $success = TRUE;
2921         foreach($menu['TODO']['ADD'] as $dn => $data){
2922           $ldap->cd($cv['base']);
2923           if(!$ldap->dn_exists($dn)){
2924             $ldap->cd($dn);
2925             $ldap->add($data);
2926             if (!$ldap->success()){
2927               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
2928               $success = FALSE;
2929             }
2930           }
2931         }
2933         /* Execute all LDAP-MODIFY actions 
2934          */
2935         foreach($menu['TODO']['MODIFY'] as $dn => $data){
2936           $ldap->cd($cv['base']);
2937           if($ldap->dn_exists($dn)){
2938             $ldap->cd($dn);
2939             $ldap->modify($data);
2940             if (!$ldap->success()){
2941               msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
2942               $success = FALSE;
2943             }
2944           }
2945         }
2946   
2947         /* If every action was successful, remove this entry from the list 
2948          */
2949         if($success){
2950           unset($this->menu[$key]);
2951         }
2952       }
2953     }
2955     /* Udpate migration status for application menus
2956      */
2957     $this->check_menus();
2958   }
2961   function migrate_selected_admin_users()
2962   {
2963     /* Updated ui selection */
2964     $this->migrate_users();
2966     /* Establish ldap connection */
2967     $cv = $this->parent->captured_values;
2968     $ldap_l = new LDAP($cv['admin'],
2969         $cv['password'],
2970         $cv['connection'],
2971         FALSE,
2972         $cv['tls']);
2974     $ldap = new ldapMultiplexer($ldap_l);
2975     $ldap->cd($cv['base']);
2977     /* Get current ACL configuration for the ldap base 
2978      */
2979     $ldap->cat($cv['base']);
2980     $base_attrs = $ldap->fetch();
2981     $acl_entries= array();
2982     $acl_id = -1;
2983     if(isset($base_attrs['gosaAclEntry'])){
2984       for($i=0; $i < $base_attrs['gosaAclEntry']['count']; $i ++){
2985         $acl_entries[] = $base_attrs['gosaAclEntry'][$i];
2986         $cur_id = preg_replace("/^([0-9]*):.*$/","\\1",$base_attrs['gosaAclEntry'][$i]);
2987         if($cur_id > $acl_id){
2988           $acl_id = $cur_id;
2989         }
2990       }
2991     }
2993     /* Append ACLs selected in the migrate admin account dialog 
2994      */
2995     foreach($this->migrate_users as $entry){
2996       if($entry['checked']){
2997         $acl_id ++;
2998         $acl_entries[] = $acl_id.$entry['change'];
2999       }
3000     }
3001    
3002     /* Check if the required objectClasses are available 
3003      */
3004     $ocs = array();     
3005     for($i=0;$i< $base_attrs['objectClass']['count']; $i++){
3006       $ocs[] = $base_attrs['objectClass'][$i];
3007     }
3008     if(!in_array("gosaACL",$ocs)){
3009       $ocs[] = "gosaACL";
3010     }
3012     /* Try to write changes 
3013      */
3014     if(count($acl_entries)){
3015       $new_entry['gosaAclEntry'] = $acl_entries;
3016       $new_entry['objectClass'] = $ocs;
3017       $ldap->cd($cv['base']);
3018       $ldap->modify($new_entry);
3019       if(!$ldap->success()){
3020         $this->checks['acls']['TITLE']     = _("Checking for super administrator");
3021         $this->checks['acls']['STATUS']    = FALSE;
3022         $this->checks['acls']['STATUS_MSG']= _("Failed");
3023         $this->checks['acls']['ERROR_MSG'] = "<br>".msgPool::ldaperror($cv['base'],$ldap->get_error(),LDAP_MOD);
3024       }else{
3025         $this->check_administrativeAccount();
3026       }     
3027     }
3028   }
3029   
3031   function migrate_users()
3032   {
3033     /* Collect a list of available GOsa users and groups 
3034      */
3036     /* Establish ldap connection */
3037     $cv = $this->parent->captured_values;
3038     $ldap_l = new LDAP($cv['admin'],
3039         $cv['password'],
3040         $cv['connection'],
3041         FALSE,
3042         $cv['tls']);
3044     $ldap = new ldapMultiplexer($ldap_l);
3045     $ldap->cd($cv['base']);
3047     $users = array();
3048     $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
3049         "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
3050     while($user_attrs = $ldap->fetch()){
3051       $users[$user_attrs['dn']] = $user_attrs['uid'][0];
3052       $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
3053     }
3054     $groups = array();
3055     $ldap->search("objectClass=posixGroup",array("cn","dn"));
3056     while($group_attrs = $ldap->fetch()){
3057       $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
3058     }
3060     foreach($this->migrate_users as $id => $data){
3061       $this->migrate_users[$id]['checked'] = isset($_POST['migrate_admin_'.$id]);
3062     }
3064     /* Try to find an old GOsa 2.5 administrative account that may be migrated
3065      */
3066     if(!count($this->migrate_users)){
3067       $ldap->cat($cv['base']);
3068       $base_data = $ldap->fetch();
3069       $base_entry = "dn: ".$base_data['dn']."\n";
3070       for($i=0;$i<$base_data['objectClass']['count'];$i++){
3071         $base_entry .= "objectClass: ".$base_data['objectClass'][$i]."\n";
3072       }
3073       if(!in_array("gosaACL",$base_data['objectClass'])){
3074         $base_entry .= "<b>objectClass: gosaACL</b>\n";
3075       }
3076       if(isset($base_data['gosaAclEntry'])){
3077         for($i=0;$i<$base_data['gosaAclEntry']['count'];$i++){
3078           $base_entry .= "gosaAclEntry: ".$base_data['gosaAclEntry'][$i]."\n";
3079         }
3080       }
3081       $this->migrate_acl_base_entry = $base_entry;
3082       $ldap->cd($cv['base']);
3083       $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
3084       while($p_group = $ldap->fetch()){
3085         for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
3086           $user = $p_group['memberUid'][$e];
3087           if(isset($rusers[$user])){
3088             $bsp_acl_entry = "gosaAclEntry: #:psub:".base64_encode($rusers[$user]).":all;cmdrw\n";
3089             $entry = array();
3090             $entry['uid'] = $user; 
3091             $entry['dn'] = $rusers[$user]; 
3092             $entry['details'] = $bsp_acl_entry; 
3093             $entry['checked'] = FALSE;
3094             $entry['change'] = ":psub:".base64_encode($rusers[$user]).":all;cmdrw";
3095             $this->migrate_users[] = $entry;
3096           }
3097         }
3098       }
3099     }
3100   }
3102 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
3103 ?>