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