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 while($attrs = $ldap->fetch()){
194 $tmp[$attrs['uidNumber'][0]][] = $attrs;
195 }
197 foreach($tmp as $id => $entries){
198 if(count($entries) > 1){
199 foreach($entries as $entry){
200 $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
201 }
202 }
203 }
205 if($this->check_uidNumbers){
206 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
207 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Failed");
208 $this->checks['uidNumber_usage']['ERROR_MSG'] =
209 sprintf(_("Found %s duplicated uidNumber values."),count($this->check_uidNumbers));
210 return(false);
211 }else{
212 $this->checks['uidNumber_usage']['STATUS'] = TRUE;
213 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
214 $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
215 return(TRUE);
216 }
217 }
219 function check_gidNumber()
220 {
221 $cv = $this->parent->captured_values;
222 $ldap = new LDAP($cv['admin'],
223 $cv['password'],
224 $cv['connection'],
225 FALSE,
226 $cv['tls']);
228 $ldap->cd($cv['base']);
229 $res = $ldap->search("gidNumber=*",array("dn","gidNumber"));
230 if(!$res){
231 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
232 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
233 $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
234 return(false);
235 }
237 $this->check_gidNumbers= array();
238 while($attrs = $ldap->fetch()){
239 $tmp[$attrs['gidNumber'][0]][] = $attrs;
240 }
242 foreach($tmp as $id => $entries){
243 if(count($entries) > 1){
244 foreach($entries as $entry){
245 $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
246 }
247 }
248 }
250 if($this->check_gidNumbers){
251 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
252 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Failed");
253 $this->checks['gidNumber_usage']['ERROR_MSG'] =
254 sprintf(_("Found %s duplicated gidNumber values."),count($this->check_gidNumbers));
255 return(false);
256 }else{
257 $this->checks['gidNumber_usage']['STATUS'] = TRUE;
258 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
259 $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
260 return(TRUE);
261 }
262 }
265 /* Search for winstations outside the winstation ou */
266 function search_outside_winstations()
267 {
268 $cv = $this->parent->captured_values;
269 $ldap = new LDAP($cv['admin'],
270 $cv['password'],
271 $cv['connection'],
272 FALSE,
273 $cv['tls']);
275 /* Get winstation ou */
276 if($cv['generic_settings']['wws_ou_active']) {
277 $winstation_ou = $cv['generic_settings']['ws_ou'];
278 }else{
279 $winstation_ou = "ou=winstations";
280 }
282 $ldap->cd($cv['base']);
283 $res = $ldap->search("(&(objectClass=posixGroup)(sambaGroupType=2)(sambaSID=*))",array("dn","sambaSID"));
284 if(!$res){
285 $this->checks['outside_winstations']['STATUS'] = FALSE;
286 $this->checks['outside_winstations']['STATUS_MSG']= _("Ldap query failed.");
287 $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
288 return(false);
289 }
291 $this->outside_winstations = array();
292 while($attrs = $ldap->fetch()){
293 if(preg_match("/-516$/","",$attrs['sambaSID'][0]) && !preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])){
294 $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
295 }
296 }
298 if(count($this->outside_winstations)){
299 $this->checks['outside_winstations']['STATUS'] = FALSE;
300 $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
301 $this->checks['outside_winstations']['ERROR_MSG'] =
302 sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
303 return(false);
304 }else{
305 $this->checks['outside_winstations']['STATUS'] = TRUE;
306 $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
307 $this->checks['outside_winstations']['ERROR_MSG'] = "";
308 return(TRUE);
309 }
310 }
313 /* Search for groups outside the group ou */
314 function search_outside_groups()
315 {
316 $cv = $this->parent->captured_values;
317 $ldap = new LDAP($cv['admin'],
318 $cv['password'],
319 $cv['connection'],
320 FALSE,
321 $cv['tls']);
323 $group_ou = $cv['groupou'];
324 $ldap->cd($cv['base']);
325 $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
326 if(!$res){
327 $this->checks['outside_groups']['STATUS'] = FALSE;
328 $this->checks['outside_groups']['STATUS_MSG']= _("Ldap query failed.");
329 $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
330 return(false);
331 }
334 $this->outside_groups = array();
335 while($attrs = $ldap->fetch()){
336 if(!preg_match("/^[^,]+,".normalizePreg($group_ou)."/",$attrs['dn'])){
337 $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
338 }
339 }
341 if(count($this->outside_groups)){
342 $this->checks['outside_groups']['STATUS'] = FALSE;
343 $this->checks['outside_groups']['STATUS_MSG']= _("Failed");
344 $this->checks['outside_groups']['ERROR_MSG'] =
345 sprintf(_("Found %s groups outside the selected group ou '%s'."),count($this->outside_groups),$group_ou);
346 return(false);
347 }else{
348 $this->checks['outside_groups']['STATUS'] = TRUE;
349 $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
350 $this->checks['outside_groups']['ERROR_MSG'] = "";
351 return(TRUE);
352 }
353 }
355 /* Search for users outside the people ou */
356 function search_outside_users()
357 {
358 $cv = $this->parent->captured_values;
359 $ldap = new LDAP($cv['admin'],
360 $cv['password'],
361 $cv['connection'],
362 FALSE,
363 $cv['tls']);
364 $people_ou = $cv['peopleou'];
365 $ldap->cd($cv['base']);
366 $res = $ldap->search("(objectClass=gosaAccount)",array("dn"));
367 if(!$res){
368 $this->checks['outside_users']['STATUS'] = FALSE;
369 $this->checks['outside_users']['STATUS_MSG']= _("Ldap query failed.");
370 $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
371 return(false);
372 }
375 $this->outside_users = array();
376 while($attrs = $ldap->fetch()){
377 if(!preg_match("/^[^,]+,".normalizePreg($people_ou)."/",$attrs['dn'])){
378 $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
379 }
380 }
382 if(count($this->outside_users)){
383 $this->checks['outside_users']['STATUS'] = FALSE;
384 $this->checks['outside_users']['STATUS_MSG']= _("Failed");
385 $this->checks['outside_users']['ERROR_MSG'] =
386 sprintf(_("Found %s users outside the selected user ou '%s'."),count($this->outside_users),$people_ou);
387 return(false);
388 }else{
389 $this->checks['outside_users']['STATUS'] = TRUE;
390 $this->checks['outside_users']['STATUS_MSG']= _("Ok");
391 $this->checks['outside_users']['ERROR_MSG'] = "";
392 return(TRUE);
393 }
394 }
397 /* Check ldap accessibility
398 * Create and remove a dummy object,
399 * to ensure that we have the necessary permissions
400 */
401 function check_ldap_permissions()
402 {
403 $cv = $this->parent->captured_values;
404 $ldap = new LDAP($cv['admin'],
405 $cv['password'],
406 $cv['connection'],
407 FALSE,
408 $cv['tls']);
410 /* Create dummy entry
411 */
412 $name = "GOsa_setup_text_entry_".session_id().rand(0,999999);
413 $dn = "ou=".$name.",".$cv['base'];
414 $testEntry= array();
415 $testEntry['objectClass'][]= "top";
416 $testEntry['objectClass'][]= "organizationalUnit";
417 $testEntry['objectClass'][]= "gosaDepartment";
418 $testEntry['description']= "Created by GOsa setup, this object can be removed.";
419 $testEntry['ou'] = $name;
421 /* check if simple ldap cat will be successful
422 */
423 $res = $ldap->cat($cv['base']);
424 if(!$res){
425 $this->checks['permissions']['STATUS'] = FALSE;
426 $this->checks['permissions']['STATUS_MSG']= _("Ldap query failed.");
427 $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
428 return(false);
429 }
431 /* Try to create dummy object
432 */
433 $ldap->cd ($dn);
434 $ldap->create_missing_trees($dn);
435 $res = $ldap->add($testEntry);
436 if(!$res){
437 gosa_log($ldap->get_error());
438 $this->checks['permissions']['STATUS'] = FALSE;
439 $this->checks['permissions']['STATUS_MSG']= _("Failed");
440 $this->checks['permissions']['ERROR_MSG'] =
441 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
442 return(false);
443 }
445 /* Try to remove created entry
446 */
447 $res = $ldap->rmDir($dn);
448 if(!$res){
449 gosa_log($ldap->get_error());
450 $this->checks['permissions']['STATUS'] = FALSE;
451 $this->checks['permissions']['STATUS_MSG']= _("Failed");
452 $this->checks['permissions']['ERROR_MSG'] =
453 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
454 return(false);
455 }
457 /* Create & remove of dummy object was successful */
458 $this->checks['permissions']['STATUS'] = TRUE;
459 $this->checks['permissions']['STATUS_MSG']= _("Ok");
460 $this->checks['permissions']['ERROR_MSG'] = "";
461 return(true);
462 }
465 /* Check if there are users which will
466 * be invisible for GOsa
467 */
468 function check_gosaAccounts()
469 {
470 /* Remember old list of ivisible users, to be able to set
471 * the 'html checked' status for the checkboxes again
472 */
473 $cnt_ok = 0;
474 $old = $this->users_to_migrate;
475 $this->users_to_migrate = array();
477 /* Get collected configuration settings */
478 $cv = $this->parent->captured_values;
480 /* Establish ldap connection */
481 $ldap = new LDAP($cv['admin'],
482 $cv['password'],
483 $cv['connection'],
484 FALSE,
485 $cv['tls']);
487 /* Get all invisible users
488 */
489 $ldap->cd($cv['base']);
490 $res =$ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
491 while($attrs = $ldap->fetch()){
492 if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
493 $attrs['checked'] = FALSE;
494 $attrs['before'] = "";
495 $attrs['after'] = "";
497 /* Set objects to selected, that were selected before reload */
498 if(isset($old[base64_encode($attrs['dn'])])){
499 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
500 }
501 $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
502 }
503 }
505 /* No invisible */
506 if(!$res){
507 $this->checks['users_visible']['STATUS'] = FALSE;
508 $this->checks['users_visible']['STATUS_MSG']= _("Ldap query failed.");
509 $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
510 }elseif(count($this->users_to_migrate) == 0){
511 $this->checks['users_visible']['STATUS'] = TRUE;
512 $this->checks['users_visible']['STATUS_MSG']= _("Ok");
513 $this->checks['users_visible']['ERROR_MSG'] = "";
514 }else{
515 $this->checks['users_visible']['STATUS'] = FALSE;
516 $this->checks['users_visible']['STATUS_MSG']= "";
517 $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."),
518 count($this->users_to_migrate));
519 $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
520 }
521 }
524 /* Start user account migration
525 */
526 function migrate_gosaAccounts($only_ldif = FALSE)
527 {
528 /* Get collected configuration settings */
529 $cv = $this->parent->captured_values;
531 /* Establish ldap connection */
532 $ldap = new LDAP($cv['admin'],
533 $cv['password'],
534 $cv['connection'],
535 FALSE,
536 $cv['tls']);
538 /* Add gosaAccount objectClass to the selected users
539 */
540 foreach($this->users_to_migrate as $key => $dep){
541 if($dep['checked']){
543 /* Get old objectClasses */
544 $ldap->cat($dep['dn'],array("objectClass"));
545 $attrs = $ldap->fetch();
547 /* Create new objectClass array */
548 $new_attrs = array();
549 $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
550 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
551 if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
552 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
553 }
554 }
556 /* Set info attributes for current object,
557 * or write changes to the ldap database
558 */
559 if($only_ldif){
560 $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
561 $this->users_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
562 }else{
563 $ldap->cd($attrs['dn']);
564 if(!$ldap->modify($new_attrs)){
565 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
566 return(false);
567 }
568 }
569 }
570 }
571 return(TRUE);
572 }
575 /* Check if there are invisible organizational Units
576 */
577 function check_organizationalUnits()
578 {
579 $cnt_ok = 0;
580 $old = $this->deps_to_migrate;
581 $this->deps_to_migrate = array();
583 /* Get collected configuration settings */
584 $cv = $this->parent->captured_values;
586 /* Establish ldap connection */
587 $ldap = new LDAP($cv['admin'],
588 $cv['password'],
589 $cv['connection'],
590 FALSE,
591 $cv['tls']);
593 /* Skip GOsa internal departments */
594 $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
595 "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
596 "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
597 "/(,|)ou=winstations,/");
600 /* Get all invisible departments */
601 $ldap->cd($cv['base']);
602 $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
603 while($attrs = $ldap->fetch()){
604 $attrs['checked'] = FALSE;
605 $attrs['before'] = "";
606 $attrs['after'] = "";
608 /* Set objects to selected, that were selected before reload */
609 if(isset($old[base64_encode($attrs['dn'])])){
610 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
611 }
612 $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
613 }
615 /* Filter returned list of departments and ensure that
616 * GOsa internal departments will not be listed
617 */
618 foreach($this->deps_to_migrate as $key => $attrs){
619 $dn = $attrs['dn'];
620 $skip = false;
621 foreach($skip_dns as $skip_dn){
622 if(preg_match($skip_dn,$dn)){
623 $skip = true;
624 }
625 }
626 if($skip){
627 unset($this->deps_to_migrate[$key]);
628 }
629 }
631 /* If we have no invisible departments found
632 * tell the user that everything is ok
633 */
634 if(!$res){
635 $this->checks['deps_visible']['STATUS'] = FALSE;
636 $this->checks['deps_visible']['STATUS_MSG']= _("Ldap query failed.");
637 $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
638 }elseif(count($this->deps_to_migrate) == 0 ){
639 $this->checks['deps_visible']['STATUS'] = TRUE;
640 $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
641 $this->checks['deps_visible']['ERROR_MSG'] = "";
642 }else{
643 $this->checks['deps_visible']['STATUS'] = FALSE;
644 $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
645 $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
646 $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
647 }
648 }
652 /* Start deparmtment migration */
653 function migrate_organizationalUnits($only_ldif = FALSE)
654 {
655 /* Get collected configuration settings */
656 $cv = $this->parent->captured_values;
658 /* Establish ldap connection */
659 $ldap = new LDAP($cv['admin'],
660 $cv['password'],
661 $cv['connection'],
662 FALSE,
663 $cv['tls']);
665 /* Add gosaDepartment objectClass to each selected entry
666 */
667 foreach($this->deps_to_migrate as $key => $dep){
668 if($dep['checked']){
670 /* Get current objectClasses */
671 $ldap->cat($dep['dn'],array("objectClass","description"));
672 $attrs = $ldap->fetch();
674 /* Create new objectClass attribute including gosaDepartment*/
675 $new_attrs = array();
676 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
677 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
678 }
679 $new_attrs['objectClass'][] = "gosaDepartment";
681 /* Append description it is missing */
682 if(!isset($attrs['description'])){
683 $new_attrs['description'][] = "GOsa department";
684 }
686 /* Depending on the parameter >only_diff< we save the changes as ldif
687 * or we write our changes directly to the ldap database
688 */
689 if($only_ldif){
690 $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
691 $this->deps_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
692 }else{
693 $ldap->cd($attrs['dn']);
694 if(!$ldap->modify($new_attrs)){
695 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
696 return(false);
697 }
698 }
699 }
700 }
701 return(TRUE);
702 }
705 /* Check Acls if there is at least one object with acls defined
706 */
707 function check_administrativeAccount()
708 {
709 /* Establish ldap connection */
710 $cv = $this->parent->captured_values;
711 $ldap = new LDAP($cv['admin'],
712 $cv['password'],
713 $cv['connection'],
714 FALSE,
715 $cv['tls']);
717 /* Search for gosaAcls */
718 $ldap->cd($cv['base']);
719 $res = $ldap->search("(&(objectClass=gosaAccount)(|(objectClass=posixAccount)".
720 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))");
721 if(!$res){
722 $this->checks['acls']['STATUS'] = FALSE;
723 $this->checks['acls']['STATUS_MSG']= _("Ldap query failed.");
724 $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
725 }elseif($ldap->count()){
726 $this->checks['acls']['STATUS'] = TRUE;
727 $this->checks['acls']['STATUS_MSG']= _("Ok");
728 }else{
729 $this->checks['acls']['STATUS'] = FALSE;
730 $this->checks['acls']['STATUS_MSG']= _("Failed");
731 $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create adminitrational account")."'>";
732 }
733 return($ldap->count()>=1);
734 }
737 function get_user_list()
738 {
739 /* Get collected configuration settings */
740 $cv = $this->parent->captured_values;
742 /* Establish ldap connection */
743 $ldap = new LDAP($cv['admin'],
744 $cv['password'],
745 $cv['connection'],
746 FALSE,
747 $cv['tls']);
749 $ldap->cd($cv['base']);
750 $ldap->search("(objectClass=gosaAccount)",array("dn"));
752 $tmp = array();
753 while($attrs = $ldap->fetch()){
754 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
755 }
757 return($tmp);
758 }
760 function get_group_list()
761 {
762 /* Get collected configuration settings */
763 $cv = $this->parent->captured_values;
765 /* Establish ldap connection */
766 $ldap = new LDAP($cv['admin'],
767 $cv['password'],
768 $cv['connection'],
769 FALSE,
770 $cv['tls']);
772 $ldap->cd($cv['base']);
773 $ldap->search("(objectClass=posixGroup)",array("dn"));
775 $tmp = array();
776 while($attrs = $ldap->fetch()){
777 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
778 }
780 return($tmp);
781 }
785 function create_admin($only_ldif = FALSE)
786 {
787 /* Reset '' */
788 $this->acl_create_changes="";
790 /* Object that should receive admin acls */
791 $dn = $this->acl_create_selected;
793 /* Get collected configuration settings */
794 $cv = $this->parent->captured_values;
796 /* Establish ldap connection */
797 $ldap = new LDAP($cv['admin'],
798 $cv['password'],
799 $cv['connection'],
800 FALSE,
801 $cv['tls']);
803 /* Get current base attributes */
804 $ldap->cd($cv['base']);
805 $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
806 $attrs = $ldap->fetch();
808 /* Add acls for the selcted user to the base */
809 $attrs_new['objectClass'] = array("gosaACL");
811 for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
812 if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
813 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
814 }
815 }
817 $acl = "0:sub:".base64_encode($dn).":all;cmdrw";
818 $attrs_new['gosaAclEntry'][] = $acl;
819 if(isset($attrs['gosaAclEntry'])){
820 for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
822 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
823 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
825 $data = ($prio+1).$rest;
826 $attrs_new['gosaAclEntry'][] = $data;
827 }
828 }
830 if($only_ldif){
831 $this->acl_create_changes ="\n".$cv['base']."\n";
832 $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
833 $this->acl_create_changes.="\n".$cv['base']."\n";
834 $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
835 }else{
837 $ldap->cd($cv['base']);
838 if(!$ldap->modify($attrs_new)){
839 print_red(sprintf(_("Adding acls for user '%s' failed, ldap says '%s'."),$dn,$ldap->get_error()));
840 }
841 }
842 }
845 function create_admin_user()
846 {
847 if(isset($_POST['new_user_password']) && !empty($_POST['new_user_password'])){
848 $pwd = $_POST['new_user_password'];
849 }else{
850 print_red(_("Please specify a valid password for the new GOsa admin user."));
851 return(FALSE);
852 }
854 /* Establish ldap connection */
855 $cv = $this->parent->captured_values;
856 $ldap = new LDAP($cv['admin'],
857 $cv['password'],
858 $cv['connection'],
859 FALSE,
860 $cv['tls']);
862 /* Get current base attributes */
863 $ldap->cd($cv['base']);
865 if($cv['peopledn'] == "cn"){
866 $dn = "cn=System Administrator,".$cv['peopleou'].",".$cv['base'];
867 }else{
868 $dn = "uid=admin,".$cv['peopleou'].",".$cv['base'];
869 }
871 $methods = @passwordMethod::get_available_methods_if_not_loaded();
872 $p_m = $methods[$cv['encryption']];
873 $p_c = new $p_m(array());
874 $hash = $p_c->generate_hash($pwd);
876 $new_user=array();
877 $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
878 $new_user['givenName'] = "System";
879 $new_user['sn'] = "Administrator";
880 $new_user['cn'] = "System Administrator";
881 $new_user['uid'] = "admin";
882 $new_user['userPassword'] = $hash;
884 $ldap->cd($cv['base']);
885 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
886 $ldap->cd($dn);
887 $res = $ldap->add($new_user);
888 $this->acl_create_selected = $dn;
889 $this->create_admin();
891 if(!$res){
892 print_red($ldap->get_error());
893 }
895 $this->acl_create_dialog=FALSE;
896 $this->check_administrativeAccount();
897 }
900 function execute()
901 {
902 /* Initialise checks if this is the first call */
903 if(!$this->checks_initialised || isset($_POST['reload'])){
904 $this->initialize_checks();
905 $this->checks_initialised = TRUE;
906 }
908 /*************
909 * Root object check
910 *************/
912 if(isset($_POST['retry_root_create'])){
913 $this->checkBase(FALSE);
914 }
916 /*************
917 * User Migration handling
918 *************/
920 if(isset($_POST['retry_acls'])){
921 $this->check_administrativeAccount();
922 }
924 if(isset($_POST['create_acls'])){
925 $this->acl_create_dialog = TRUE;
926 $this->dialog = TRUE;
927 }
929 if(isset($_POST['create_acls_cancel'])){
930 $this->acl_create_dialog = FALSE;
931 $this->dialog = FALSE;
932 }
934 if(isset($_POST['create_acls_create_confirmed'])){
935 $this->create_admin();
936 }
938 if(isset($_POST['create_acls_create'])){
939 $this->create_admin(TRUE);
940 }
942 if(isset($_POST['create_admin_user'])){
943 $this->create_admin_user();
944 }
946 if($this->acl_create_dialog){
947 $smarty = get_smarty();
948 $smarty->assign("new_user_password",@$_POST['new_user_password']);
949 $smarty->assign("users" ,$this->get_user_list());
950 $smarty->assign("users_cnt" ,count($this->get_user_list()));
951 $smarty->assign("groups",$this->get_group_list());
952 $smarty->assign("groups_cnt",count($this->get_group_list()));
953 $smarty->assign("type" ,$this->acl_create_type);
954 $smarty->assign("method","create_acls");
955 $smarty->assign("acl_create_selected",$this->acl_create_selected);
956 $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
957 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
958 }
960 /*************
961 * User Migration handling
962 *************/
964 /* Refresh list of deparments */
965 if(isset($_POST['users_visible_migrate_refresh'])){
966 $this->check_gosaAccounts();
967 }
969 /* Open migration dialog */
970 if(isset($_POST['users_visible_migrate'])){
971 $this->users_migration_dialog = TRUE;
972 $this->dialog =TRUE;
973 }
975 /* Close migration dialog */
976 if(isset($_POST['users_visible_migrate_close'])){
977 $this->users_migration_dialog = FALSE;
978 $this->dialog =FALSE;
979 }
981 /* Start migration */
982 if(isset($_POST['users_visible_migrate_migrate'])){
983 if($this->migrate_gosaAccounts()){
984 $this->check_gosaAccounts();
985 }
986 }
988 /* Start migration */
989 if(isset($_POST['users_visible_migrate_whatsdone'])){
990 $this->migrate_gosaAccounts(TRUE);
991 }
993 /* Display migration dialog */
994 if($this->users_migration_dialog){
995 $smarty = get_smarty();
996 $smarty->assign("users_to_migrate",$this->users_to_migrate);
997 $smarty->assign("method","migrate_users");
998 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
999 }
1002 /*************
1003 * Department Migration handling
1004 *************/
1006 /* Refresh list of deparments */
1007 if(isset($_POST['deps_visible_migrate_refresh'])){
1008 $this->check_organizationalUnits();
1009 }
1011 /* Open migration dialog */
1012 if(isset($_POST['deps_visible_migrate'])){
1013 $this->dep_migration_dialog = TRUE;
1014 $this->dialog =TRUE;
1015 }
1017 /* Close migration dialog */
1018 if(isset($_POST['deps_visible_migrate_close'])){
1019 $this->dep_migration_dialog = FALSE;
1020 $this->dialog =FALSE;
1021 }
1023 /* Start migration */
1024 if(isset($_POST['deps_visible_migrate_migrate'])){
1025 if($this->migrate_organizationalUnits()){
1026 $this->check_organizationalUnits();
1027 }
1028 }
1030 /* Start migration */
1031 if(isset($_POST['deps_visible_migrate_whatsdone'])){
1032 $this->migrate_organizationalUnits(TRUE);
1033 }
1035 /* Display migration dialog */
1036 if($this->dep_migration_dialog){
1037 $smarty = get_smarty();
1038 $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
1039 $smarty->assign("method","migrate_deps");
1040 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1041 }
1043 $smarty = get_smarty();
1044 $smarty->assign("checks",$this->checks);
1045 $smarty->assign("method","default");
1046 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1047 }
1050 function save_object()
1051 {
1052 /* Get "create acl" dialog posts */
1053 if($this->acl_create_dialog){
1054 if(isset($_POST['create_acls_create'])){
1055 if(isset($_POST['create_acls_selected'])){
1056 $this->acl_create_selected = base64_decode($_POST['create_acls_selected']);
1057 }else{
1058 $this->acl_create_selected = "";
1059 }
1060 }
1062 if(isset($_POST['create_acls_create_abort'])){
1063 $this->acl_create_selected = "";
1064 }
1066 if(isset($_POST['acl_create_type'])){
1067 $this->acl_create_type = $_POST['acl_create_type'];
1068 }
1069 }
1071 /* Get selected departments */
1072 if($this->dep_migration_dialog){
1073 foreach($this->deps_to_migrate as $id => $data){
1074 if(isset($_POST['migrate_'.$id])){
1075 $this->deps_to_migrate[$id]['checked'] = TRUE;
1076 }else{
1077 $this->deps_to_migrate[$id]['checked'] = FALSE;
1078 }
1079 }
1080 }
1082 /* Get selected users */
1083 if($this->users_migration_dialog){
1084 foreach($this->users_to_migrate as $id => $data){
1085 if(isset($_POST['migrate_'.$id])){
1086 $this->users_to_migrate[$id]['checked'] = TRUE;
1087 }else{
1088 $this->users_to_migrate[$id]['checked'] = FALSE;
1089 }
1090 }
1091 }
1092 }
1095 // checks for valid base entry
1096 function checkBase($just_check = TRUE)
1097 {
1098 /* Get collected setup informations */
1099 $cv = $this->parent->captured_values;
1101 /* Establish ldap connection */
1102 $ldap = new LDAP($cv['admin'],
1103 $cv['password'],
1104 $cv['connection'],
1105 FALSE,
1106 $cv['tls']);
1108 /* Check if root object exists */
1109 $ldap->cd($cv['base']);
1110 $res = $ldap->search("(objectClass=*)");
1111 $err = ldap_errno($ldap->cid);
1113 if( !$res ||
1114 $err == 0x20 || # LDAP_NO_SUCH_OBJECT
1115 $err == 0x40) { # LDAP_NAMING_VIOLATION
1117 /* Root object doesn't exists
1118 */
1119 if($just_check){
1120 $this->checks['root']['STATUS'] = FALSE;
1121 $this->checks['root']['STATUS_MSG']= _("Failed");
1122 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1123 return(FALSE);
1124 }else{
1126 /* Try to find out which values are necessary */
1127 $tmp = $ldap->get_objectclasses();
1128 $oc = $tmp['organization'];
1130 $must_attrs = $oc['MUST'];
1131 if(!is_array($must_attrs)){
1132 $must_attrs = array($must_attrs);
1133 }
1135 /* Root object does not exists try to create it */
1136 $ldapadd["objectclass"][0]="top";
1137 $ldapadd["objectclass"][1]="organization";
1139 /* Try to fill all collected must attributes */
1140 $base_parts = preg_split("/,/",$cv['base']);
1141 foreach($must_attrs as $attr){
1142 foreach($base_parts as $part){
1143 if(preg_match("/^".$attr."=/",$part) && !isset($ldapadd[$attr])){
1144 $ldapadd[$attr]= preg_replace("/^[^=]*+=/","",$part);
1145 }
1146 }
1147 }
1149 /* Add root object */
1150 $ldap->cd($cv['base']);
1151 $res = $ldap->add($ldapadd);
1153 /* Add root object */
1154 # $ldap->cd($cv['base']);
1155 # $res = $ldap->create_missing_trees($cv['base']);
1157 /* If adding failed, tell the user */
1158 if(!$res){
1159 $this->checks['root']['STATUS'] = FALSE;
1160 $this->checks['root']['STATUS_MSG']= _("Failed");
1161 $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1162 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1163 return($res);;
1164 }
1165 }
1166 }
1168 /* Create & remove of dummy object was successful */
1169 $this->checks['root']['STATUS'] = TRUE;
1170 $this->checks['root']['STATUS_MSG']= _("Ok");
1171 }
1174 /* Return ldif information for a
1175 * given attribute array
1176 */
1177 function array_to_ldif($atts)
1178 {
1179 $ret = "";
1180 unset($atts['count']);
1181 unset($atts['dn']);
1182 foreach($atts as $name => $value){
1183 if(is_numeric($name)) {
1184 continue;
1185 }
1186 if(is_array($value)){
1187 unset($value['count']);
1188 foreach($value as $a_val){
1189 $ret .= $name.": ". $a_val."\n";
1190 }
1191 }else{
1192 $ret .= $name.": ". $value."\n";
1193 }
1194 }
1195 return(preg_replace("/\n$/","",$ret));
1196 }
1197 }
1199 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1200 ?>