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 = explode(":",$acl);
926 if($tmp[1] == "psub"){
927 $members = explode(",",$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 = explode(",",$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 }
1055 // Reload base OC
1056 $this->checkBaseOC();
1057 return($GOsa_26_found);
1058 }
1062 function create_admin($only_ldif = FALSE)
1063 {
1064 /* Reset '' */
1065 $this->acl_create_changes="";
1067 /* Object that should receive admin acls */
1068 $dn = $this->acl_create_selected;
1070 /* Get collected configuration settings */
1071 $cv = $this->parent->captured_values;
1073 /* On first call check for rid/sid base */
1074 $ldap_l = new LDAP($cv['admin'],
1075 $cv['password'],
1076 $cv['connection'],
1077 FALSE,
1078 $cv['tls']);
1080 $ldap = new ldapMultiplexer($ldap_l);
1082 /* Get current base attributes */
1083 $ldap->cd($cv['base']);
1084 $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
1085 $attrs = $ldap->fetch();
1087 /* Add acls for the selcted user to the base */
1088 $attrs_new = array();
1089 $attrs_new['objectClass'] = array("gosaACL");
1091 for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
1092 if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
1093 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
1094 }
1095 }
1097 $acl = "0:psub:".base64_encode($dn).":all;cmdrw";
1098 $attrs_new['gosaAclEntry'][] = $acl;
1099 if(isset($attrs['gosaAclEntry'])){
1100 for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
1102 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
1103 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
1105 $data = ($prio+1).$rest;
1106 $attrs_new['gosaAclEntry'][] = $data;
1107 }
1108 }
1110 if($only_ldif){
1111 $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
1112 $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
1113 $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
1114 $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
1115 }else{
1117 $ldap->cd($cv['base']);
1118 if(!$ldap->modify($attrs_new)){
1119 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);
1120 return(FALSE);
1121 }else{
1122 return(TRUE);
1123 }
1124 }
1125 }
1128 function create_admin_user()
1129 {
1130 $pw1 = $pw2 = "";
1131 $uid = "";
1133 /* On first call check for rid/sid base */
1134 $cv = $this->parent->captured_values;
1135 $ldap_l = new LDAP($cv['admin'],
1136 $cv['password'],
1137 $cv['connection'],
1138 FALSE,
1139 $cv['tls']);
1141 $ldap = new ldapMultiplexer($ldap_l);
1143 if(isset($_POST['new_user_uid'])){
1144 $uid = $_POST['new_user_uid'];
1145 }
1146 if(isset($_POST['new_user_password'])){
1147 $pw1 = $_POST['new_user_password'];
1148 }
1149 if(isset($_POST['new_user_password2'])){
1150 $pw2 = $_POST['new_user_password2'];
1151 }
1154 $ldap->cd($cv['base']);
1155 $ldap->search("(uid=".$uid.")");
1156 if($ldap->count()){
1157 msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
1158 return false;
1159 }
1161 if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
1162 msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
1163 return false;
1164 }
1166 if(!tests::is_uid($uid) || empty($uid)){
1167 msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
1168 return false;
1169 }
1172 /* Get current base attributes */
1173 $ldap->cd($cv['base']);
1175 $people_ou = trim($cv['peopleou']);
1176 if(!empty($people_ou)){
1177 $people_ou = trim($people_ou).",";
1178 }
1180 if($cv['peopledn'] == "cn"){
1181 $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
1182 }else{
1183 $dn = "uid=".$uid.",".$people_ou.$cv['base'];
1184 }
1186 $hash = passwordMethod::make_hash($pw2, $cv['encryption']);
1188 $new_user=array();
1189 $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
1190 $new_user['givenName'] = "System";
1191 $new_user['sn'] = "Administrator";
1192 $new_user['cn'] = "System Administrator-".$uid;
1193 $new_user['uid'] = $uid;
1194 $new_user['userPassword'] = $hash;
1196 $ldap->cd($cv['base']);
1198 $ldap->cat($dn,array("dn"));
1199 if($ldap->count()){
1200 msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
1201 return(FALSE);
1202 }
1204 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
1205 $ldap->cd($dn);
1206 $res = $ldap->add($new_user);
1207 $this->acl_create_selected = $dn;
1208 $this->create_admin();
1210 if(!$res){
1211 msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
1212 return(FALSE);
1213 }
1215 $this->acl_create_dialog=FALSE;
1216 $this->check_administrativeAccount();
1217 return(TRUE);
1218 }
1221 function migrate_outside_winstations($perform = FALSE)
1222 {
1223 /* Establish ldap connection */
1224 $cv = $this->parent->captured_values;
1225 $ldap_l = new LDAP($cv['admin'],
1226 $cv['password'],
1227 $cv['connection'],
1228 FALSE,
1229 $cv['tls']);
1231 $ldap = new ldapMultiplexer($ldap_l);
1233 $ldap->cd($cv['base']);
1235 /* Check if there was a destination department posted */
1236 if(isset($_POST['move_winstation_to'])){
1237 $destination_dep = $_POST['move_winstation_to'];
1238 }else{
1239 msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1240 return(false);
1241 }
1243 foreach($this->outside_winstations as $b_dn => $data){
1244 $this->outside_winstations[$b_dn]['ldif'] ="";
1245 if($data['selected']){
1246 $dn = base64_decode($b_dn);
1247 $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1248 if(!$perform){
1249 $this->outside_winstations[$b_dn]['ldif'] = _("Winstation will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1252 /* Check if there are references to this object */
1253 $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1254 $refs = "";
1255 while($attrs = $ldap->fetch()){
1256 $ref_dn = $attrs['dn'];
1257 $refs .= "<br />\t".$ref_dn;
1258 }
1259 if(!empty($refs)){
1260 $this->outside_winstations[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1261 }
1263 }else{
1264 $this->move($dn,$d_dn);
1265 }
1266 }
1267 }
1268 }
1271 function migrate_outside_groups($perform = FALSE)
1272 {
1273 /* Establish ldap connection */
1274 $cv = $this->parent->captured_values;
1275 $ldap_l = new LDAP($cv['admin'],
1276 $cv['password'],
1277 $cv['connection'],
1278 FALSE,
1279 $cv['tls']);
1281 $ldap = new ldapMultiplexer($ldap_l);
1282 $ldap->cd($cv['base']);
1284 /* Check if there was a destination department posted */
1285 if(isset($_POST['move_group_to'])){
1286 $destination_dep = $_POST['move_group_to'];
1287 }else{
1288 msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1289 return(false);
1290 }
1292 foreach($this->outside_groups as $b_dn => $data){
1293 $this->outside_groups[$b_dn]['ldif'] ="";
1294 if($data['selected']){
1295 $dn = base64_decode($b_dn);
1296 $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1297 if(!$perform){
1299 $this->outside_groups[$b_dn]['ldif'] = _("Group will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1301 /* Check if there are references to this object */
1302 $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1303 $refs = "";
1304 while($attrs = $ldap->fetch()){
1305 $ref_dn = $attrs['dn'];
1306 $refs .= "<br />\t".$ref_dn;
1307 }
1308 if(!empty($refs)){
1309 $this->outside_groups[$b_dn]['ldif'] .= "<br /><br /><i>"._("Updating following references too").":</i>".$refs;
1310 }
1312 }else{
1313 $this->move($dn,$d_dn);
1314 }
1315 }
1316 }
1317 }
1320 function migrate_outside_users($perform = FALSE)
1321 {
1322 /* Establish ldap connection */
1323 $cv = $this->parent->captured_values;
1324 $ldap_l = new LDAP($cv['admin'],
1325 $cv['password'],
1326 $cv['connection'],
1327 FALSE,
1328 $cv['tls']);
1330 $ldap = new ldapMultiplexer($ldap_l);
1331 $ldap->cd($cv['base']);
1333 /* Check if there was a destination department posted */
1334 if(isset($_POST['move_user_to'])){
1335 $destination_dep = $_POST['move_user_to'];
1336 }else{
1337 msg_dialog::display(_("LDAP error"), _("Cannot move users to the requested department!"), ERROR_DIALOG);
1338 return(false);
1339 }
1341 foreach($this->outside_users as $b_dn => $data){
1342 $this->outside_users[$b_dn]['ldif'] ="";
1343 if($data['selected']){
1344 $dn = base64_decode($b_dn);
1345 $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
1346 if(!$perform){
1347 $this->outside_users[$b_dn]['ldif'] = _("User will be moved from").":<br>\t".($ldap->fix($dn))."<br>"._("to").":<br>\t".($ldap->fix($d_dn));
1349 /* Check if there are references to this object */
1350 $ldap->search("(&(member=".LDAP::prepare4filter($dn).")(|(objectClass=gosaGroupOfNames)(objectClass=groupOfNames)))",array('dn'));
1351 $refs = "";
1352 while($attrs = $ldap->fetch()){
1353 $ref_dn = $attrs['dn'];
1354 $refs .= "<br />\t".$ref_dn;
1355 }
1356 if(!empty($refs)){
1357 $this->outside_users[$b_dn]['ldif'] .= "<br /><br /><i>"._("The following references will be updated").":</i>".$refs;
1358 }
1360 }else{
1361 $this->move($dn,$d_dn);
1362 }
1363 }
1364 }
1365 }
1368 function execute()
1369 {
1370 /* Initialise checks if this is the first call */
1371 if(!$this->checks_initialised || isset($_POST['reload'])){
1372 $this->initialize_checks();
1373 $this->checks_initialised = TRUE;
1374 }
1376 /*************
1377 * Winstations outside the group ou
1378 *************/
1380 if(isset($_POST['outside_winstations_dialog_cancel'])){
1381 $this->outside_winstations_dialog = FALSE;
1382 $this->dialog = FALSE;
1383 $this->show_details = FALSE;
1384 }
1386 if(isset($_POST['outside_winstations_dialog_whats_done'])){
1387 $this->migrate_outside_winstations(FALSE);
1388 }
1390 if(isset($_POST['outside_winstations_dialog_perform'])){
1391 $this->migrate_outside_winstations(TRUE);
1392 $this->search_outside_winstations();
1393 $this->dialog = FALSE;
1394 $this->show_details = FALSE;
1395 $this->outside_winstations_dialog = FALSE;
1396 }
1398 if(isset($_POST['outside_winstations_dialog'])){
1399 $this->outside_winstations_dialog = TRUE;
1400 $this->dialog = TRUE;
1401 }
1403 if($this->outside_winstations_dialog){
1405 /* Fix displayed dn syntax */
1406 $tmp = $this->outside_winstations;
1407 foreach($tmp as $key => $data){
1408 $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1409 }
1411 $smarty = get_smarty();
1412 $smarty->assign("ous",$this->get_all_winstation_ous());
1413 $smarty->assign("method","outside_winstations");
1414 $smarty->assign("outside_winstations",$tmp);
1415 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1416 }
1417 /*************
1418 * Groups outside the group ou
1419 *************/
1421 if(isset($_POST['outside_groups_dialog_cancel'])){
1422 $this->outside_groups_dialog = FALSE;
1423 $this->show_details = FALSE;
1424 $this->dialog = FALSE;
1425 }
1427 if(isset($_POST['outside_groups_dialog_whats_done'])){
1428 $this->show_details= TRUE;
1429 $this->migrate_outside_groups(FALSE);
1430 }
1432 if(isset($_POST['outside_groups_dialog_refresh'])){
1433 $this->show_details= FALSE;
1434 }
1436 if(isset($_POST['outside_groups_dialog_perform'])){
1437 $this->migrate_outside_groups(TRUE);
1438 $this->dialog = FALSE;
1439 $this->show_details = FALSE;
1440 $this->outside_groups_dialog = FALSE;
1441 $this->initialize_checks();
1442 }
1444 if(isset($_POST['outside_groups_dialog'])){
1445 $this->outside_groups_dialog = TRUE;
1446 $this->dialog = TRUE;
1447 }
1449 if($this->outside_groups_dialog){
1451 /* Fix displayed dn syntax */
1452 $tmp = $this->outside_groups;
1453 foreach($tmp as $key => $data){
1454 $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1455 }
1457 $smarty = get_smarty();
1458 $smarty->assign("ous",$this->get_all_group_ous());
1459 $smarty->assign("method","outside_groups");
1460 $smarty->assign("outside_groups",$tmp);
1461 $smarty->assign("group_details", $this->show_details);
1462 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1463 }
1465 /*************
1466 * User outside the people ou
1467 *************/
1469 if(isset($_POST['outside_users_dialog_cancel'])){
1470 $this->outside_users_dialog = FALSE;
1471 $this->dialog = FALSE;
1472 $this->show_details = FALSE;
1473 }
1475 if(isset($_POST['outside_users_dialog_whats_done'])){
1476 $this->show_details= TRUE;
1477 $this->migrate_outside_users(FALSE);
1478 }
1480 if(isset($_POST['outside_users_dialog_perform'])){
1481 $this->migrate_outside_users(TRUE);
1482 $this->initialize_checks();
1483 $this->dialog = FALSE;
1484 $this->show_details = FALSE;
1485 $this->outside_users_dialog = FALSE;
1486 }
1488 if (isset($_POST['outside_users_dialog_refresh'])){
1489 $this->show_details= FALSE;
1490 }
1492 if(isset($_POST['outside_users_dialog'])){
1493 $this->outside_users_dialog = TRUE;
1494 $this->dialog = TRUE;
1495 }
1497 if($this->outside_users_dialog){
1499 /* Fix displayed dn syntax */
1500 $tmp = $this->outside_users;
1501 foreach($tmp as $key => $data){
1502 $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1503 }
1505 $smarty = get_smarty();
1506 $smarty->assign("ous",$this->get_all_people_ous());
1507 $smarty->assign("method","outside_users");
1508 $smarty->assign("outside_users",$tmp);
1509 $smarty->assign("user_details", $this->show_details);
1510 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1511 }
1513 /*************
1514 * Root object check
1515 *************/
1517 if(isset($_POST['retry_root_create'])){
1519 $state = $this->checks['root']['STATUS'];
1520 $this->checkBase(FALSE);
1521 if($state != $this->checks['root']['STATUS']){
1522 $this->initialize_checks();
1523 }
1524 }
1526 /*************
1527 * Root object class check
1528 *************/
1530 if(isset($_POST['root_add_objectclasses'])){
1531 $this->rootOC_migrate_dialog = TRUE;
1532 $this->dialog = TRUE;
1533 }
1534 if(isset($_POST['rootOC_dialog_cancel'])){
1535 $this->rootOC_migrate_dialog = FALSE;
1536 $this->dialog = FALSE;
1537 }
1538 if(isset($_POST['rootOC_migrate_start'])){
1539 if($this->checkBaseOC(FALSE)){
1540 $this->checkBaseOC(); // Update overview info
1541 $this->dialog = FALSE;
1542 $this->rootOC_migrate_dialog = FALSE;
1543 }
1544 }
1547 if($this->rootOC_migrate_dialog){
1548 $smarty = get_smarty();
1549 $smarty->assign("details",$this->rootOC_details);
1550 $smarty->assign("method","rootOC_migrate_dialog");
1551 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1552 }
1554 /*************
1555 * Administrative Account -- Migrate/Create
1556 *************/
1558 if(isset($_POST['retry_acls'])){
1559 $this->check_administrativeAccount();
1560 }
1562 /* Dialog handling */
1563 if(isset($_POST['create_acls'])){
1564 $this->acl_create_dialog = TRUE;
1565 $this->dialog = TRUE;
1566 }
1568 if(isset($_POST['migrate_acls'])){
1569 $this->acl_migrate_dialog = TRUE;
1570 $this->dialog = TRUE;
1571 }
1573 if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
1574 $this->acl_create_dialog = FALSE;
1575 $this->acl_migrate_dialog = FALSE;
1576 $this->dialog = FALSE;
1577 $this->show_details = FALSE;
1578 }
1580 /* Account creation */
1581 if(isset($_POST['create_acls_create'])){
1582 $this->create_admin(TRUE);
1583 }
1585 if(isset($_POST['create_admin_user'])){
1586 if($this->create_admin_user()){
1587 $this->dialog = FALSE;
1588 $this->show_details = FALSE;
1589 }
1590 }
1592 /* Add admin acls for the selected users to the ldap base.
1593 */
1594 if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
1596 /* Update ldap and reload check infos
1597 */
1598 $this->migrate_selected_admin_users();
1599 $this->dialog = FALSE;
1600 $this->acl_migrate_dialog = FALSE;
1602 }elseif($this->acl_migrate_dialog){
1604 /* Display admin migration dialog.
1605 */
1606 $this->migrate_users();
1607 $smarty = get_smarty();
1609 /* Do we have to display the changes
1610 */
1611 $details = isset($_POST['details']) && $_POST['details'];
1612 if(isset($_POST['migrate_acls_show_changes'])){
1613 $details = TRUE;
1614 }elseif(isset($_POST['migrate_acls_hide_changes'])){
1615 $details = FALSE;
1616 }
1618 $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
1619 $smarty->assign("details", $details);
1620 $smarty->assign("method","migrate_acls");
1621 $smarty->assign("migrateable_users",$this->migrate_users);
1622 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1623 }
1625 if($this->acl_create_dialog){
1626 $smarty = get_smarty();
1627 $uid = "admin";
1628 if(isset($_POST['new_user_uid'])){
1629 $uid = $_POST['new_user_uid'];
1630 }
1631 $smarty->assign("new_user_uid",$uid);
1632 $smarty->assign("new_user_password",@$_POST['new_user_password']);
1633 $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
1634 $smarty->assign("method","create_acls");
1635 $smarty->assign("acl_create_selected",$this->acl_create_selected);
1636 $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
1637 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1638 }
1640 /*************
1641 * User Migration handling
1642 *************/
1644 /* Refresh list of deparments */
1645 if(isset($_POST['users_visible_migrate_refresh'])){
1646 $this->check_gosaAccounts();
1647 }
1649 /* Open migration dialog */
1650 if(isset($_POST['users_visible_migrate'])){
1651 $this->show_details= FALSE;
1652 $this->users_migration_dialog = TRUE;
1653 $this->dialog =TRUE;
1654 }
1656 /* Close migration dialog */
1657 if(isset($_POST['users_visible_migrate_close'])){
1658 $this->users_migration_dialog = FALSE;
1659 $this->dialog =FALSE;
1660 $this->show_details = FALSE;
1661 }
1663 /* Start migration */
1664 if(isset($_POST['users_visible_migrate_migrate'])){
1665 if($this->migrate_gosaAccounts()){
1666 $this->initialize_checks();
1667 $this->dialog = FALSE;
1668 $this->show_details = FALSE;
1669 $this->users_migration_dialog = FALSE;
1670 }
1671 }
1673 /* Start migration */
1674 if(isset($_POST['users_visible_migrate_whatsdone'])){
1675 $this->migrate_gosaAccounts(TRUE);
1676 }
1678 /* Display migration dialog */
1679 if($this->users_migration_dialog){
1681 /* Fix displayed dn syntax */
1682 $tmp = $this->users_to_migrate;
1683 foreach($tmp as $key => $data){
1684 $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1685 }
1687 $smarty = get_smarty();
1688 $smarty->assign("users_to_migrate",$tmp);
1689 $smarty->assign("method","migrate_users");
1690 $smarty->assign("user_details", $this->show_details);
1691 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1692 }
1695 /*************
1696 * Department Migration handling
1697 *************/
1699 /* Refresh list of deparments */
1700 if(isset($_POST['deps_visible_migrate_refresh'])){
1701 $this->check_organizationalUnits();
1702 $this->show_details= FALSE;
1703 }
1705 /* Open migration dialog */
1706 if(isset($_POST['deps_visible_migrate'])){
1707 $this->dep_migration_dialog = TRUE;
1708 $this->dialog =TRUE;
1709 }
1711 /* Close migration dialog */
1712 if(isset($_POST['deps_visible_migrate_close'])){
1713 $this->dep_migration_dialog = FALSE;
1714 $this->dialog =FALSE;
1715 $this->show_details = FALSE;
1716 }
1718 /* Start migration */
1719 if(isset($_POST['deps_visible_migrate_migrate'])){
1720 if($this->migrate_organizationalUnits()){
1721 $this->show_details= FALSE;
1722 $this->check_organizationalUnits();
1723 $this->dialog = FALSE;
1724 $this->dep_migration_dialog = FALSE;
1725 }
1726 }
1728 /* Start migration */
1729 if(isset($_POST['deps_visible_migrate_whatsdone'])){
1730 $this->migrate_organizationalUnits(TRUE);
1731 }
1733 /* Display migration dialog */
1734 if($this->dep_migration_dialog){
1735 $smarty = get_smarty();
1737 /* Fix displayed dn syntax */
1738 $tmp = $this->deps_to_migrate;
1739 foreach($tmp as $key => $data){
1740 $tmp[$key]['dn'] = LDAP::fix($data['dn']);
1741 }
1743 $smarty->assign("deps_to_migrate",$tmp);
1744 $smarty->assign("method","migrate_deps");
1745 $smarty->assign("deps_details", $this->show_details);
1746 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1747 }
1750 /*************
1751 * Device migration
1752 *************/
1754 if($this->device_dialog) {
1755 $this->check_device_posts();
1756 }
1758 if(isset($_POST['device_dialog_cancel'])){
1759 $this->device_dialog = FALSE;
1760 $this->show_details = FALSE;
1761 $this->dialog = FALSE;
1762 }
1764 if(isset($_POST['device_dialog_whats_done'])){
1765 $this->show_details= TRUE;
1766 }
1768 if(isset($_POST['device_dialog_refresh'])){
1769 $this->show_details= FALSE;
1770 }
1772 if(isset($_POST['migrate_devices'])){
1773 $this->migrate_usb_devices();
1774 # $this->dialog = FALSE;
1775 # $this->show_details = FALSE;
1776 # $this->device_dialog = FALSE;
1777 # $this->initialize_checks();
1778 }
1780 if(isset($_POST['device_dialog'])){
1781 $this->device_dialog = TRUE;
1782 $this->dialog = TRUE;
1783 }
1785 if($this->device_dialog){
1786 $smarty = get_smarty();
1787 $smarty->assign("method","devices");
1788 $smarty->assign("devices",$this->device);
1789 $smarty->assign("device_details", $this->show_details);
1790 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1791 }
1794 /*************
1795 * Service migration
1796 *************/
1798 if($this->service_dialog) {
1799 $this->check_service_posts();
1800 }
1802 if(isset($_POST['service_dialog_cancel'])){
1803 $this->service_dialog = FALSE;
1804 $this->show_details = FALSE;
1805 $this->dialog = FALSE;
1806 }
1808 if(isset($_POST['service_dialog_whats_done'])){
1809 $this->show_details= TRUE;
1810 }
1812 if(isset($_POST['service_dialog_refresh'])){
1813 $this->show_details= FALSE;
1814 }
1816 if(isset($_POST['migrate_services'])){
1817 $this->migrate_services();
1818 # $this->dialog = FALSE;
1819 # $this->show_details = FALSE;
1820 # $this->service_dialog = FALSE;
1821 # $this->initialize_checks();
1822 }
1824 if(isset($_POST['service_dialog'])){
1825 $this->service_dialog = TRUE;
1826 $this->dialog = TRUE;
1827 }
1829 if($this->service_dialog){
1830 $smarty = get_smarty();
1831 $smarty->assign("method","services");
1832 $smarty->assign("services",$this->service);
1833 $smarty->assign("service_details", $this->show_details);
1834 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1835 }
1838 /*************
1839 * Menu migration
1840 *************/
1842 if($this->menu_dialog) {
1843 $this->check_menu_posts();
1844 }
1846 if(isset($_POST['menu_dialog_cancel'])){
1847 $this->menu_dialog = FALSE;
1848 $this->show_details = FALSE;
1849 $this->dialog = FALSE;
1850 }
1852 if(isset($_POST['menu_dialog_whats_done'])){
1853 $this->show_details= TRUE;
1854 }
1856 if(isset($_POST['menu_dialog_refresh'])){
1857 $this->show_details= FALSE;
1858 }
1860 if(isset($_POST['migrate_menus'])){
1861 $this->migrate_menus();
1862 # $this->dialog = FALSE;
1863 # $this->show_details = FALSE;
1864 # $this->menu_dialog = FALSE;
1865 # $this->initialize_checks();
1866 }
1868 if(isset($_POST['menu_dialog'])){
1869 $this->menu_dialog = TRUE;
1870 $this->dialog = TRUE;
1871 }
1873 if($this->menu_dialog){
1874 $smarty = get_smarty();
1875 $smarty->assign("method","menus");
1876 $smarty->assign("menus",$this->menu);
1877 $smarty->assign("menu_details", $this->show_details);
1878 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1879 }
1881 $smarty = get_smarty();
1882 $smarty->assign("checks",$this->checks);
1883 $smarty->assign("method","default");
1884 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1885 }
1888 function save_object()
1889 {
1890 $this->is_completed= TRUE;
1892 /* Capture all selected winstations from outside_winstations_dialog */
1893 if($this->outside_winstations_dialog){
1894 foreach($this->outside_winstations as $dn => $data){
1895 if(isset($_POST['select_winstation_'.$dn])){
1896 $this->outside_winstations[$dn]['selected'] = TRUE;
1897 }else{
1898 $this->outside_winstations[$dn]['selected'] = FALSE;
1899 }
1900 }
1901 }
1903 /* Capture all selected groups from outside_groups_dialog */
1904 if($this->outside_groups_dialog){
1905 foreach($this->outside_groups as $dn => $data){
1906 if(isset($_POST['select_group_'.$dn])){
1907 $this->outside_groups[$dn]['selected'] = TRUE;
1908 }else{
1909 $this->outside_groups[$dn]['selected'] = FALSE;
1910 }
1911 }
1912 }
1914 /* Capture all selected users from outside_users_dialog */
1915 if($this->outside_users_dialog){
1916 foreach($this->outside_users as $dn => $data){
1917 if(isset($_POST['select_user_'.$dn])){
1918 $this->outside_users[$dn]['selected'] = TRUE;
1919 }else{
1920 $this->outside_users[$dn]['selected'] = FALSE;
1921 }
1922 }
1923 }
1925 /* Get "create acl" dialog posts */
1926 if($this->acl_create_dialog){
1928 if(isset($_POST['create_acls_create_abort'])){
1929 $this->acl_create_selected = "";
1930 }
1931 }
1933 /* Get selected departments */
1934 if($this->dep_migration_dialog){
1935 foreach($this->deps_to_migrate as $id => $data){
1936 if(isset($_POST['migrate_'.$id])){
1937 $this->deps_to_migrate[$id]['checked'] = TRUE;
1938 }else{
1939 $this->deps_to_migrate[$id]['checked'] = FALSE;
1940 }
1941 }
1942 }
1944 /* Get selected users */
1945 if($this->users_migration_dialog){
1946 foreach($this->users_to_migrate as $id => $data){
1947 if(isset($_POST['migrate_'.$id])){
1948 $this->users_to_migrate[$id]['checked'] = TRUE;
1949 }else{
1950 $this->users_to_migrate[$id]['checked'] = FALSE;
1951 }
1952 }
1953 }
1954 }
1957 /* Check if the root object exists.
1958 * If the parameter just_check is true, then just check if the
1959 * root object is missing and update the info messages.
1960 * If the Parameter is false, try to create a new root object.
1961 */
1962 function checkBase($just_check = TRUE)
1963 {
1964 /* Establish ldap connection */
1965 $cv = $this->parent->captured_values;
1966 $ldap_l = new LDAP($cv['admin'],
1967 $cv['password'],
1968 $cv['connection'],
1969 FALSE,
1970 $cv['tls']);
1972 $ldap = new ldapMultiplexer($ldap_l);
1974 /* Check if root object exists */
1975 $ldap->cd($cv['base']);
1976 $ldap->set_size_limit(1);
1977 $res = $ldap->search("(objectClass=*)");
1978 $ldap->set_size_limit(0);
1979 $err = ldap_errno($ldap->cid);
1981 if( !$res ||
1982 $err == 0x20 || # LDAP_NO_SUCH_OBJECT
1983 $err == 0x40) { # LDAP_NAMING_VIOLATION
1985 /* Root object doesn't exists
1986 */
1987 if($just_check){
1988 $this->checks['root']['STATUS'] = FALSE;
1989 $this->checks['root']['STATUS_MSG']= _("Failed");
1990 $this->checks['root']['ERROR_MSG'] = _("The LDAP root object is missing. It is required to use your LDAP service.").' ';
1991 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1992 return(FALSE);
1993 }else{
1995 /* Add root object */
1996 $ldap->cd($cv['base']);
1997 $res = $ldap->create_missing_trees($cv['base']);
1999 /* If adding failed, tell the user */
2000 if(!$res){
2001 $this->checks['root']['STATUS'] = FALSE;
2002 $this->checks['root']['STATUS_MSG']= _("Failed");
2003 $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
2004 $this->checks['root']['ERROR_MSG'].= " <input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
2005 return($res);;
2006 }
2007 }
2008 }
2010 /* Create & remove of dummy object was successful */
2011 $this->checks['root']['STATUS'] = TRUE;
2012 $this->checks['root']['STATUS_MSG']= _("Ok");
2013 }
2016 /* Check if the root object includes the required object classes, e.g. gosaDepartment is required for ACLs.
2017 * If the parameter just_check is true, then just check for the OCs.
2018 * If the Parameter is false, try to add the required object classes.
2019 */
2020 function checkBaseOC($just_check = TRUE)
2021 {
2022 /* Establish ldap connection */
2023 $cv = $this->parent->captured_values;
2024 $ldap_l = new LDAP($cv['admin'],
2025 $cv['password'],
2026 $cv['connection'],
2027 FALSE,
2028 $cv['tls']);
2030 $ldap = new ldapMultiplexer($ldap_l);
2032 /* Check if root object exists */
2033 $ldap->cd($cv['base']);
2034 $ldap->cat($cv['base']);
2035 if(!$ldap->count()){
2036 $this->checks['rootOC']['STATUS'] = FALSE;
2037 $this->checks['rootOC']['STATUS_MSG']= _("LDAP query failed");
2038 $this->checks['rootOC']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2039 return;
2040 }
2042 $attrs = $ldap->fetch();
2044 /* Root object doesn't exists
2045 */
2046 if(!in_array("gosaDepartment",$attrs['objectClass'])){
2047 if($just_check){
2049 $this->rootOC_details = array();
2050 $mods = array();
2052 /* Get list of possible container objects, to be able to detect naming
2053 * attributes and missing attribute types.
2054 */
2055 if(!class_available("departmentManagement")){
2056 $this->checks['rootOC']['STATUS'] = FALSE;
2057 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2058 $this->checks['rootOC']['ERROR_MSG'] = sprintf(_("Missing GOsa object class '%s'!"),"departmentManagement").
2059 " "._("Please check your installation.");
2060 return;
2061 }
2063 /* Try to detect base class type, e.g. is it a dcObject.
2064 */
2065 $dep_types = departmentManagement::get_support_departments();
2066 $dep_type ="";
2067 foreach($dep_types as $dep_name => $dep_class){
2068 if(in_array($dep_class['CLASS'], $attrs['objectClass'])){
2069 $dep_type = $dep_name;
2070 break;
2071 }
2072 }
2074 /* If no known base class was detect, abort with message
2075 */
2076 if(empty($dep_type)){
2077 $this->checks['rootOC']['STATUS'] = FALSE;
2078 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2079 $this->checks['rootOC']['ERROR_MSG'] =
2080 sprintf(_("Cannot handle the structural object type of your root object. Please try to add the object class '%s' manually."),"gosaDepartment");
2081 return;
2082 }
2084 /* Create 'current' and 'target' object properties, to be able to display
2085 * a set of modifications required to create a valid GOsa department.
2086 */
2087 $str = "dn: ".$cv['base']."\n";
2088 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
2089 $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
2090 }
2091 $this->rootOC_details['current'] = $str;
2093 /* Create target infos
2094 */
2095 $str = "dn: ".$cv['base']."\n";
2096 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
2097 $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
2098 $mods['objectClass'][] = $attrs['objectClass'][$i];
2099 }
2100 $mods['objectClass'][] = "gosaDepartment";
2101 $str .= "<b>objectClass: gosaDepartment</b>\n";
2103 /* Append attribute 'ou', it is required by gosaDepartment
2104 */
2105 if(!isset($attrs['ou'])){
2106 $val = "GOsa";
2107 if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
2108 $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
2109 }
2110 $str .= "<b>ou: ".$val."</b>\n";
2111 $mods['ou'] =$val;
2112 }
2114 /*Append description, it is required by gosaDepartment too.
2115 */
2116 if(!isset($attrs['description'])){
2117 $val = "GOsa";
2118 if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
2119 $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
2120 }
2121 $str .= "<b>description: ".$val."</b>\n";
2122 $mods['description'] = $val;
2123 }
2124 $this->rootOC_details['target'] = $str;
2125 $this->rootOC_details['mods'] = $mods;
2127 /* Add button that allows to open the migration details
2128 */
2129 $this->checks['rootOC']['STATUS'] = FALSE;
2130 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
2131 $this->checks['rootOC']['ERROR_MSG'] = " <input type='submit'
2132 name='root_add_objectclasses' value='"._("Migrate")."'>";
2134 return(FALSE);
2135 }else{
2137 /* Add root object */
2138 $ldap->cd($cv['base']);
2139 if(isset($this->rootOC_details['mods'])){
2140 $res = $ldap->modify($this->rootOC_details['mods']);
2141 if(!$res){
2142 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $cv['base'], LDAP_MOD, get_class()));
2143 }
2144 $this->checkBaseOC();
2145 $this->check_administrativeAccount();
2146 return($res);
2147 }else{
2148 trigger_error("No modifications to make... ");
2149 }
2150 }
2151 return(TRUE);
2152 }
2154 /* Create & remove of dummy object was successful */
2155 $this->checks['rootOC']['STATUS'] = TRUE;
2156 $this->checks['rootOC']['STATUS_MSG']= _("Ok");
2157 $this->checks['rootOC']['ERROR_MSG'] = "";
2158 }
2161 /* Return ldif information for a
2162 * given attribute array
2163 */
2164 function array_to_ldif($atts)
2165 {
2166 $ret = "";
2167 unset($atts['count']);
2168 unset($atts['dn']);
2169 foreach($atts as $name => $value){
2170 if(is_numeric($name)) {
2171 continue;
2172 }
2173 if(is_array($value)){
2174 unset($value['count']);
2175 foreach($value as $a_val){
2176 $ret .= $name.": ". $a_val."\n";
2177 }
2178 }else{
2179 $ret .= $name.": ". $value."\n";
2180 }
2181 }
2182 return(preg_replace("/\n$/","",$ret));
2183 }
2186 function get_user_list()
2187 {
2188 /* Establish ldap connection */
2189 $cv = $this->parent->captured_values;
2190 $ldap_l = new LDAP($cv['admin'],
2191 $cv['password'],
2192 $cv['connection'],
2193 FALSE,
2194 $cv['tls']);
2196 $ldap = new ldapMultiplexer($ldap_l);
2197 $ldap->cd($cv['base']);
2198 $ldap->search("(objectClass=gosaAccount)",array("dn"));
2200 $tmp = array();
2201 while($attrs = $ldap->fetch()){
2202 $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2203 }
2204 return($tmp);
2205 }
2208 function get_all_people_ous()
2209 {
2210 /* Get collected configuration settings */
2211 $cv = $this->parent->captured_values;
2212 $people_ou = trim($cv['peopleou']);
2214 /* Establish ldap connection */
2215 $cv = $this->parent->captured_values;
2216 $ldap_l = new LDAP($cv['admin'],
2217 $cv['password'],
2218 $cv['connection'],
2219 FALSE,
2220 $cv['tls']);
2222 $ldap = new ldapMultiplexer($ldap_l);
2224 /*****************
2225 * If people ou is NOT empty
2226 * search for for all objects matching the given container
2227 *****************/
2228 if(!empty($people_ou)){
2229 $ldap->search("(".$people_ou.")",array("dn"));
2231 /* Create people ou if there is currently none */
2232 if($ldap->count() == 0 ){
2233 $add_dn = $cv['peopleou'].",".$cv['base'];
2234 $naming_attr = preg_replace("/=.*$/","",$add_dn);
2235 $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2236 $add = array();
2237 $add['objectClass'] = array("organizationalUnit");
2238 $add[$naming_attr] = $naming_value;
2239 $ldap->cd($cv['base']);
2240 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2241 $ldap->cd($add_dn);
2242 $ldap->add($add);
2243 }
2245 /* Create result */
2246 $ldap->search("(".$cv['peopleou'].")",array("dn"));
2247 $tmp = array();
2248 while($attrs= $ldap->fetch()){
2249 if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2250 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2251 }
2252 }
2253 } else{
2255 /************
2256 * If people ou is empty
2257 * Get all valid gosaDepartments
2258 ************/
2259 $ldap->cd($cv['base']);
2260 $tmp = array();
2261 $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2262 $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2263 while($attrs = $ldap->fetch()){
2264 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2265 }
2266 }
2267 return($tmp);
2268 }
2271 function get_all_winstation_ous()
2272 {
2273 /* Establish ldap connection */
2274 $cv = $this->parent->captured_values;
2275 $ldap_l = new LDAP($cv['admin'],
2276 $cv['password'],
2277 $cv['connection'],
2278 FALSE,
2279 $cv['tls']);
2281 $ldap = new ldapMultiplexer($ldap_l);
2283 /* Get winstation ou */
2284 if($cv['generic_settings']['wws_ou_active']) {
2285 $winstation_ou = $cv['generic_settings']['wws_ou'];
2286 }else{
2287 $winstation_ou = "ou=winstations";
2288 }
2290 $ldap->cd($cv['base']);
2291 $ldap->search("(".$winstation_ou.")",array("dn"));
2293 if($ldap->count() == 0 ){
2294 $add_dn = $winstation_ou.",ou=systems,".$cv['base'];
2295 $naming_attr = preg_replace("/=.*$/","",$add_dn);
2296 $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2297 $add = array();
2298 $add['objectClass'] = array("organizationalUnit");
2299 $add[$naming_attr] = $naming_value;
2301 $ldap->cd($cv['base']);
2302 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2303 $ldap->cd($add_dn);
2304 $ldap->add($add);
2305 }
2307 $ldap->search("(".$winstation_ou.")",array("dn"));
2308 $tmp = array();
2309 while($attrs= $ldap->fetch()){
2310 if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2311 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2312 }
2313 }
2314 return($tmp);
2315 }
2318 function get_all_group_ous()
2319 {
2320 /* Establish ldap connection */
2321 $cv = $this->parent->captured_values;
2322 $ldap_l = new LDAP($cv['admin'],
2323 $cv['password'],
2324 $cv['connection'],
2325 FALSE,
2326 $cv['tls']);
2328 $ldap = new ldapMultiplexer($ldap_l);
2330 $group_ou = trim($cv['groupou']);
2331 if(!empty($group_ou)){
2332 $group_ou = trim($group_ou);
2333 }
2335 /************
2336 * If group ou is NOT empty
2337 * Get all valid group ous, create one if necessary
2338 ************/
2339 $ldap->cd($cv['base']);
2340 if(!empty($group_ou)){
2341 $ldap->search("(".$group_ou.")",array("dn"));
2342 if($ldap->count() == 0 ){
2343 $add_dn = $group_ou.$cv['base'];
2344 $naming_attr = preg_replace("/=.*$/","",$add_dn);
2345 $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
2346 $add = array();
2347 $add['objectClass'] = array("organizationalUnit");
2348 $add[$naming_attr] = $naming_value;
2350 $ldap->cd($cv['base']);
2351 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
2352 $ldap->cd($add_dn);
2353 $ldap->add($add);
2354 }
2355 $ldap->search("(".$group_ou.")",array("dn"));
2356 $tmp = array();
2357 while($attrs= $ldap->fetch()){
2358 if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
2359 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
2360 }
2361 }
2362 }else{
2363 /************
2364 * If group ou is empty
2365 * Get all valid gosaDepartments
2366 ************/
2367 $ldap->cd($cv['base']);
2368 $tmp = array();
2369 $ldap->search("(&(objectClass=gosaDepartment)(ou=*))",array("dn"));
2370 $tmp[base64_encode($cv['base'])] = $ldap->fix($cv['base']);
2371 while($attrs = $ldap->fetch()){
2372 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);;
2373 }
2374 }
2375 return($tmp);
2376 }
2379 function get_group_list()
2380 {
2381 /* Establish ldap connection */
2382 $cv = $this->parent->captured_values;
2383 $ldap_l = new LDAP($cv['admin'],
2384 $cv['password'],
2385 $cv['connection'],
2386 FALSE,
2387 $cv['tls']);
2389 $ldap = new ldapMultiplexer($ldap_l);
2391 $ldap->cd($cv['base']);
2392 $ldap->search("(objectClass=posixGroup)",array("dn"));
2394 $tmp = array();
2395 while($attrs = $ldap->fetch()){
2396 $tmp[base64_encode($attrs['dn'])] = LDAP::fix($attrs['dn']);
2397 }
2398 return($tmp);
2399 }
2402 function move($source,$destination)
2403 {
2404 /* Establish ldap connection */
2405 $cv = $this->parent->captured_values;
2406 $ldap_l = new LDAP($cv['admin'],
2407 $cv['password'],
2408 $cv['connection'],
2409 FALSE,
2410 $cv['tls']);
2412 $ldap = new ldapMultiplexer($ldap_l);
2414 /* Update object references in gosaGroupOfNames */
2415 $ogs_to_fix = array();
2416 $ldap->cd($cv['base']);
2417 $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($source).'))', array('cn','member'));
2418 while ($attrs= $ldap->fetch()){
2419 $dn = $attrs['dn'];
2420 $attrs = $this->cleanup_array($attrs);
2421 $member_new = array($destination);
2422 foreach($attrs['member'] as $member){
2423 if($member != $source){
2424 $member_new[] = $member;
2425 }
2426 }
2427 $attrs['member'] = $member_new;
2428 $ogs_to_fix[$dn] = $attrs;
2429 }
2431 /* Copy source to destination dn */
2432 $ldap->cat($source);
2433 $new_data = $this->cleanup_array($ldap->fetch());
2434 $ldap->cd($destination);
2435 $res = $ldap->add($new_data);
2437 /* Display warning if copy failed */
2438 if(!$res){
2439 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);
2440 }else{
2441 $res = $ldap->rmDir($source);
2442 if (!$ldap->success()){
2443 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $source, LDAP_DEL, get_class()));
2444 }
2446 /* Object is copied, so update its references */
2447 foreach($ogs_to_fix as $dn => $data){
2448 $ldap->cd($dn);
2449 $ldap->modify($data);
2450 }
2451 }
2452 }
2455 /* Cleanup ldap result to be able to write it be to ldap */
2456 function cleanup_array($attrs)
2457 {
2458 foreach($attrs as $key => $value) {
2459 if(is_numeric($key) || in_array($key,array("count","dn"))){
2460 unset($attrs[$key]);
2461 }
2462 if(is_array($value) && isset($value['count'])){
2463 unset($attrs[$key]['count']);
2464 }
2465 }
2466 return($attrs);
2467 }
2470 /*! \brief Act in posts from the device migration dialog
2471 */
2472 function check_device_posts()
2473 {
2474 foreach($this->device as $key => $device){
2475 if(isset($_POST["migrate_".$key])){
2476 $this->device[$key]['DETAILS'] =TRUE;
2477 }else{
2478 $this->device[$key]['DETAILS'] =FALSE;
2479 }
2480 }
2481 }
2484 /*! \brief Check for old style (gosa-2.5) devices.
2485 Save readable informations and a list of migratable devices
2486 in $this->devices.
2487 */
2488 function check_usb_devices ()
2489 {
2490 /* Establish ldap connection */
2491 $cv = $this->parent->captured_values;
2492 $ldap_l = new LDAP($cv['admin'],
2493 $cv['password'],
2494 $cv['connection'],
2495 FALSE,
2496 $cv['tls']);
2498 $ldap = new ldapMultiplexer($ldap_l);
2499 $ldap->cd($cv['base']);
2500 $res = $ldap->search("(&(|(objectClass=posixAccount)(objectClass=posixGroup))(gotoHotplugDevice=*))",
2501 array("cn","gotoHotplugDevice","gosaUnitTag"));
2503 if(!$res){
2504 $this->checks['old_style_devices']['STATUS'] = FALSE;
2505 $this->checks['old_style_devices']['STATUS_MSG']= _("LDAP query failed");
2506 $this->checks['old_style_devices']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2507 return;
2508 }
2511 /* If adding failed, tell the user */
2512 if($ldap->count()){
2514 $this->device = array();
2515 while($attrs = $ldap->fetch()){
2517 for ($j= 0; $j < $attrs['gotoHotplugDevice']['count']; $j++){
2519 $after = "";
2520 $current= "";
2522 $entry= $attrs['gotoHotplugDevice'][$j];
2524 @list($name,$desc,$serial,$vendor,$product) = explode('|', $entry);
2526 $add = 1;
2527 $new_name = $name;
2528 while(isset($dest[$new_name])){
2529 $new_name = $name."_".$add;
2530 $add ++;
2531 }
2532 $name = $new_name;
2533 $newdn= "cn=$name,ou=devices,".preg_replace('/^[^,]+,/', '', $attrs['dn']);
2535 if (!isset($dest[$name])){
2536 $dest[$name]= $newdn;
2538 $current.= "dn: ".$attrs['dn']."\n";
2540 for ($c= 0; $c < $attrs['gotoHotplugDevice']['count']; $c++){
2541 if($c == $j){
2542 $current.= "<b>gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."</b>\n";
2543 }else{
2544 $current.= "gotoHotplugDevice: ".$attrs['gotoHotplugDevice'][$c]."\n";
2545 }
2546 }
2548 $after.= "dn: $newdn\n";
2549 $after.= "changetype: add\n";
2550 $after.= "objectClass: top\n";
2551 $after.= "objectClass: gotoDevice\n";
2552 if (isset($attrs['gosaunittag'][0])){
2553 $after.= "objectClass: gosaAdminiafter\n";
2554 $after.= "gosaUnitTag: ".$attrs['gosaunittag'][0]."\n";
2555 }
2556 $after.= "cn: $name\n";
2557 $after.= "gotoHotplugDevice: $desc|$serial|$vendor|$product\n\n";
2559 $this->device[] = array(
2560 'CURRENT' => $current,
2561 'AFTER' => $after,
2562 'OLD_DEVICE' => $entry,
2563 'DN' => $attrs['dn'],
2564 'NEW_DN' => $newdn,
2565 'DEVICE_NAME' => $name,
2566 'DETAILS' => FALSE);
2567 }
2568 }
2569 }
2571 $this->checks['old_style_devices']['STATUS'] = FALSE;
2572 $this->checks['old_style_devices']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2573 $this->checks['old_style_devices']['ERROR_MSG'] =
2574 sprintf(_("There are %s devices that need to be migrated."),count($this->device)).
2575 "<input type='submit' name='device_dialog' value='"._("Migrate")."'>";
2576 }else{
2577 $this->checks['old_style_devices']['STATUS'] = TRUE;
2578 $this->checks['old_style_devices']['STATUS_MSG']= _("Ok");
2579 $this->checks['old_style_devices']['ERROR_MSG'] = "";
2580 }
2581 }
2584 /*! \brief Migrate all selected devices.
2585 Execute all required ldap actions to migrate the
2586 selected devices.
2587 */
2588 function migrate_usb_devices ()
2589 {
2590 /* Establish ldap connection */
2591 $cv = $this->parent->captured_values;
2592 $ldap_l = new LDAP($cv['admin'],
2593 $cv['password'],
2594 $cv['connection'],
2595 FALSE,
2596 $cv['tls']);
2598 $ldap = new ldapMultiplexer($ldap_l);
2600 /* Walk through migrateable devices and initiate migration for all
2601 devices that are checked (DETAILS==TRUE)
2602 */
2603 foreach($this->device as $key => $device){
2604 if($device['DETAILS']){
2606 /* Get source object and verify that the specified device is a
2607 member attribute of it.
2608 */
2609 $ldap->cd($cv['base']);
2610 $ldap->cat($device['DN']);
2611 $attrs = $ldap->fetch();
2612 if(in_array($device['OLD_DEVICE'],$attrs['gotoHotplugDevice'])){
2614 /* Create new hotplug device object 'gotoDevice'
2615 */
2616 @list($name,$desc,$serial,$vendor,$product) = explode('|', $device['OLD_DEVICE']);
2617 $newdn = $device['NEW_DN'];
2618 $new_attr = array();
2619 $new_attr['cn'] = $device['DEVICE_NAME'];
2620 $new_attr['objectClass'] = array('top','gotoDevice');
2621 $new_attr['gotoHotplugDevice'] = "$desc|$serial|$vendor|$product";
2623 /* Add new object
2624 */
2625 $ldap->cd($cv['base']);
2626 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$newdn));
2627 $ldap->cd($newdn);
2628 $ldap->add($new_attr);
2630 /* Throw an error message if the action failed.
2631 */
2632 if(!$ldap->success()){
2633 msg_dialog::display(_("LDAP error"),
2634 sprintf(_("Adding '%s' to the LDAP failed: %s"),
2635 "<b>".LDAP::fix($newdn)."</b>",
2636 "<br><br><i>".$ldap->get_error()."</i>"), ERROR_DIALOG);
2637 }else{
2639 /* Remove old style device definition from source object.
2640 */
2641 $update['gotoHotplugDevice'] = array();
2642 for($i = 0 ; $i < $attrs['gotoHotplugDevice']['count'] ; $i++){
2643 if($attrs['gotoHotplugDevice'][$i] == $device['OLD_DEVICE']){
2644 continue;
2645 }
2646 $update['gotoHotplugDevice'][] = $attrs['gotoHotplugDevice'][$i];
2647 }
2649 $ldap->cd($device['DN']);
2650 $ldap->modify($update);
2651 $ldap->cat($device['DN'],array("gotoHotplugDevice"));
2652 if(!$ldap->success()){
2653 msg_dialog::display(_("LDAP error"),
2654 sprintf(_("Updating '%s' failed: %s"),
2655 "<b>".LDAP::fix($device['DN'])."</b>",
2656 "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2657 }else{
2658 unset($this->device[$key]);
2659 }
2660 }
2661 }
2662 }
2663 }
2664 $this->check_usb_devices();
2665 }
2668 /*! \brief Check for old style (gosa-2.5) services that have to be migrated
2669 to be useable in gosa-2.6.
2670 All required changes are stored in $this->service, also some
2671 readable informations describing the actions required
2672 to migrate the service
2673 */
2674 function check_services()
2675 {
2676 /* Establish ldap connection */
2677 $cv = $this->parent->captured_values;
2678 $ldap_l = new LDAP($cv['admin'],
2679 $cv['password'],
2680 $cv['connection'],
2681 FALSE,
2682 $cv['tls']);
2684 $ldap = new ldapMultiplexer($ldap_l);
2685 $this->service = array();
2687 /* Check for Ldap services that must be migrated
2688 */
2689 $ldap->cd($cv['base']);
2690 $res = $ldap->search("(objectClass=goLdapServer)", array("goLdapBase", "cn"));
2692 /* Check if we were able to query the ldap server
2693 */
2694 if(!$res){
2695 $this->checks['old_style_services']['STATUS'] = FALSE;
2696 $this->checks['old_style_services']['STATUS_MSG']= _("LDAP query failed");
2697 $this->checks['old_style_services']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2698 return;
2699 }
2701 /* Walk through each configured ldap server
2702 and check if it is configured correctly.
2703 */
2704 while($attrs = $ldap->fetch()){
2705 $dn= $attrs['dn'];
2706 $uri= $attrs['goLdapBase'][0];
2707 if (! preg_match("!^ldaps?://!", $uri)){
2708 $this->service[] = array(
2709 "TYPE" => "modify" ,
2710 "DN" => $dn,
2711 "DETAILS" => FALSE,
2712 "ATTRS" => array("goLdapBase" => "ldap://".$attrs['cn'][0]."/$uri"),
2713 "CURRENT" => "goLdapBase: ".$uri,
2714 "AFTER" => "goLdapBase: "."ldap://".$attrs['cn'][0]."/$uri");
2715 }
2716 }
2718 /* Other sevices following here later ...maybe
2719 */
2721 /* Update status message
2722 */
2723 if(count($this->service)){
2724 $this->checks['old_style_services']['STATUS'] = FALSE;
2725 $this->checks['old_style_services']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
2726 $this->checks['old_style_services']['ERROR_MSG'] =
2727 sprintf(_("There are %s services that need to be migrated."),
2728 count($this->service)).
2729 "<input type='submit' name='service_dialog' value='"._("Migrate")."'>";
2730 }else{
2731 $this->checks['old_style_services']['STATUS'] = TRUE;
2732 $this->checks['old_style_services']['STATUS_MSG']= _("Ok");
2733 $this->checks['old_style_services']['ERROR_MSG'] = "";
2734 }
2735 }
2739 /*! \brief Migrate selected services.
2740 This function executes the commands collected by the
2741 service_check() function.
2742 */
2743 function migrate_services()
2744 {
2745 /* Establish ldap connection
2746 */
2747 $cv = $this->parent->captured_values;
2748 $ldap_l = new LDAP($cv['admin'],
2749 $cv['password'],
2750 $cv['connection'],
2751 FALSE,
2752 $cv['tls']);
2754 $ldap = new ldapMultiplexer($ldap_l);
2756 /* Handle each service
2757 */
2758 foreach($this->service as $key => $service){
2759 if($service['DETAILS']){
2761 /* Handle modify requests
2762 */
2763 if($service['TYPE'] == "modify"){
2764 $ldap->cd($service['DN']);
2765 $ldap->modify($service['ATTRS']);
2767 /* Check if everything done was successful
2768 */
2769 if(!$ldap->success()){
2770 msg_dialog::display(_("LDAP error"),
2771 sprintf(_("Updating '%s' failed: %s"),
2772 "<b>".LDAP::fix($service['DN'])."</b>",
2773 "<br><br><i>".$ldap->get_error()."</b>"), ERROR_DIALOG);
2774 }else{
2776 /* Remove action from list
2777 */
2778 unset($this->service[$key]);
2779 }
2780 }
2781 }
2782 }
2784 /* Update the service migration status
2785 */
2786 $this->check_services();
2787 }
2790 /*! \brief Ensure that posts made on the service migration dialog
2791 are processed.
2792 */
2793 function check_service_posts()
2794 {
2795 foreach($this->service as $key => $service){
2796 if(isset($_POST["migrate_".$key])){
2797 $this->service[$key]['DETAILS'] =TRUE;
2798 }else{
2799 $this->service[$key]['DETAILS'] =FALSE;
2800 }
2801 }
2802 }
2805 /*! \brief This function checks the given ldap for old style (gosa-2.5)
2806 menu entries and will prepare a list of actions that are required
2807 to migrate them to gosa-2.6.
2808 All required actions and some readable informations are stored in
2809 $this->menu.
2810 */
2811 function check_menus()
2812 {
2813 /* Establish ldap connection
2814 */
2815 $cv = $this->parent->captured_values;
2816 $ldap_l = new LDAP($cv['admin'],
2817 $cv['password'],
2818 $cv['connection'],
2819 FALSE,
2820 $cv['tls']);
2822 $ldap = new ldapMultiplexer($ldap_l);
2824 /* First detect all release names
2825 */
2826 $ldap->cd($cv['base']);
2827 $res = $ldap->search("(&(objectClass=organizational)(objectClass=FAIbranch))",array("ou","objectClass"));
2829 /* Check if we were able to query the ldap server
2830 */
2831 if(!$res){
2832 $this->checks['old_style_menus']['STATUS'] = FALSE;
2833 $this->checks['old_style_menus']['STATUS_MSG']= _("LDAP query failed");
2834 $this->checks['old_style_menus']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
2835 return;
2836 }
2838 /* Create application -> parameter mapping, used later to detect
2839 which configured parameter belongs to which application entry.
2840 */
2841 $amap= array();
2842 $todo = array();
2843 $ldap->cd($cv['base']);
2844 $ldap->search("(objectClass=gosaApplication)", array("cn", "gosaApplicationParameter"));
2845 while($info = $ldap->fetch()){
2846 if (isset($info['gosaApplicationParameter']['count'])){
2847 for ($j= 0; $j < $info['gosaApplicationParameter']['count']; $j++){
2848 $p= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$j]);
2850 if(!isset($amap[$info['cn'][0]]) || !in_array($p, $amap[$info['cn'][0]])){
2851 $amap[$info['cn'][0]][]= $p;
2852 }
2853 }
2854 } else {
2855 $amap[$info['cn'][0]]= array();
2856 }
2857 }
2859 /* Search for all groups that have an old style application menu configured.
2860 */
2861 $appgroups = array();
2862 $ldap->cd($cv['base']);
2863 $ldap->search("(&(objectClass=gosaApplicationGroup)(objectClass=posixGroup)(FAIrelease=*))",
2864 array("gosaMemberApplication","gosaApplicationParameter","FAIrelease","objectClass","gosaUnitTag"));
2866 /* Create readable prefix for "What will be done" infos
2867 */
2868 $s_add = "<i>"._("Add")."</i>\t";
2869 $s_del = "<i>"._("Remove")."</i>\t";
2871 /* Walk through all found old-style menu configurations.
2872 -Prepare ldap update list $data
2873 -Prepare printable changes $after/$current
2874 */
2875 while($info = $ldap->fetch()){
2877 $data = array();
2878 $current = "";
2879 $after ="";
2881 /* Get unit tag
2882 */
2883 $tag ="";
2884 if(isset($info['gosaUnitTag'])){
2885 $tag = $info['gosaUnitTag'][0];
2886 }
2888 /* Collect application parameter for this group
2889 */
2890 $params= array();
2891 if(isset($info['gosaApplicationParameter'])){
2892 for ($i= 0; $i < $info['gosaApplicationParameter']['count']; $i++){
2893 $name= preg_replace("/^([^:]+):.*$/", "$1", $info['gosaApplicationParameter'][$i]);
2894 $params[$name]= $info['gosaApplicationParameter'][$i];
2895 }
2896 }
2898 /* Create release container for each release/subrelease.
2899 eg. "sisa/1.0.0":
2900 . "ou=siga, ..."
2901 . "ou=1.0.0,ou=siga, .."
2902 */
2903 $release = "";
2904 $r = $info['FAIrelease'][0];
2905 $z = explode("/",$r);
2906 foreach($z as $part){
2908 if(!empty($part)){
2909 $release = "ou=".$part.",".$release;
2911 /* Append release department information to "What will be done" info
2912 */
2913 $release_dn = $release.$info['dn'];
2914 $after .= $s_add."dn: $release_dn\n";
2915 $after .= $s_add."objectClass: top\n";
2916 $after .= $s_add."objectClass: FAIbranch\n";
2917 $after .= $s_add."objectClass: organizationalUnit\n";
2919 /* Append UnitTag
2920 */
2921 if($tag != ""){
2922 $after .= $s_add."objectClass: gosaAdministrativeUnitTag\n";
2923 $after .= $s_add."gosaUnitTag: $tag\n";
2924 }
2925 $after .= $s_add."ou: $part\n";
2927 /* Append release data to ldap actions
2928 */
2929 $d = array();
2930 $d['objectClass'] = array("top","FAIbranch","organizationalUnit");
2931 if(!empty($tag)){
2932 $d['objectClass'][] = "gosaAdministrativeUnitTag";
2933 $d['gosaUnitTag'] = $tag;
2934 }
2935 $d['ou'] = $part;
2936 $data['ADD'][$release_dn]= $d;
2937 }
2938 }
2940 /* Add member applications to the array.
2941 */
2942 $current .= "dn: ".$info['dn']."\n";
2943 $menu_structure = array();
2944 for ($i= 0; $i < $info['gosaMemberApplication']['count']; $i++){
2945 list($name, $location, $priority)= explode("|", $info['gosaMemberApplication'][$i]);
2947 /* Create location dn
2948 */
2949 $location_dn ="";
2950 if(!empty($location)){
2951 $location_dn ="cn=".$location.",";
2952 }
2954 /* Append old style element to current detail informations
2955 */
2956 $current .= $s_del."gosaMemberApplication: ".$info['gosaMemberApplication'][$i]."\n";
2958 /* Append ldap update action to remove the old menu entry attributes
2959 */
2960 unset($info['objectClass']['count']);
2961 $d = array();
2962 $d['gosaMemberApplication'] = array();
2963 $d['gosaApplicationParameter'] = array();
2964 if(isset($info['FAIrelease'])){
2965 $d['FAIrelease'] = array();
2966 }
2967 $d['objectClass'] = array_remove_entries(array("gosaApplicationGroup","FAIreleaseTag"),$info['objectClass']);
2968 $data['MODIFY'][$info['dn']] = $d;
2970 /* Create new application menu structure
2971 */
2972 if (isset($amap[$name])){
2974 /* Append missing menu structure to "What is done info"
2975 */
2976 if(!isset($menu_structure[$location]) && !empty($location)){
2977 $menu_structure[$location] = TRUE;
2978 $after .= "\n";
2979 $after .= $s_add."dn: $location_dn$release_dn\n";
2980 $after .= $s_add."objectClass: gotoSubmenuEntry\n";
2982 /* Append UnitTag
2983 */
2984 if($tag != ""){
2985 $after .= $s_add."objectClass: gosaAdministrativeUnitTag\n";
2986 $after .= $s_add."gosaUnitTag: $tag\n";
2987 }
2988 $after .= $s_add."cn: $location\n";
2990 /* Create ldap entry to append
2991 */
2992 $d = array();
2993 $d['cn'] = $location;
2994 $d['objectClass'] = array("gotoSubmenuEntry");
2995 if(!empty($tag)){
2996 $d['objectClass'][] = "gosaAdministrativeUnitTag";
2997 $d['gosaUnitTag'] = $tag;
2998 }
2999 $data['ADD'][$location_dn.$release_dn] = $d;
3000 }
3003 /* Append missing menu entry for "What is done info".
3004 */
3005 if(!empty($name)){
3006 $after .= "\n";
3007 $after .= $s_add."dn: cn=$name,$location_dn$release_dn\n";
3008 $after .= $s_add."objectClass: gotoMenuEntry\n";
3009 if($tag != ""){
3010 $after .= $s_add."objectClass: gosaAdministrativeUnitTag\n";
3011 $after .= $s_add."gosaUnitTag: $tag\n";
3012 }
3013 $after .= $s_add."cn: $name\n";
3014 $after .= $s_add."gosaApplicationPriority: $priority\n";
3016 /* Create ldap entry
3017 */
3018 $d= array();
3019 $d['objectClass'] = array("gotoMenuEntry");
3020 if(!empty($tag)){
3021 $d['objectClass'][] = "gosaAdministrativeUnitTag";
3022 $d['gosaUnitTag'] = $tag;
3023 }
3024 $d['cn'] = $name;
3025 $d['gosaApplicationPriority'] = $priority;
3027 foreach ($amap[$name] as $n){
3028 if (isset($params[$n])){
3029 $after .= $s_add."gosaApplicationParameter: ".$params[$n]."\n";
3030 $d['gosaApplicationParameter'][] = $params[$n];
3031 }
3032 }
3033 $data['ADD']["cn=$name,$location_dn$release_dn"] = $d;
3034 }
3035 }
3036 }
3038 /* Updated todo list
3039 */
3040 $todo[] = array(
3041 "DETAILS" => FALSE,
3042 "DN" => $info['dn'],
3043 "AFTER" => $after,
3044 "CURRENT" => $current,
3045 "TODO" => $data
3046 );
3047 }
3049 /* Remember checks.
3050 */
3051 $this->menu = $todo;
3053 /* Check if we were able to query the ldap server
3054 */
3055 if(count($this->menu)){
3056 $this->checks['old_style_menus']['STATUS'] = FALSE;
3057 $this->checks['old_style_menus']['STATUS_MSG']= "<font style='color:#F0A500'>"._("Warning")."</font>";
3058 $this->checks['old_style_menus']['ERROR_MSG'] = sprintf(_("There are %s application menus which have to be migrated."),
3059 count($this->menu))."<input type='submit' name='menu_dialog' value='"._("Migrate")."'>";
3060 }else{
3061 $this->checks['old_style_menus']['STATUS'] = TRUE;
3062 $this->checks['old_style_menus']['STATUS_MSG']= _("Ok");
3063 $this->checks['old_style_menus']['ERROR_MSG'] = "";
3064 }
3065 }
3068 /*! \brief Handle posts for the menu_dialog
3069 Ensure that checked checkboxes stay checked.
3070 */
3071 function check_menu_posts()
3072 {
3073 foreach($this->menu as $key => $menu){
3074 if(isset($_POST["migrate_".$key])){
3075 $this->menu[$key]['DETAILS'] =TRUE;
3076 }else{
3077 $this->menu[$key]['DETAILS'] =FALSE;
3078 }
3079 }
3080 }
3083 /*! \brief This function updates old-style application menus to
3084 valid 2.6 application menus.
3085 All selected menus will be converted (DETAILS = TRUE).
3086 The ldap actions collected by check_menus() will be executed.
3087 */
3088 function migrate_menus()
3089 {
3091 /* Establish ldap connection
3092 */
3093 $cv = $this->parent->captured_values;
3094 $ldap_l = new LDAP($cv['admin'],
3095 $cv['password'],
3096 $cv['connection'],
3097 FALSE,
3098 $cv['tls']);
3100 $ldap = new ldapMultiplexer($ldap_l);
3101 $ldap->cd($cv['base']);
3103 /* Walk through menus and detect selected menu
3104 */
3105 foreach($this->menu as $key => $menu){
3106 if($menu['DETAILS']) {
3108 /* Excute all LDAP-ADD actions
3109 */
3110 $success = TRUE;
3111 foreach($menu['TODO']['ADD'] as $dn => $data){
3112 $ldap->cd($cv['base']);
3113 if(!$ldap->dn_exists($dn)){
3114 $ldap->cd($dn);
3115 $ldap->add($data);
3116 if (!$ldap->success()){
3117 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
3118 $success = FALSE;
3119 }
3120 }
3121 }
3123 /* Execute all LDAP-MODIFY actions
3124 */
3125 foreach($menu['TODO']['MODIFY'] as $dn => $data){
3126 $ldap->cd($cv['base']);
3127 if($ldap->dn_exists($dn)){
3128 $ldap->cd($dn);
3129 $ldap->modify($data);
3130 if (!$ldap->success()){
3131 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
3132 $success = FALSE;
3133 }
3134 }
3135 }
3137 /* If every action was successful, remove this entry from the list
3138 */
3139 if($success){
3140 unset($this->menu[$key]);
3141 }
3142 }
3143 }
3145 /* Udpate migration status for application menus
3146 */
3147 $this->check_menus();
3148 }
3151 function migrate_selected_admin_users()
3152 {
3153 /* Updated ui selection */
3154 $this->migrate_users();
3156 /* Establish ldap connection */
3157 $cv = $this->parent->captured_values;
3158 $ldap_l = new LDAP($cv['admin'],
3159 $cv['password'],
3160 $cv['connection'],
3161 FALSE,
3162 $cv['tls']);
3164 $ldap = new ldapMultiplexer($ldap_l);
3165 $ldap->cd($cv['base']);
3167 /* Get current ACL configuration for the ldap base
3168 */
3169 $ldap->cat($cv['base']);
3170 $base_attrs = $ldap->fetch();
3171 $acl_entries= array();
3172 $acl_id = -1;
3173 if(isset($base_attrs['gosaAclEntry'])){
3174 for($i=0; $i < $base_attrs['gosaAclEntry']['count']; $i ++){
3175 $acl_entries[] = $base_attrs['gosaAclEntry'][$i];
3176 $cur_id = preg_replace("/^([0-9]*):.*$/","\\1",$base_attrs['gosaAclEntry'][$i]);
3177 if($cur_id > $acl_id){
3178 $acl_id = $cur_id;
3179 }
3180 }
3181 }
3183 /* Append ACLs selected in the migrate admin account dialog
3184 */
3185 foreach($this->migrate_users as $entry){
3186 if($entry['checked']){
3187 $acl_id ++;
3188 $acl_entries[] = $acl_id.$entry['change'];
3189 }
3190 }
3192 /* Check if the required objectClasses are available
3193 */
3194 $ocs = array();
3195 for($i=0;$i< $base_attrs['objectClass']['count']; $i++){
3196 $ocs[] = $base_attrs['objectClass'][$i];
3197 }
3198 if(!in_array("gosaACL",$ocs)){
3199 $ocs[] = "gosaACL";
3200 }
3202 /* Try to write changes
3203 */
3204 if(count($acl_entries)){
3205 $new_entry['gosaAclEntry'] = $acl_entries;
3206 $new_entry['objectClass'] = $ocs;
3207 $ldap->cd($cv['base']);
3208 $ldap->modify($new_entry);
3209 if(!$ldap->success()){
3210 $this->checks['acls']['TITLE'] = _("Checking for super administrator");
3211 $this->checks['acls']['STATUS'] = FALSE;
3212 $this->checks['acls']['STATUS_MSG']= _("Failed");
3213 $this->checks['acls']['ERROR_MSG'] = "<br>".msgPool::ldaperror($cv['base'],$ldap->get_error(),LDAP_MOD);
3214 }else{
3215 $this->check_administrativeAccount();
3216 }
3217 }
3218 }
3221 function migrate_users()
3222 {
3223 /* Collect a list of available GOsa users and groups
3224 */
3226 /* Establish ldap connection */
3227 $cv = $this->parent->captured_values;
3228 $ldap_l = new LDAP($cv['admin'],
3229 $cv['password'],
3230 $cv['connection'],
3231 FALSE,
3232 $cv['tls']);
3234 $ldap = new ldapMultiplexer($ldap_l);
3235 $ldap->cd($cv['base']);
3237 $users = array();
3238 $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
3239 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
3240 while($user_attrs = $ldap->fetch()){
3241 $users[$user_attrs['dn']] = $user_attrs['uid'][0];
3242 $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
3243 }
3244 $groups = array();
3245 $ldap->search("objectClass=posixGroup",array("cn","dn"));
3246 while($group_attrs = $ldap->fetch()){
3247 $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
3248 }
3250 foreach($this->migrate_users as $id => $data){
3251 $this->migrate_users[$id]['checked'] = isset($_POST['migrate_admin_'.$id]);
3252 }
3254 /* Try to find an old GOsa 2.5 administrative account that may be migrated
3255 */
3256 if(!count($this->migrate_users)){
3257 $ldap->cat($cv['base']);
3258 $base_data = $ldap->fetch();
3259 $base_entry = "dn: ".$base_data['dn']."\n";
3260 for($i=0;$i<$base_data['objectClass']['count'];$i++){
3261 $base_entry .= "objectClass: ".$base_data['objectClass'][$i]."\n";
3262 }
3263 if(!in_array("gosaACL",$base_data['objectClass'])){
3264 $base_entry .= "<b>objectClass: gosaACL</b>\n";
3265 }
3266 if(isset($base_data['gosaAclEntry'])){
3267 for($i=0;$i<$base_data['gosaAclEntry']['count'];$i++){
3268 $base_entry .= "gosaAclEntry: ".$base_data['gosaAclEntry'][$i]."\n";
3269 }
3270 }
3271 $this->migrate_acl_base_entry = $base_entry;
3272 $ldap->cd($cv['base']);
3273 $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
3274 while($p_group = $ldap->fetch()){
3275 for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
3276 $user = $p_group['memberUid'][$e];
3277 if(isset($rusers[$user])){
3278 $bsp_acl_entry = "gosaAclEntry: #:psub:".base64_encode($rusers[$user]).":all;cmdrw\n";
3279 $entry = array();
3280 $entry['uid'] = $user;
3281 $entry['dn'] = $rusers[$user];
3282 $entry['details'] = $bsp_acl_entry;
3283 $entry['checked'] = FALSE;
3284 $entry['change'] = ":psub:".base64_encode($rusers[$user]).":all;cmdrw";
3285 $this->migrate_users[] = $entry;
3286 }
3287 }
3288 }
3289 }
3290 }
3291 }
3292 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
3293 ?>