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 }
521 }
523 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
524 ?>