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/monitoring.png";
57 var $checks = array();
59 /* Department migration attributes */
60 var $dep_migration_dialog = FALSE;
61 var $deps_to_migrate = array();
63 /* Department migration attributes */
64 var $users_migration_dialog= FALSE;
65 var $users_to_migrate = array();
67 /* Create Acl attributes */
68 var $acl_create_dialog = FALSE;
69 var $acl_create_type = "group";
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 /* Win-Workstations outside to reserved ou */
86 var $outside_winstations = array();
87 var $outside_winstations_dialog = FALSE;
89 /* check for multiple use of same uidNumber */
90 var $check_uidNumbers = array();
91 var $check_uidNumbers_dialog = FALSE;
93 /* check for multiple use of same gidNumber */
94 var $check_gidNumbers = array();
95 var $check_gidNumbers_dialog = FALSE;
98 function Step_Migrate()
99 {
100 $this->update_strings();
101 }
103 function update_strings()
104 {
105 $this->s_title = _("LDAP inspection");
106 $this->s_title_long = _("LDAP inspection");
107 $this->s_info = _("Analyze your current LDAP for GOsa compatibility");
108 }
110 function initialize_checks()
111 {
112 $this->checks = array();
113 $this->checks['root']['TITLE'] = _("Checking for root object");
114 $this->checks['root']['STATUS'] = FALSE;
115 $this->checks['root']['STATUS_MSG']= "";
116 $this->checks['root']['ERROR_MSG'] = "";
117 $this->checkBase();
119 $this->checks['permissions']['TITLE'] = _("Checking permissions on ldap database");
120 $this->checks['permissions']['STATUS'] = FALSE;
121 $this->checks['permissions']['STATUS_MSG']= "";
122 $this->checks['permissions']['ERROR_MSG'] = "";
123 $this->check_ldap_permissions();
125 $this->checks['deps_visible']['TITLE'] = _("Checking for invisible deparmtments");
126 $this->checks['deps_visible']['STATUS'] = FALSE;
127 $this->checks['deps_visible']['STATUS_MSG']= "";
128 $this->checks['deps_visible']['ERROR_MSG'] = "";
129 $this->check_organizationalUnits();
131 $this->checks['users_visible']['TITLE'] = _("Checking for invisible user");
132 $this->checks['users_visible']['STATUS'] = FALSE;
133 $this->checks['users_visible']['STATUS_MSG']= "";
134 $this->checks['users_visible']['ERROR_MSG'] = "";
135 $this->check_gosaAccounts();
137 $this->checks['acls']['TITLE'] = _("Checking for administrational account");
138 $this->checks['acls']['STATUS'] = FALSE;
139 $this->checks['acls']['STATUS_MSG']= "";
140 $this->checks['acls']['ERROR_MSG'] = "";
141 $this->check_administrativeAccount();
143 $this->checks['outside_users']['TITLE'] = _("Checking for users outside the people department.");
144 $this->checks['outside_users']['STATUS'] = FALSE;
145 $this->checks['outside_users']['STATUS_MSG']= "";
146 $this->checks['outside_users']['ERROR_MSG'] = "";
147 $this->search_outside_users();
149 $this->checks['outside_groups']['TITLE'] = _("Checking for groups outside the groups department.");
150 $this->checks['outside_groups']['STATUS'] = FALSE;
151 $this->checks['outside_groups']['STATUS_MSG']= "";
152 $this->checks['outside_groups']['ERROR_MSG'] = "";
153 $this->search_outside_groups();
155 $this->checks['outside_winstations']['TITLE'] = _("Checking for windows workstations outside the winstation department.");
156 $this->checks['outside_winstations']['STATUS'] = FALSE;
157 $this->checks['outside_winstations']['STATUS_MSG']= "";
158 $this->checks['outside_winstations']['ERROR_MSG'] = "";
159 $this->search_outside_winstations();
161 $this->checks['uidNumber_usage']['TITLE'] = _("Checking for multiple use of same uidNumber value.");
162 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
163 $this->checks['uidNumber_usage']['STATUS_MSG']= "";
164 $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
165 $this->check_uidNumber();
167 $this->checks['gidNumber_usage']['TITLE'] = _("Checking for multiple use of same gidNumber value.");
168 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
169 $this->checks['gidNumber_usage']['STATUS_MSG']= "";
170 $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
171 $this->check_gidNumber();
172 }
174 function check_uidNumber()
175 {
176 $cv = $this->parent->captured_values;
177 $ldap = new LDAP($cv['admin'],
178 $cv['password'],
179 $cv['connection'],
180 FALSE,
181 $cv['tls']);
183 $ldap->cd($cv['base']);
184 $res = $ldap->search("uidNumber=*",array("dn","uidNumber"));
185 if(!$res){
186 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
187 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
188 $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
189 return(false);
190 }
192 $this->check_uidNumbers= array();
193 $tmp = array();
194 while($attrs = $ldap->fetch()){
195 $tmp[$attrs['uidNumber'][0]][] = $attrs;
196 }
198 foreach($tmp as $id => $entries){
199 if(count($entries) > 1){
200 foreach($entries as $entry){
201 $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
202 }
203 }
204 }
206 if($this->check_uidNumbers){
207 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
208 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Failed");
209 $this->checks['uidNumber_usage']['ERROR_MSG'] =
210 sprintf(_("Found %s duplicated uidNumber values."),count($this->check_uidNumbers));
211 return(false);
212 }else{
213 $this->checks['uidNumber_usage']['STATUS'] = TRUE;
214 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
215 $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
216 return(TRUE);
217 }
218 }
220 function check_gidNumber()
221 {
222 $cv = $this->parent->captured_values;
223 $ldap = new LDAP($cv['admin'],
224 $cv['password'],
225 $cv['connection'],
226 FALSE,
227 $cv['tls']);
229 $ldap->cd($cv['base']);
230 $res = $ldap->search("gidNumber=*",array("dn","gidNumber"));
231 if(!$res){
232 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
233 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
234 $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
235 return(false);
236 }
238 $this->check_gidNumbers= array();
239 $tmp = array();
240 while($attrs = $ldap->fetch()){
241 $tmp[$attrs['gidNumber'][0]][] = $attrs;
242 }
244 foreach($tmp as $id => $entries){
245 if(count($entries) > 1){
246 foreach($entries as $entry){
247 $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
248 }
249 }
250 }
252 if($this->check_gidNumbers){
253 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
254 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Failed");
255 $this->checks['gidNumber_usage']['ERROR_MSG'] =
256 sprintf(_("Found %s duplicated gidNumber values."),count($this->check_gidNumbers));
257 return(false);
258 }else{
259 $this->checks['gidNumber_usage']['STATUS'] = TRUE;
260 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
261 $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
262 return(TRUE);
263 }
264 }
267 /* Search for winstations outside the winstation ou */
268 function search_outside_winstations()
269 {
270 $cv = $this->parent->captured_values;
271 $ldap = new LDAP($cv['admin'],
272 $cv['password'],
273 $cv['connection'],
274 FALSE,
275 $cv['tls']);
277 /* Get winstation ou */
278 if($cv['generic_settings']['wws_ou_active']) {
279 $winstation_ou = $cv['generic_settings']['ws_ou'];
280 }else{
281 $winstation_ou = "ou=winstations";
282 }
284 $ldap->cd($cv['base']);
285 $res = $ldap->search("(&(objectClass=posixGroup)(sambaGroupType=2)(sambaSID=*))",array("dn","sambaSID"));
286 if(!$res){
287 $this->checks['outside_winstations']['STATUS'] = FALSE;
288 $this->checks['outside_winstations']['STATUS_MSG']= _("Ldap query failed.");
289 $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
290 return(false);
291 }
293 $this->outside_winstations = array();
294 while($attrs = $ldap->fetch()){
295 if(preg_match("/-516$/","",$attrs['sambaSID'][0]) && !preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])){
296 $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
297 }
298 }
300 if(count($this->outside_winstations)){
301 $this->checks['outside_winstations']['STATUS'] = FALSE;
302 $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
303 $this->checks['outside_winstations']['ERROR_MSG'] =
304 sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
305 return(false);
306 }else{
307 $this->checks['outside_winstations']['STATUS'] = TRUE;
308 $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
309 $this->checks['outside_winstations']['ERROR_MSG'] = "";
310 return(TRUE);
311 }
312 }
315 /* Search for groups outside the group ou */
316 function search_outside_groups()
317 {
318 $cv = $this->parent->captured_values;
319 $ldap = new LDAP($cv['admin'],
320 $cv['password'],
321 $cv['connection'],
322 FALSE,
323 $cv['tls']);
325 $group_ou = $cv['groupou'];
326 $ldap->cd($cv['base']);
327 $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
328 if(!$res){
329 $this->checks['outside_groups']['STATUS'] = FALSE;
330 $this->checks['outside_groups']['STATUS_MSG']= _("Ldap query failed.");
331 $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
332 return(false);
333 }
336 $this->outside_groups = array();
337 while($attrs = $ldap->fetch()){
338 if(!preg_match("/^[^,]+,".normalizePreg($group_ou)."/",$attrs['dn'])){
339 $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
340 }
341 }
343 if(count($this->outside_groups)){
344 $this->checks['outside_groups']['STATUS'] = FALSE;
345 $this->checks['outside_groups']['STATUS_MSG']= _("Failed");
346 $this->checks['outside_groups']['ERROR_MSG'] =
347 sprintf(_("Found %s groups outside the selected group ou '%s'."),count($this->outside_groups),$group_ou);
348 return(false);
349 }else{
350 $this->checks['outside_groups']['STATUS'] = TRUE;
351 $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
352 $this->checks['outside_groups']['ERROR_MSG'] = "";
353 return(TRUE);
354 }
355 }
357 /* Search for users outside the people ou */
358 function search_outside_users()
359 {
360 $cv = $this->parent->captured_values;
361 $ldap = new LDAP($cv['admin'],
362 $cv['password'],
363 $cv['connection'],
364 FALSE,
365 $cv['tls']);
366 $people_ou = $cv['peopleou'];
367 $ldap->cd($cv['base']);
368 $res = $ldap->search("(objectClass=gosaAccount)",array("dn"));
369 if(!$res){
370 $this->checks['outside_users']['STATUS'] = FALSE;
371 $this->checks['outside_users']['STATUS_MSG']= _("Ldap query failed.");
372 $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
373 return(false);
374 }
377 $this->outside_users = array();
378 while($attrs = $ldap->fetch()){
379 if(!preg_match("/^[^,]+,".normalizePreg($people_ou)."/",$attrs['dn'])){
380 $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
381 }
382 }
384 if(count($this->outside_users)){
385 $this->checks['outside_users']['STATUS'] = FALSE;
386 $this->checks['outside_users']['STATUS_MSG']= _("Failed");
387 $this->checks['outside_users']['ERROR_MSG'] =
388 sprintf(_("Found %s users outside the selected user ou '%s'."),count($this->outside_users),$people_ou);
389 return(false);
390 }else{
391 $this->checks['outside_users']['STATUS'] = TRUE;
392 $this->checks['outside_users']['STATUS_MSG']= _("Ok");
393 $this->checks['outside_users']['ERROR_MSG'] = "";
394 return(TRUE);
395 }
396 }
399 /* Check ldap accessibility
400 * Create and remove a dummy object,
401 * to ensure that we have the necessary permissions
402 */
403 function check_ldap_permissions()
404 {
405 $cv = $this->parent->captured_values;
406 $ldap = new LDAP($cv['admin'],
407 $cv['password'],
408 $cv['connection'],
409 FALSE,
410 $cv['tls']);
412 /* Create dummy entry
413 */
414 $name = "GOsa_setup_text_entry_".session_id().rand(0,999999);
415 $dn = "ou=".$name.",".$cv['base'];
416 $testEntry= array();
417 $testEntry['objectClass'][]= "top";
418 $testEntry['objectClass'][]= "organizationalUnit";
419 $testEntry['objectClass'][]= "gosaDepartment";
420 $testEntry['description']= "Created by GOsa setup, this object can be removed.";
421 $testEntry['ou'] = $name;
423 /* check if simple ldap cat will be successful
424 */
425 $res = $ldap->cat($cv['base']);
426 if(!$res){
427 $this->checks['permissions']['STATUS'] = FALSE;
428 $this->checks['permissions']['STATUS_MSG']= _("Ldap query failed.");
429 $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
430 return(false);
431 }
433 /* Try to create dummy object
434 */
435 $ldap->cd ($dn);
436 $ldap->create_missing_trees($dn);
437 $res = $ldap->add($testEntry);
438 if(!$res){
439 gosa_log($ldap->get_error());
440 $this->checks['permissions']['STATUS'] = FALSE;
441 $this->checks['permissions']['STATUS_MSG']= _("Failed");
442 $this->checks['permissions']['ERROR_MSG'] =
443 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
444 return(false);
445 }
447 /* Try to remove created entry
448 */
449 $res = $ldap->rmDir($dn);
450 if(!$res){
451 gosa_log($ldap->get_error());
452 $this->checks['permissions']['STATUS'] = FALSE;
453 $this->checks['permissions']['STATUS_MSG']= _("Failed");
454 $this->checks['permissions']['ERROR_MSG'] =
455 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
456 return(false);
457 }
459 /* Create & remove of dummy object was successful */
460 $this->checks['permissions']['STATUS'] = TRUE;
461 $this->checks['permissions']['STATUS_MSG']= _("Ok");
462 $this->checks['permissions']['ERROR_MSG'] = "";
463 return(true);
464 }
467 /* Check if there are users which will
468 * be invisible for GOsa
469 */
470 function check_gosaAccounts()
471 {
472 /* Remember old list of ivisible users, to be able to set
473 * the 'html checked' status for the checkboxes again
474 */
475 $cnt_ok = 0;
476 $old = $this->users_to_migrate;
477 $this->users_to_migrate = array();
479 /* Get collected configuration settings */
480 $cv = $this->parent->captured_values;
482 /* Establish ldap connection */
483 $ldap = new LDAP($cv['admin'],
484 $cv['password'],
485 $cv['connection'],
486 FALSE,
487 $cv['tls']);
489 /* Get all invisible users
490 */
491 $ldap->cd($cv['base']);
492 $res =$ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
493 while($attrs = $ldap->fetch()){
494 if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
495 $attrs['checked'] = FALSE;
496 $attrs['before'] = "";
497 $attrs['after'] = "";
499 /* Set objects to selected, that were selected before reload */
500 if(isset($old[base64_encode($attrs['dn'])])){
501 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
502 }
503 $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
504 }
505 }
507 /* No invisible */
508 if(!$res){
509 $this->checks['users_visible']['STATUS'] = FALSE;
510 $this->checks['users_visible']['STATUS_MSG']= _("Ldap query failed.");
511 $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
512 }elseif(count($this->users_to_migrate) == 0){
513 $this->checks['users_visible']['STATUS'] = TRUE;
514 $this->checks['users_visible']['STATUS_MSG']= _("Ok");
515 $this->checks['users_visible']['ERROR_MSG'] = "";
516 }else{
517 $this->checks['users_visible']['STATUS'] = FALSE;
518 $this->checks['users_visible']['STATUS_MSG']= "";
519 $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."),
520 count($this->users_to_migrate));
521 $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
522 }
523 }
526 /* Start user account migration
527 */
528 function migrate_gosaAccounts($only_ldif = FALSE)
529 {
530 /* Get collected configuration settings */
531 $cv = $this->parent->captured_values;
533 /* Establish ldap connection */
534 $ldap = new LDAP($cv['admin'],
535 $cv['password'],
536 $cv['connection'],
537 FALSE,
538 $cv['tls']);
540 /* Add gosaAccount objectClass to the selected users
541 */
542 foreach($this->users_to_migrate as $key => $dep){
543 if($dep['checked']){
545 /* Get old objectClasses */
546 $ldap->cat($dep['dn'],array("objectClass"));
547 $attrs = $ldap->fetch();
549 /* Create new objectClass array */
550 $new_attrs = array();
551 $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
552 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
553 if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
554 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
555 }
556 }
558 /* Set info attributes for current object,
559 * or write changes to the ldap database
560 */
561 if($only_ldif){
562 $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
563 $this->users_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
564 }else{
565 $ldap->cd($attrs['dn']);
566 if(!$ldap->modify($new_attrs)){
567 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
568 return(false);
569 }
570 }
571 }
572 }
573 return(TRUE);
574 }
577 /* Check if there are invisible organizational Units
578 */
579 function check_organizationalUnits()
580 {
581 $cnt_ok = 0;
582 $old = $this->deps_to_migrate;
583 $this->deps_to_migrate = array();
585 /* Get collected configuration settings */
586 $cv = $this->parent->captured_values;
588 /* Establish ldap connection */
589 $ldap = new LDAP($cv['admin'],
590 $cv['password'],
591 $cv['connection'],
592 FALSE,
593 $cv['tls']);
595 /* Skip GOsa internal departments */
596 $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
597 "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
598 "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
599 "/(,|)ou=winstations,/");
602 /* Get all invisible departments */
603 $ldap->cd($cv['base']);
604 $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
605 while($attrs = $ldap->fetch()){
606 $attrs['checked'] = FALSE;
607 $attrs['before'] = "";
608 $attrs['after'] = "";
610 /* Set objects to selected, that were selected before reload */
611 if(isset($old[base64_encode($attrs['dn'])])){
612 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
613 }
614 $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
615 }
617 /* Filter returned list of departments and ensure that
618 * GOsa internal departments will not be listed
619 */
620 foreach($this->deps_to_migrate as $key => $attrs){
621 $dn = $attrs['dn'];
622 $skip = false;
623 foreach($skip_dns as $skip_dn){
624 if(preg_match($skip_dn,$dn)){
625 $skip = true;
626 }
627 }
628 if($skip){
629 unset($this->deps_to_migrate[$key]);
630 }
631 }
633 /* If we have no invisible departments found
634 * tell the user that everything is ok
635 */
636 if(!$res){
637 $this->checks['deps_visible']['STATUS'] = FALSE;
638 $this->checks['deps_visible']['STATUS_MSG']= _("Ldap query failed.");
639 $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
640 }elseif(count($this->deps_to_migrate) == 0 ){
641 $this->checks['deps_visible']['STATUS'] = TRUE;
642 $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
643 $this->checks['deps_visible']['ERROR_MSG'] = "";
644 }else{
645 $this->checks['deps_visible']['STATUS'] = FALSE;
646 $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
647 $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
648 $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
649 }
650 }
654 /* Start deparmtment migration */
655 function migrate_organizationalUnits($only_ldif = FALSE)
656 {
657 /* Get collected configuration settings */
658 $cv = $this->parent->captured_values;
660 /* Establish ldap connection */
661 $ldap = new LDAP($cv['admin'],
662 $cv['password'],
663 $cv['connection'],
664 FALSE,
665 $cv['tls']);
667 /* Add gosaDepartment objectClass to each selected entry
668 */
669 foreach($this->deps_to_migrate as $key => $dep){
670 if($dep['checked']){
672 /* Get current objectClasses */
673 $ldap->cat($dep['dn'],array("objectClass","description"));
674 $attrs = $ldap->fetch();
676 /* Create new objectClass attribute including gosaDepartment*/
677 $new_attrs = array();
678 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
679 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
680 }
681 $new_attrs['objectClass'][] = "gosaDepartment";
683 /* Append description it is missing */
684 if(!isset($attrs['description'])){
685 $new_attrs['description'][] = "GOsa department";
686 }
688 /* Depending on the parameter >only_diff< we save the changes as ldif
689 * or we write our changes directly to the ldap database
690 */
691 if($only_ldif){
692 $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
693 $this->deps_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
694 }else{
695 $ldap->cd($attrs['dn']);
696 if(!$ldap->modify($new_attrs)){
697 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
698 return(false);
699 }
700 }
701 }
702 }
703 return(TRUE);
704 }
707 /* Check Acls if there is at least one object with acls defined
708 */
709 function check_administrativeAccount()
710 {
711 /* Establish ldap connection */
712 $cv = $this->parent->captured_values;
713 $ldap = new LDAP($cv['admin'],
714 $cv['password'],
715 $cv['connection'],
716 FALSE,
717 $cv['tls']);
719 /* Search for gosaAcls */
720 $ldap->cd($cv['base']);
721 $res = $ldap->search("(&(objectClass=gosaAccount)(|(objectClass=posixAccount)".
722 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))");
723 if(!$res){
724 $this->checks['acls']['STATUS'] = FALSE;
725 $this->checks['acls']['STATUS_MSG']= _("Ldap query failed.");
726 $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
727 }elseif($ldap->count()){
728 $this->checks['acls']['STATUS'] = TRUE;
729 $this->checks['acls']['STATUS_MSG']= _("Ok");
730 }else{
731 $this->checks['acls']['STATUS'] = FALSE;
732 $this->checks['acls']['STATUS_MSG']= _("Failed");
733 $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create adminitrational account")."'>";
734 }
735 return($ldap->count()>=1);
736 }
739 function get_user_list()
740 {
741 /* Get collected configuration settings */
742 $cv = $this->parent->captured_values;
744 /* Establish ldap connection */
745 $ldap = new LDAP($cv['admin'],
746 $cv['password'],
747 $cv['connection'],
748 FALSE,
749 $cv['tls']);
751 $ldap->cd($cv['base']);
752 $ldap->search("(objectClass=gosaAccount)",array("dn"));
754 $tmp = array();
755 while($attrs = $ldap->fetch()){
756 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
757 }
759 return($tmp);
760 }
762 function get_group_list()
763 {
764 /* Get collected configuration settings */
765 $cv = $this->parent->captured_values;
767 /* Establish ldap connection */
768 $ldap = new LDAP($cv['admin'],
769 $cv['password'],
770 $cv['connection'],
771 FALSE,
772 $cv['tls']);
774 $ldap->cd($cv['base']);
775 $ldap->search("(objectClass=posixGroup)",array("dn"));
777 $tmp = array();
778 while($attrs = $ldap->fetch()){
779 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
780 }
782 return($tmp);
783 }
787 function create_admin($only_ldif = FALSE)
788 {
789 /* Reset '' */
790 $this->acl_create_changes="";
792 /* Object that should receive admin acls */
793 $dn = $this->acl_create_selected;
795 /* Get collected configuration settings */
796 $cv = $this->parent->captured_values;
798 /* Establish ldap connection */
799 $ldap = new LDAP($cv['admin'],
800 $cv['password'],
801 $cv['connection'],
802 FALSE,
803 $cv['tls']);
805 /* Get current base attributes */
806 $ldap->cd($cv['base']);
807 $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
808 $attrs = $ldap->fetch();
810 /* Add acls for the selcted user to the base */
811 $attrs_new['objectClass'] = array("gosaACL");
813 for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
814 if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
815 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
816 }
817 }
819 $acl = "0:sub:".base64_encode($dn).":all;cmdrw";
820 $attrs_new['gosaAclEntry'][] = $acl;
821 if(isset($attrs['gosaAclEntry'])){
822 for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
824 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
825 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
827 $data = ($prio+1).$rest;
828 $attrs_new['gosaAclEntry'][] = $data;
829 }
830 }
832 if($only_ldif){
833 $this->acl_create_changes ="\n".$cv['base']."\n";
834 $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
835 $this->acl_create_changes.="\n".$cv['base']."\n";
836 $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
837 }else{
839 $ldap->cd($cv['base']);
840 if(!$ldap->modify($attrs_new)){
841 print_red(sprintf(_("Adding acls for user '%s' failed, ldap says '%s'."),$dn,$ldap->get_error()));
842 }
843 }
844 }
847 function create_admin_user()
848 {
849 if(isset($_POST['new_user_password']) && !empty($_POST['new_user_password'])){
850 $pwd = $_POST['new_user_password'];
851 }else{
852 print_red(_("Please specify a valid password for the new GOsa admin user."));
853 return(FALSE);
854 }
856 /* Establish ldap connection */
857 $cv = $this->parent->captured_values;
858 $ldap = new LDAP($cv['admin'],
859 $cv['password'],
860 $cv['connection'],
861 FALSE,
862 $cv['tls']);
864 /* Get current base attributes */
865 $ldap->cd($cv['base']);
867 if($cv['peopledn'] == "cn"){
868 $dn = "cn=System Administrator,".$cv['peopleou'].",".$cv['base'];
869 }else{
870 $dn = "uid=admin,".$cv['peopleou'].",".$cv['base'];
871 }
873 $methods = @passwordMethod::get_available_methods_if_not_loaded();
874 $p_m = $methods[$cv['encryption']];
875 $p_c = new $p_m(array());
876 $hash = $p_c->generate_hash($pwd);
878 $new_user=array();
879 $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
880 $new_user['givenName'] = "System";
881 $new_user['sn'] = "Administrator";
882 $new_user['cn'] = "System Administrator";
883 $new_user['uid'] = "admin";
884 $new_user['userPassword'] = $hash;
886 $ldap->cd($cv['base']);
887 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
888 $ldap->cd($dn);
889 $res = $ldap->add($new_user);
890 $this->acl_create_selected = $dn;
891 $this->create_admin();
893 if(!$res){
894 print_red($ldap->get_error());
895 }
897 $this->acl_create_dialog=FALSE;
898 $this->check_administrativeAccount();
899 }
902 function execute()
903 {
904 /* Initialise checks if this is the first call */
905 if(!$this->checks_initialised || isset($_POST['reload'])){
906 $this->initialize_checks();
907 $this->checks_initialised = TRUE;
908 }
910 /*************
911 * Root object check
912 *************/
914 if(isset($_POST['retry_root_create'])){
915 $this->checkBase(FALSE);
916 }
918 /*************
919 * User Migration handling
920 *************/
922 if(isset($_POST['retry_acls'])){
923 $this->check_administrativeAccount();
924 }
926 if(isset($_POST['create_acls'])){
927 $this->acl_create_dialog = TRUE;
928 $this->dialog = TRUE;
929 }
931 if(isset($_POST['create_acls_cancel'])){
932 $this->acl_create_dialog = FALSE;
933 $this->dialog = FALSE;
934 }
936 if(isset($_POST['create_acls_create_confirmed'])){
937 $this->create_admin();
938 }
940 if(isset($_POST['create_acls_create'])){
941 $this->create_admin(TRUE);
942 }
944 if(isset($_POST['create_admin_user'])){
945 $this->create_admin_user();
946 }
948 if($this->acl_create_dialog){
949 $smarty = get_smarty();
950 $smarty->assign("new_user_password",@$_POST['new_user_password']);
951 $smarty->assign("users" ,$this->get_user_list());
952 $smarty->assign("users_cnt" ,count($this->get_user_list()));
953 $smarty->assign("groups",$this->get_group_list());
954 $smarty->assign("groups_cnt",count($this->get_group_list()));
955 $smarty->assign("type" ,$this->acl_create_type);
956 $smarty->assign("method","create_acls");
957 $smarty->assign("acl_create_selected",$this->acl_create_selected);
958 $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
959 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
960 }
962 /*************
963 * User Migration handling
964 *************/
966 /* Refresh list of deparments */
967 if(isset($_POST['users_visible_migrate_refresh'])){
968 $this->check_gosaAccounts();
969 }
971 /* Open migration dialog */
972 if(isset($_POST['users_visible_migrate'])){
973 $this->users_migration_dialog = TRUE;
974 $this->dialog =TRUE;
975 }
977 /* Close migration dialog */
978 if(isset($_POST['users_visible_migrate_close'])){
979 $this->users_migration_dialog = FALSE;
980 $this->dialog =FALSE;
981 }
983 /* Start migration */
984 if(isset($_POST['users_visible_migrate_migrate'])){
985 if($this->migrate_gosaAccounts()){
986 $this->check_gosaAccounts();
987 }
988 }
990 /* Start migration */
991 if(isset($_POST['users_visible_migrate_whatsdone'])){
992 $this->migrate_gosaAccounts(TRUE);
993 }
995 /* Display migration dialog */
996 if($this->users_migration_dialog){
997 $smarty = get_smarty();
998 $smarty->assign("users_to_migrate",$this->users_to_migrate);
999 $smarty->assign("method","migrate_users");
1000 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1001 }
1004 /*************
1005 * Department Migration handling
1006 *************/
1008 /* Refresh list of deparments */
1009 if(isset($_POST['deps_visible_migrate_refresh'])){
1010 $this->check_organizationalUnits();
1011 }
1013 /* Open migration dialog */
1014 if(isset($_POST['deps_visible_migrate'])){
1015 $this->dep_migration_dialog = TRUE;
1016 $this->dialog =TRUE;
1017 }
1019 /* Close migration dialog */
1020 if(isset($_POST['deps_visible_migrate_close'])){
1021 $this->dep_migration_dialog = FALSE;
1022 $this->dialog =FALSE;
1023 }
1025 /* Start migration */
1026 if(isset($_POST['deps_visible_migrate_migrate'])){
1027 if($this->migrate_organizationalUnits()){
1028 $this->check_organizationalUnits();
1029 }
1030 }
1032 /* Start migration */
1033 if(isset($_POST['deps_visible_migrate_whatsdone'])){
1034 $this->migrate_organizationalUnits(TRUE);
1035 }
1037 /* Display migration dialog */
1038 if($this->dep_migration_dialog){
1039 $smarty = get_smarty();
1040 $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
1041 $smarty->assign("method","migrate_deps");
1042 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1043 }
1045 $smarty = get_smarty();
1046 $smarty->assign("checks",$this->checks);
1047 $smarty->assign("method","default");
1048 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1049 }
1052 function save_object()
1053 {
1054 /* Get "create acl" dialog posts */
1055 if($this->acl_create_dialog){
1056 if(isset($_POST['create_acls_create'])){
1057 if(isset($_POST['create_acls_selected'])){
1058 $this->acl_create_selected = base64_decode($_POST['create_acls_selected']);
1059 }else{
1060 $this->acl_create_selected = "";
1061 }
1062 }
1064 if(isset($_POST['create_acls_create_abort'])){
1065 $this->acl_create_selected = "";
1066 }
1068 if(isset($_POST['acl_create_type'])){
1069 $this->acl_create_type = $_POST['acl_create_type'];
1070 }
1071 }
1073 /* Get selected departments */
1074 if($this->dep_migration_dialog){
1075 foreach($this->deps_to_migrate as $id => $data){
1076 if(isset($_POST['migrate_'.$id])){
1077 $this->deps_to_migrate[$id]['checked'] = TRUE;
1078 }else{
1079 $this->deps_to_migrate[$id]['checked'] = FALSE;
1080 }
1081 }
1082 }
1084 /* Get selected users */
1085 if($this->users_migration_dialog){
1086 foreach($this->users_to_migrate as $id => $data){
1087 if(isset($_POST['migrate_'.$id])){
1088 $this->users_to_migrate[$id]['checked'] = TRUE;
1089 }else{
1090 $this->users_to_migrate[$id]['checked'] = FALSE;
1091 }
1092 }
1093 }
1094 }
1097 // checks for valid base entry
1098 function checkBase($just_check = TRUE)
1099 {
1100 /* Get collected setup informations */
1101 $cv = $this->parent->captured_values;
1103 /* Establish ldap connection */
1104 $ldap = new LDAP($cv['admin'],
1105 $cv['password'],
1106 $cv['connection'],
1107 FALSE,
1108 $cv['tls']);
1110 /* Check if root object exists */
1111 $ldap->cd($cv['base']);
1112 $res = $ldap->search("(objectClass=*)");
1113 $err = ldap_errno($ldap->cid);
1115 if( !$res ||
1116 $err == 0x20 || # LDAP_NO_SUCH_OBJECT
1117 $err == 0x40) { # LDAP_NAMING_VIOLATION
1119 /* Root object doesn't exists
1120 */
1121 if($just_check){
1122 $this->checks['root']['STATUS'] = FALSE;
1123 $this->checks['root']['STATUS_MSG']= _("Failed");
1124 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1125 return(FALSE);
1126 }else{
1128 echo "REMOVE this : Autocreation of the root object will be donw be create_missing_trees later. !!!!!!!";
1130 /* Try to find out which values are necessary */
1131 $tmp = $ldap->get_objectclasses();
1132 $oc = $tmp['organization'];
1134 $must_attrs = $oc['MUST'];
1135 if(!is_array($must_attrs)){
1136 $must_attrs = array($must_attrs);
1137 }
1139 /* Root object does not exists try to create it */
1140 $ldapadd["objectclass"][0]="top";
1141 $ldapadd["objectclass"][1]="organization";
1143 /* Try to fill all collected must attributes */
1144 $base_parts = preg_split("/,/",$cv['base']);
1145 foreach($must_attrs as $attr){
1146 foreach($base_parts as $part){
1147 if(preg_match("/^".$attr."=/",$part) && !isset($ldapadd[$attr])){
1148 $ldapadd[$attr]= preg_replace("/^[^=]*+=/","",$part);
1149 }
1150 }
1151 }
1153 /* Add root object */
1154 $ldap->cd($cv['base']);
1155 $res = $ldap->add($ldapadd);
1157 /* Add root object */
1158 # $ldap->cd($cv['base']);
1159 # $res = $ldap->create_missing_trees($cv['base']);
1161 /* If adding failed, tell the user */
1162 if(!$res){
1163 $this->checks['root']['STATUS'] = FALSE;
1164 $this->checks['root']['STATUS_MSG']= _("Failed");
1165 $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1166 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1167 return($res);;
1168 }
1169 }
1170 }
1172 /* Create & remove of dummy object was successful */
1173 $this->checks['root']['STATUS'] = TRUE;
1174 $this->checks['root']['STATUS_MSG']= _("Ok");
1175 }
1178 /* Return ldif information for a
1179 * given attribute array
1180 */
1181 function array_to_ldif($atts)
1182 {
1183 $ret = "";
1184 unset($atts['count']);
1185 unset($atts['dn']);
1186 foreach($atts as $name => $value){
1187 if(is_numeric($name)) {
1188 continue;
1189 }
1190 if(is_array($value)){
1191 unset($value['count']);
1192 foreach($value as $a_val){
1193 $ret .= $name.": ". $a_val."\n";
1194 }
1195 }else{
1196 $ret .= $name.": ". $value."\n";
1197 }
1198 }
1199 return(preg_replace("/\n$/","",$ret));
1200 }
1201 }
1203 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1204 ?>