Code

652f379f3af0280641def60c97c56d3e728d474a
[gosa.git] / setup / class_setupStep_Migrate.inc
1 <?php
3 /*
4    This code is part of GOsa (https://gosa.gonicus.de)
5    Copyright (C) 2007 Fabian Hickert
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
23 class Step_Migrate extends setup_step
24 {
25   var $languages      = array();
26   var $attributes     = array();
27   var $header_image   = "images/monitoring.png";
28   var $checks         = array();
30   /* Department migration attributes */
31   var $dep_migration_dialog = FALSE;
32   var $deps_to_migrate      = array();
34   /* Department migration attributes */
35   var $users_migration_dialog= FALSE;
36   var $users_to_migrate      = array();
38   function Step_Migrate()
39   {
40     $this->update_strings(); 
41     $this->initialize_checks();
42   }
44   function update_strings()
45   {
46     $this->s_title      = _("LDAP inspection");
47     $this->s_title_long = _("LDAP inspection");
48     $this->s_info       = _("Analyze your current LDAP for GOsa compatibility");
49   }
51   function initialize_checks()
52   {
53     $this->checks = array();
54     $this->checks['permissions']['TITLE']     = _("Checking permissions on ldap database");
55     $this->checks['permissions']['STATUS']    = FALSE;
56     $this->checks['permissions']['STATUS_MSG']= "";
57     $this->checks['permissions']['ERROR_MSG'] = "";
58     $this->check_ldap_permissions();
60     $this->checks['deps_visible']['TITLE']     = _("Checking for invisible deparmtments");
61     $this->checks['deps_visible']['STATUS']    = FALSE;
62     $this->checks['deps_visible']['STATUS_MSG']= "";
63     $this->checks['deps_visible']['ERROR_MSG'] = "";
64     $this->check_visible_organizationalUnits();
66     $this->checks['users_visible']['TITLE']     = _("Checking for invisible user");
67     $this->checks['users_visible']['STATUS']    = FALSE;
68     $this->checks['users_visible']['STATUS_MSG']= "";
69     $this->checks['users_visible']['ERROR_MSG'] = "";
70     $this->check_invisible_gosaAccounts();
71   }
74   /* Check ldap accessibility 
75    * Create and remove a dummy object, 
76    *  to ensure that we have the necessary permissions
77    */
78   function check_ldap_permissions()
79   {
80     $cv = $this->parent->captured_values;
81     $ldap = new LDAP($cv['admin'],
82         $cv['password'],
83         $cv['connection'],
84         FALSE,
85         $cv['tls']);
87     /* Create dummy entry 
88      */
89     $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
90     $dn       = "ou=".$name.",".$cv['base'];
91     $testEntry= array();
92     $testEntry['objectClass'][]= "top";
93     $testEntry['objectClass'][]= "organizationalUnit";
94     $testEntry['objectClass'][]= "gosaDepartment";
95     $testEntry['description']= "Created by GOsa setup, this object can be removed.";
96     $testEntry['ou']  = $name;
98     /* Try to create dummy object 
99      */ 
100     $ldap->cd ($dn);
101     $res = $ldap->add($testEntry);
102     if(!$res){
103       $this->checks['permissions']['STATUS']    = FALSE;
104       $this->checks['permissions']['STATUS_MSG']= _("Failed");
105       $this->checks['permissions']['ERROR_MSG'] = 
106         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
107       $this->checks['permissions']['ERROR_MSG'].=
108         "<input type='submit' name='retry_permissions' value='"._("Retry")."'>";
109       return(false);
110     }
112     /* Try to remove created entry 
113      */
114     $res = $ldap->rmDir($dn);
115     if(!$res){
116       $this->checks['permissions']['STATUS']    = FALSE;
117       $this->checks['permissions']['STATUS_MSG']= _("Failed");
118       $this->checks['permissions']['ERROR_MSG'] = 
119         sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
120       $this->checks['permissions']['ERROR_MSG'].=
121         "<input type='submit' name='retry_permissions' value='"._("Retry")."'>";
122       return(false);
123     }
125     /* Create & remove of dummy object was successful */
126     $this->checks['permissions']['STATUS']    = TRUE;
127     $this->checks['permissions']['STATUS_MSG']= _("Ok");
128     $this->checks['permissions']['ERROR_MSG'] = "<input type='submit' name='retry_permissions' value='"._("Retry")."'>";
129     return(true);
130   } 
133   /* Check if there are users which will 
134    *  be invisible for GOsa 
135    */
136   function check_invisible_gosaAccounts()
137   {
138     /* Remember old list of ivisible users, to be able to set 
139      *  the 'html checked' status for the checkboxes again 
140      */
141     $cnt_ok = 0;
142     $old    = $this->users_to_migrate;
143     $this->users_to_migrate = array();
145     /* Get collected configuration settings */
146     $cv = $this->parent->captured_values;
148     /* Establish ldap connection */
149     $ldap = new LDAP($cv['admin'],
150         $cv['password'],
151         $cv['connection'],
152         FALSE,
153         $cv['tls']);
155     /* Get all invisible users 
156      */
157     $ldap->cd($cv['base']); 
158     $ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
159     while($attrs = $ldap->fetch()){
160       if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
161         $attrs['checked'] = FALSE;
162         $attrs['before']  = "";
163         $attrs['after']   = "";
165         /* Set objects to selected, that were selected before reload */
166         if(isset($old[base64_encode($attrs['dn'])])){
167           $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
168         }
169         $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
170       }
171     }
173     /* No invisible */
174     if(count($this->users_to_migrate) == 0){
175       $this->checks['users_visible']['STATUS']    = TRUE;
176       $this->checks['users_visible']['STATUS_MSG']= _("Ok");
177       $this->checks['users_visible']['ERROR_MSG'] = "";
178       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate_refresh' value='"._("Retry")."'>";
179     }else{
180       $this->checks['users_visible']['STATUS']    = FALSE;
181       $this->checks['users_visible']['STATUS_MSG']= "";
182       $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."), 
183           count($this->users_to_migrate));
184       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
185       $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate_refresh' value='"._("Reload list").   "'>";
186     }
187   }
190   /* Start user account migration 
191    */  
192   function migrate_gosaAccounts($only_ldif = FALSE)
193   {
194     /* Get collected configuration settings */
195     $cv = $this->parent->captured_values;
197     /* Establish ldap connection */
198     $ldap = new LDAP($cv['admin'],
199         $cv['password'],
200         $cv['connection'],
201         FALSE,
202         $cv['tls']);
204     /* Add gosaAccount objectClass to the selected users  
205      */
206     foreach($this->users_to_migrate as $key => $dep){
207       if($dep['checked']){
209         /* Get old objectClasses */
210         $ldap->cat($dep['dn'],array("objectClass"));
211         $attrs      = $ldap->fetch();
213         /* Create new objectClass array */
214         $new_attrs  = array();
215         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
216           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
217         }
218         $new_attrs['objectClass'][] = "gosaAccount";
220         /* Set info attributes for current object, 
221          *  or write changes to the ldap database 
222          */
223         if($only_ldif){
224           $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
225           $this->users_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
226         }else{
227           $ldap->cd($attrs['dn']);
228           if(!$ldap->modify($new_attrs)){
229             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
230             return(false);
231           }
232         }
233       }
234     }
235     return(TRUE);
236   }
239   /* Check if there are invisible organizational Units 
240    */
241   function check_visible_organizationalUnits()
242   {
243     $cnt_ok = 0;
244     $old = $this->deps_to_migrate;
245     $this->deps_to_migrate = array();
247     /* Get collected configuration settings */
248     $cv = $this->parent->captured_values;
250     /* Establish ldap connection */
251     $ldap = new LDAP($cv['admin'],
252         $cv['password'],
253         $cv['connection'],
254         FALSE,
255         $cv['tls']);
257     /* Skip GOsa internal departments */
258     $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
259         "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
260         "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
261         "/(,|)ou=winstations,/");
264     /* Get all invisible departments */
265     $ldap->cd($cv['base']); 
266     $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
267     while($attrs = $ldap->fetch()){
268       $attrs['checked'] = FALSE;
269       $attrs['before']  = "";
270       $attrs['after']   = "";
272       /* Set objects to selected, that were selected before reload */
273       if(isset($old[base64_encode($attrs['dn'])])){
274         $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
275       }
276       $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
277     }
279     /* Filter returned list of departments and ensure that 
280      *  GOsa internal departments will not be listed 
281      */
282     foreach($this->deps_to_migrate as $key => $attrs){
283       $dn = $attrs['dn'];
284       $skip = false;
285       foreach($skip_dns as $skip_dn){
286         if(preg_match($skip_dn,$dn)){
287           $skip = true;
288         }
289       }
290       if($skip){
291         unset($this->deps_to_migrate[$key]);
292       }
293     }
295     /* If we have no invisible departments found  
296      *  tell the user that everything is ok 
297      */
298     if(count($this->deps_to_migrate) == 0){
299       $this->checks['deps_visible']['STATUS']    = TRUE;
300       $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
301       $this->checks['deps_visible']['ERROR_MSG'] = "";
302       $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate_refresh' value='"._("Retry")."'>";
303     }else{
304       $this->checks['deps_visible']['STATUS']    = FALSE;
305       $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
306       $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
307       $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
308       $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate_refresh' value='"._("Reload list")."'>";
309     }
310   }
314   /* Start deparmtment migration */  
315   function migrate_organizationalUnits($only_ldif = FALSE)
316   {
317     /* Get collected configuration settings */
318     $cv = $this->parent->captured_values;
320     /* Establish ldap connection */
321     $ldap = new LDAP($cv['admin'],
322         $cv['password'],
323         $cv['connection'],
324         FALSE,
325         $cv['tls']);
327     /* Add gosaDepartment objectClass to each selected entry 
328      */
329     foreach($this->deps_to_migrate as $key => $dep){
330       if($dep['checked']){
332         /* Get current objectClasses */
333         $ldap->cat($dep['dn'],array("objectClass","description"));
334         $attrs      = $ldap->fetch();
336         /* Create new objectClass attribute including gosaDepartment*/
337         $new_attrs  = array();
338         for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
339           $new_attrs['objectClass'][]   = $attrs['objectClass'][$i];
340         }
341         $new_attrs['objectClass'][] = "gosaDepartment";
343         /* Append description it is missing */
344         if(!isset($attrs['description'])){
345           $new_attrs['description'][] = "GOsa department";
346         }
348         /* Depending on the parameter >only_diff< we save the changes as ldif
349          *  or we write our changes directly to the ldap database
350          */
351         if($only_ldif){
352           $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
353           $this->deps_to_migrate[$key]['after']  = $this->array_to_ldif($new_attrs);
354         }else{
355           $ldap->cd($attrs['dn']);
356           if(!$ldap->modify($new_attrs)){
357             print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
358             return(false);
359           }
360         }
361       }
362     }
363     return(TRUE);
364   }
368   function execute()
369   {
370     /* Permission check */
371     $this->check_ldap_permissions();
374     /*************
375      * User Migration handling 
376      *************
378     /* Refresh list of deparments */
379     if(isset($_POST['users_visible_migrate_refresh'])){
380       $this->check_invisible_gosaAccounts();
381     }
383     /* Open migration dialog */
384     if(isset($_POST['users_visible_migrate'])){
385       $this->users_migration_dialog = TRUE;
386       $this->dialog =TRUE;
387     }
389     /* Close migration dialog */
390     if(isset($_POST['users_visible_migrate_close'])){
391       $this->users_migration_dialog = FALSE;
392       $this->dialog =FALSE;
393     }
395     /* Start migration */
396     if(isset($_POST['users_visible_migrate_migrate'])){
397       if($this->migrate_gosaAccounts()){
398         $this->check_invisible_gosaAccounts();
399       }
400     }
402     /* Start migration */
403     if(isset($_POST['users_visible_migrate_whatsdone'])){
404       $this->migrate_gosaAccounts(TRUE);
405     }
407     /* Display migration dialog */
408     if($this->users_migration_dialog){
409       $smarty = get_smarty();
410       $smarty->assign("users_to_migrate",$this->users_to_migrate);
411       $smarty->assign("method","migrate_users");
412       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
413     }
416     /*************
417      * Department Migration handling 
418      *************
420     /* Refresh list of deparments */
421     if(isset($_POST['deps_visible_migrate_refresh'])){
422       $this->check_visible_organizationalUnits();
423     }
425     /* Open migration dialog */
426     if(isset($_POST['deps_visible_migrate'])){
427       $this->dep_migration_dialog = TRUE;
428       $this->dialog =TRUE;
429     }
431     /* Close migration dialog */
432     if(isset($_POST['deps_visible_migrate_close'])){
433       $this->dep_migration_dialog = FALSE;
434       $this->dialog =FALSE;
435     }
437     /* Start migration */
438     if(isset($_POST['deps_visible_migrate_migrate'])){
439       if($this->migrate_organizationalUnits()){
440         $this->check_visible_organizationalUnits();
441       }
442     }
444     /* Start migration */
445     if(isset($_POST['deps_visible_migrate_whatsdone'])){
446       $this->migrate_organizationalUnits(TRUE);
447     }
449     /* Display migration dialog */
450     if($this->dep_migration_dialog){
451       $smarty = get_smarty();
452       $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
453       $smarty->assign("method","migrate_deps");
454       return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
455     }
457     $smarty = get_smarty();
458     $smarty->assign("checks",$this->checks);
459     $smarty->assign("method","default");
460     return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
461   }
463   function save_object()
464   {
465     /* Get selected departments */
466     if($this->dep_migration_dialog){
467       foreach($this->deps_to_migrate as $id => $data){
468         if(isset($_POST['migrate_'.$id])){
469           $this->deps_to_migrate[$id]['checked'] = TRUE;
470         }else{
471           $this->deps_to_migrate[$id]['checked'] = FALSE;
472         }
473       }
474     }
476     /* Get selected users */
477     if($this->users_migration_dialog){
478       foreach($this->users_to_migrate as $id => $data){
479         if(isset($_POST['migrate_'.$id])){
480           $this->users_to_migrate[$id]['checked'] = TRUE;
481         }else{
482           $this->users_to_migrate[$id]['checked'] = FALSE;
483         }
484       }
485     }
487   }
490   /* Return ldif information for a 
491    * given attribute array 
492    */
493   function array_to_ldif($atts)
494   {
495     $ret = "";
496     unset($atts['count']);
497     unset($atts['dn']);
498     foreach($atts as $name => $value){
499       if(is_numeric($name)) {
500         continue;
501       }
502       if(is_array($value)){
503         unset($value['count']);
504         foreach($value as $a_val){
505           if(!preg_match('/^[a-z0-9+@#.=, \/ -]+$/i', $a_val)){
506             $ret .= $name.":: ". base64_encode($a_val)."\n";
507           }else{
508             $ret .= $name.": ". $a_val."\n";
509           }
510         }
511       }else{
512         if(!preg_match('/^[a-z0-9+@#.=, \/ -]+$/i', $value)){
513           $ret .= $name.": ". base64_encode($value)."\n";
514         }else{
515           $ret .= $name.": ". $value."\n";
516         }
517       }
518     }
519     return(preg_replace("/\n$/","",$ret));
520   }
523 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
524 ?>