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 */
25 class Step_Migrate extends setup_step
26 {
27 var $header_image = "images/setup/migrate.png";
28 var $checks = array();
30 /* Create Acl attributes */
31 var $acl_create_dialog = FALSE;
32 var $acl_create_selected= ""; // Currently selected element, that should receive admin rights
33 var $acl_create_changes = ""; // Contains ldif information about changes
34 var $acl_create_confirmed= FALSE;
36 /* Checks initialised ? */
37 var $checks_initialised = FALSE;
39 /* Root object classes */
40 var $rootOC_migrate_dialog = FALSE;
41 var $rootOC_details = array();
42 var $b_displayCheckbutton = TRUE;
44 function Step_Migrate()
45 {
46 $this->update_strings();
47 }
49 function update_strings()
50 {
51 $this->s_title = _("LDAP inspection");
52 $this->s_title_long = _("LDAP inspection");
53 $this->s_info = _("Analyze your current LDAP for GOsa compatibility");
54 }
56 function initialize_checks()
57 {
58 $this->checks = array();
59 $this->checks['root']['TITLE'] = _("Checking for root object");
60 $this->checks['root']['STATUS'] = FALSE;
61 $this->checks['root']['STATUS_MSG']= "";
62 $this->checks['root']['ERROR_MSG'] = "";
63 $this->checkBase();
65 $this->checks['rootOC']['TITLE'] = _("Inspecting object classes in root object");
66 $this->checks['rootOC']['STATUS'] = FALSE;
67 $this->checks['rootOC']['STATUS_MSG']= "";
68 $this->checks['rootOC']['ERROR_MSG'] = "";
69 $this->checkBaseOC();
71 $this->checks['permissions']['TITLE'] = _("Checking permission for LDAP database");
72 $this->checks['permissions']['STATUS'] = FALSE;
73 $this->checks['permissions']['STATUS_MSG']= "";
74 $this->checks['permissions']['ERROR_MSG'] = "";
75 $this->check_ldap_permissions();
77 $this->migrate_users = array();
78 $this->checks['acls']['TITLE'] = _("Checking for super administrator");
79 $this->checks['acls']['STATUS'] = FALSE;
80 $this->checks['acls']['STATUS_MSG']= "";
81 $this->checks['acls']['ERROR_MSG'] = "";
82 $this->check_administrativeAccount();
83 }
86 /* Check ldap accessibility
87 * Create and remove a dummy object,
88 * to ensure that we have the necessary permissions
89 */
90 function check_ldap_permissions()
91 {
92 /* Establish ldap connection */
93 $cv = $this->parent->captured_values;
94 $ldap_l = new LDAP($cv['admin'],
95 $cv['password'],
96 $cv['connection'],
97 FALSE,
98 $cv['tls']);
100 $ldap = new ldapMultiplexer($ldap_l);
102 /* Create dummy entry
103 */
104 $name = "GOsa_setup_text_entry_".session_id().rand(0,999999);
105 $dn = "ou=".$name.",".$cv['base'];
106 $testEntry= array();
107 $testEntry['objectClass'][]= "top";
108 $testEntry['objectClass'][]= "organizationalUnit";
109 $testEntry['objectClass'][]= "gosaDepartment";
110 $testEntry['description']= "Created by GOsa setup, this object can be removed.";
111 $testEntry['ou'] = $name;
113 /* check if simple ldap cat will be successful
114 */
115 $res = $ldap->cat($cv['base']);
116 if(!$res){
117 $this->checks['permissions']['STATUS'] = FALSE;
118 $this->checks['permissions']['STATUS_MSG']= _("LDAP query failed");
119 $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
120 return(false);
121 }
123 /* Try to create dummy object
124 */
125 $ldap->cd ($dn);
126 $res = $ldap->add($testEntry);
127 $ldap->cat($dn);
128 if(!$ldap->count()){
129 new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
131 $this->checks['permissions']['STATUS'] = FALSE;
132 $this->checks['permissions']['STATUS_MSG']= _("Failed");
133 $this->checks['permissions']['ERROR_MSG'] =
134 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
135 return(false);
136 }
138 /* Try to remove created entry
139 */
140 $res = $ldap->rmDir($dn);
141 $ldap->cat($dn);
142 if($ldap->count()){
143 new log("view","setup/".get_class($this),$dn,array(),$ldap->get_error());
144 $this->checks['permissions']['STATUS'] = FALSE;
145 $this->checks['permissions']['STATUS_MSG']= _("Failed");
146 $this->checks['permissions']['ERROR_MSG'] =
147 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
148 return(false);
149 }
151 /* Create & remove of dummy object was successful */
152 $this->checks['permissions']['STATUS'] = TRUE;
153 $this->checks['permissions']['STATUS_MSG']= _("Ok");
154 $this->checks['permissions']['ERROR_MSG'] = "";
155 return(true);
156 }
161 /* Check Acls if there is at least one object with acls defined
162 */
163 function check_administrativeAccount()
164 {
165 /* Reset settings
166 */
167 $GOsa_26_found = FALSE;
168 $this->migrate_users = array();
169 $this->acl_migrate_dialog = FALSE;
170 $this->migrate_acl_base_entry = "";
172 /* Establish ldap connection */
173 $cv = $this->parent->captured_values;
174 $ldap_l = new LDAP($cv['admin'],
175 $cv['password'],
176 $cv['connection'],
177 FALSE,
178 $cv['tls']);
180 $ldap = new ldapMultiplexer($ldap_l);
181 $ldap->cd($cv['base']);
182 $res = $ldap->cat($cv['base']);
184 if(!$res){
185 $this->checks['acls']['STATUS'] = FALSE;
186 $this->checks['acls']['STATUS_MSG']= _("LDAP query failed");
187 $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
188 }else{
189 $GOsa_26_found = false; // GOsa 2.6 Account found
190 $GOsa_25_found = false; // GOsa 2.5 Account found, allow migration
192 $username = "";
193 $attrs = $ldap->fetch();
195 /* Collect a list of available GOsa users and groups
196 */
197 $users = array();
198 $ldap->search("(&(objectClass=gosaAccount)(objectClass=person)".
199 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson))",array("uid","dn"));
200 while($user_attrs = $ldap->fetch()){
201 $users[$user_attrs['dn']] = $user_attrs['uid'][0];
202 $rusers[$user_attrs['uid'][0]] = $user_attrs['dn'];
203 }
204 $groups = array();
205 $ldap->search("objectClass=posixGroup",array("cn","dn"));
206 while($group_attrs = $ldap->fetch()){
207 $groups[$group_attrs['dn']] = $group_attrs['cn'][0];
208 }
210 /* Check if a valid GOsa 2.6 admin exists
211 -> gosaAclEntry for an existing and accessible user.
212 */
213 $valid_users = "";
214 $valid_groups = "";
215 if(isset($attrs['gosaAclEntry'])){
216 $acls = $attrs['gosaAclEntry'];
217 for($i = 0 ; $i < $acls['count'] ; $i++){
218 $acl = $acls[$i];
219 $tmp = explode(":",$acl);
221 if($tmp[1] == "psub"){
222 $members = explode(",",$tmp[2]);
223 foreach($members as $member){
224 $member = base64_decode($member);
225 if(isset($users[$member])){
226 if(preg_match("/all\/all;cmdrw/i",$tmp[3])){
227 $valid_users .= $users[$member].", ";
228 $GOsa_26_found = TRUE;
229 }
230 }
231 if(isset($groups[$member])){
232 if(preg_match("/all\/all;cmdrw/i",$tmp[3])){
233 $ldap->cat($member);
234 $group_attrs = $ldap->fetch();
235 $val_users = "";
236 if(isset($group_attrs['memberUid'])){
237 for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
238 if(isset($rusers[$group_attrs['memberUid'][$e]])){
239 $val_users .= $group_attrs['memberUid'][$e].", ";
240 }
241 }
242 }
243 if(!empty($val_users)){
244 $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
245 $GOsa_26_found = TRUE;
246 }
247 }
248 }
249 }
250 }elseif($tmp[1] == "role"){
252 /* Check if acl owner is a valid GOsa user account */
253 $ldap->cat(base64_decode($tmp[2]),array("gosaAclTemplate"));
254 $ret = $ldap->fetch();
256 if(isset($ret['gosaAclTemplate'])){
257 $cnt = $ret['gosaAclTemplate']['count'];
258 for($e = 0 ; $e < $cnt ; $e++){
260 $a_str = $ret['gosaAclTemplate'][$e];
261 if(preg_match("/^[0-9]*:psub:/",$a_str) && preg_match("/:all\/all;cmdrw$/",$a_str)){
263 $members = explode(",",$tmp[3]);
264 foreach($members as $member){
265 $member = base64_decode($member);
267 if(isset($users[$member])){
268 $valid_users .= $users[$member].", ";
269 $GOsa_26_found = TRUE;
270 }
271 if(isset($groups[$member])){
272 $ldap->cat($member);
273 $group_attrs = $ldap->fetch();
274 $val_users = "";
275 if(isset($group_attrs['memberUid'])){
276 for($e = 0 ; $e < $group_attrs['memberUid']['count']; $e ++){
277 if(isset($rusers[$group_attrs['memberUid'][$e]])){
278 $val_users .= $group_attrs['memberUid'][$e].", ";
279 }
280 }
281 }
282 if(!empty($val_users)){
283 $valid_groups .= $groups[$member]."(<i>".trim($val_users,", ")."</i>), ";
284 $GOsa_26_found = TRUE;
285 }
286 }
287 }
288 }
289 }
290 }
291 }
292 }
293 }
295 /* Try to find an old GOsa 2.5 administrative account that may be migrated
296 */
297 if(!$GOsa_26_found){
298 $valid_users = "";
299 $valid_groups = "";
300 $ldap->cd($cv['base']);
301 $ldap->search("(&(objectClass=posixGroup)(gosaSubtreeACL=:all)(memberUid=*))",array("memberUid","cn"));
302 while($p_group = $ldap->fetch()){
303 $val_users = "";
304 for($e = 0 ; $e < $p_group['memberUid']['count'] ; $e ++ ){
305 $user = $p_group['memberUid'][$e];
306 if(isset($rusers[$user])){
307 $val_users .= $user.", ";
308 }
309 }
310 if(!empty($val_users)){
311 $valid_groups .= $groups[$p_group['dn']]."(<i>".trim($val_users,", ")."</i>), ";
312 $GOsa_25_found = TRUE;
313 }
314 }
315 }
318 /* Print out results
319 */
320 if($GOsa_25_found){
321 $str = "";
322 if(!empty($valid_groups)){
323 $str.= "<i>".sprintf(_("GOsa 2.5 administrative accounts found: %s"),trim($valid_groups,", "))."</i><br>";
324 }
325 $this->checks['acls']['STATUS'] = FALSE;
326 $this->checks['acls']['STATUS_MSG']= _("Failed");
327 $this->checks['acls']['ERROR_MSG'] = $str;
328 $this->checks['acls']['ERROR_MSG'].= _("There is no valid GOsa 2.6 administrator account inside your LDAP.")." ";
329 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='migrate_acls'>"._("Migrate")."</button>";
330 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='create_acls'>"._("Create")."</button>";
331 }elseif($GOsa_26_found){
332 $str = "";
333 if(!empty($valid_users)){
334 $str.= "<b>"._("Users")."</b>: ".trim($valid_users,", ")."<br>";
335 }
336 if(!empty($valid_groups)){
337 $str.= "<b>"._("Groups")."</b>: ".trim($valid_groups,", ")."<br>";
338 }
339 $this->checks['acls']['STATUS'] = TRUE;
340 $this->checks['acls']['STATUS_MSG']= _("Ok");
341 $this->checks['acls']['ERROR_MSG'] = $str;
342 }else{
343 $this->checks['acls']['STATUS'] = FALSE;
344 $this->checks['acls']['STATUS_MSG']= _("Failed");
345 $this->checks['acls']['ERROR_MSG']= _("There is no GOsa administrator account inside your LDAP.")." ";
346 $this->checks['acls']['ERROR_MSG'].= "<button type='submit' name='create_acls'>"._("Create")."</button>";
347 }
348 }
350 // Reload base OC
351 $this->checkBaseOC();
352 return($GOsa_26_found);
353 }
357 function create_admin($only_ldif = FALSE)
358 {
359 /* Reset '' */
360 $this->acl_create_changes="";
362 /* Object that should receive admin acls */
363 $dn = $this->acl_create_selected;
365 /* Get collected configuration settings */
366 $cv = $this->parent->captured_values;
368 /* On first call check for rid/sid base */
369 $ldap_l = new LDAP($cv['admin'],
370 $cv['password'],
371 $cv['connection'],
372 FALSE,
373 $cv['tls']);
375 $ldap = new ldapMultiplexer($ldap_l);
377 /* Get current base attributes */
378 $ldap->cd($cv['base']);
379 $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
380 $attrs = $ldap->fetch();
382 /* Add acls for the selcted user to the base */
383 $attrs_new = array();
384 $attrs_new['objectClass'] = array("gosaACL");
386 for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
387 if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
388 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
389 }
390 }
392 $acl = "0:psub:".base64_encode($dn).":all/all;cmdrw";
393 $attrs_new['gosaAclEntry'][] = $acl;
394 if(isset($attrs['gosaAclEntry'])){
395 for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
397 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
398 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
400 $data = ($prio+1).$rest;
401 $attrs_new['gosaAclEntry'][] = $data;
402 }
403 }
405 if($only_ldif){
406 $this->acl_create_changes ="\n".($ldap->fix($cv['base']))."\n";
407 $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
408 $this->acl_create_changes.="\n".($ldap->fix($cv['base']))."\n";
409 $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
410 }else{
412 $ldap->cd($cv['base']);
413 if(!$ldap->modify($attrs_new)){
414 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);
415 return(FALSE);
416 }else{
417 return(TRUE);
418 }
419 }
420 }
423 function create_admin_user()
424 {
425 $pw1 = $pw2 = "";
426 $uid = "";
428 /* On first call check for rid/sid base */
429 $cv = $this->parent->captured_values;
430 $ldap_l = new LDAP($cv['admin'],
431 $cv['password'],
432 $cv['connection'],
433 FALSE,
434 $cv['tls']);
436 $ldap = new ldapMultiplexer($ldap_l);
438 if(isset($_POST['new_user_uid'])){
439 $uid = $_POST['new_user_uid'];
440 }
441 if(isset($_POST['new_user_password'])){
442 $pw1 = $_POST['new_user_password'];
443 }
444 if(isset($_POST['new_user_password2'])){
445 $pw2 = $_POST['new_user_password2'];
446 }
449 $ldap->cd($cv['base']);
450 $ldap->search("(uid=".$uid.")");
451 if($ldap->count()){
452 msg_dialog::display(_("Input error"),msgPool::duplicated(_("Uid")), ERROR_DIALOG);
453 return false;
454 }
456 if(empty($pw1) || empty($pw2) | ($pw1 != $pw2)){
457 msg_dialog::display(_("Password error"), _("Provided passwords do not match!"), ERROR_DIALOG);
458 return false;
459 }
461 if(!tests::is_uid($uid) || empty($uid)){
462 msg_dialog::display(_("Input error"), _("Specify a valid user ID!"), ERROR_DIALOG);
463 return false;
464 }
467 /* Get current base attributes */
468 $ldap->cd($cv['base']);
470 $people_ou = "ou=people,"; // Thats the property default.
471 $dn = "cn=System Administrator-".$uid.",".$people_ou.$cv['base'];
473 $hash = $hash = passwordMethod::make_hash($pw2, 'crypt/md5');
475 $new_user=array();
476 $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
477 $new_user['givenName'] = "System";
478 $new_user['sn'] = "Administrator";
479 $new_user['cn'] = "System Administrator-".$uid;
480 $new_user['uid'] = $uid;
481 $new_user['userPassword'] = $hash;
483 $ldap->cd($cv['base']);
485 $ldap->cat($dn,array("dn"));
486 if($ldap->count()){
487 msg_dialog::display(_("Error"), sprintf(_("Adding an administrative user failed: object '%s' already exists!"), LDAP::fix($dn)), ERROR_DIALOG);
488 return(FALSE);
489 }
491 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
492 $ldap->cd($dn);
493 $res = $ldap->add($new_user);
494 $this->acl_create_selected = $dn;
495 $this->create_admin();
497 if(!$res){
498 msg_dialog::display(_("LDAP error"), $ldap->get_error(), ERROR_DIALOG);
499 return(FALSE);
500 }
502 $this->acl_create_dialog=FALSE;
503 $this->check_administrativeAccount();
504 return(TRUE);
505 }
508 function execute()
509 {
510 /* Initialise checks if this is the first call */
511 if(!$this->checks_initialised || isset($_POST['test'])){
512 $this->initialize_checks();
513 $this->checks_initialised = TRUE;
514 }
517 /*************
518 * Root object check
519 *************/
521 if(isset($_POST['retry_root_create'])){
523 $state = $this->checks['root']['STATUS'];
524 $this->checkBase(FALSE);
525 if($state != $this->checks['root']['STATUS']){
526 $this->initialize_checks();
527 }
528 }
530 /*************
531 * Root object class check
532 *************/
534 if(isset($_POST['root_add_objectclasses'])){
535 $this->rootOC_migrate_dialog = TRUE;
536 $this->dialog = TRUE;
537 }
538 if(isset($_POST['rootOC_dialog_cancel'])){
539 $this->rootOC_migrate_dialog = FALSE;
540 $this->dialog = FALSE;
541 }
542 if(isset($_POST['rootOC_migrate_start'])){
543 if($this->checkBaseOC(FALSE)){
544 $this->checkBaseOC(); // Update overview info
545 $this->dialog = FALSE;
546 $this->rootOC_migrate_dialog = FALSE;
547 }
548 }
549 if($this->rootOC_migrate_dialog){
550 $smarty = get_smarty();
551 $smarty->assign("details",$this->rootOC_details);
552 $smarty->assign("method","rootOC_migrate_dialog");
553 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
554 }
556 /*************
557 * Administrative Account -- Migrate/Create
558 *************/
560 if(isset($_POST['retry_acls'])){
561 $this->check_administrativeAccount();
562 }
564 /* Dialog handling */
565 if(isset($_POST['create_acls'])){
566 $this->acl_create_dialog = TRUE;
567 $this->dialog = TRUE;
568 }
570 if(isset($_POST['migrate_acls'])){
571 $this->acl_migrate_dialog = TRUE;
572 $this->dialog = TRUE;
573 }
575 if(isset($_POST['create_acls_cancel']) || isset($_POST['migrate_acls_cancel'])){
576 $this->acl_create_dialog = FALSE;
577 $this->acl_migrate_dialog = FALSE;
578 $this->dialog = FALSE;
579 $this->show_details = FALSE;
580 }
582 /* Account creation */
583 if(isset($_POST['create_acls_create'])){
584 $this->create_admin(TRUE);
585 }
587 if(isset($_POST['create_admin_user'])){
588 if($this->create_admin_user()){
589 $this->dialog = FALSE;
590 $this->show_details = FALSE;
591 }
592 }
594 /* Add admin acls for the selected users to the ldap base.
595 */
596 if($this->acl_migrate_dialog && isset($_POST['migrate_admin_user'])){
598 /* Update ldap and reload check infos
599 */
600 $this->migrate_selected_admin_users();
601 $this->dialog = FALSE;
602 $this->acl_migrate_dialog = FALSE;
604 }elseif($this->acl_migrate_dialog){
606 /* Display admin migration dialog.
607 */
608 $this->migrate_users();
609 $smarty = get_smarty();
611 /* Do we have to display the changes
612 */
613 $details = isset($_POST['details']) && $_POST['details'];
614 if(isset($_POST['migrate_acls_show_changes'])){
615 $details = TRUE;
616 }elseif(isset($_POST['migrate_acls_hide_changes'])){
617 $details = FALSE;
618 }
620 $smarty->assign("migrate_acl_base_entry", $this->migrate_acl_base_entry);
621 $smarty->assign("details", $details);
622 $smarty->assign("method","migrate_acls");
623 $smarty->assign("migrateable_users",$this->migrate_users);
624 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
625 }
627 if($this->acl_create_dialog){
628 $smarty = get_smarty();
629 $uid = "admin";
630 if(isset($_POST['new_user_uid'])){
631 $uid = $_POST['new_user_uid'];
632 }
633 $smarty->assign("new_user_uid",$uid);
634 $smarty->assign("new_user_password",@$_POST['new_user_password']);
635 $smarty->assign("new_user_password2",@$_POST['new_user_password2']);
636 $smarty->assign("method","create_acls");
637 $smarty->assign("acl_create_selected",$this->acl_create_selected);
638 $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
639 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
640 }
643 $smarty = get_smarty();
644 $smarty->assign("checks",$this->checks);
645 $smarty->assign("method","default");
646 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
647 }
650 function save_object()
651 {
652 $this->is_completed= TRUE;
655 /* Get "create acl" dialog posts */
656 if($this->acl_create_dialog){
658 if(isset($_POST['create_acls_create_abort'])){
659 $this->acl_create_selected = "";
660 }
661 }
663 }
666 /* Check if the root object exists.
667 * If the parameter just_check is true, then just check if the
668 * root object is missing and update the info messages.
669 * If the Parameter is false, try to create a new root object.
670 */
671 function checkBase($just_check = TRUE)
672 {
673 /* Establish ldap connection */
674 $cv = $this->parent->captured_values;
675 $ldap_l = new LDAP($cv['admin'],
676 $cv['password'],
677 $cv['connection'],
678 FALSE,
679 $cv['tls']);
681 $ldap = new ldapMultiplexer($ldap_l);
683 /* Check if root object exists */
684 $ldap->cd($cv['base']);
685 $ldap->set_size_limit(1);
686 $res = $ldap->search("(objectClass=*)");
687 $ldap->set_size_limit(0);
688 $err = ldap_errno($ldap->cid);
690 if( !$res ||
691 $err == 0x20 || # LDAP_NO_SUCH_OBJECT
692 $err == 0x40) { # LDAP_NAMING_VIOLATION
694 /* Root object doesn't exists
695 */
696 if($just_check){
697 $this->checks['root']['STATUS'] = FALSE;
698 $this->checks['root']['STATUS_MSG']= _("Failed");
699 $this->checks['root']['ERROR_MSG'] = _("The LDAP root object is missing. It is required to use your LDAP service.").' ';
700 $this->checks['root']['ERROR_MSG'].= "<button type='submit' name='retry_root_create'>"._("Try to create root object")."</button>";
701 return(FALSE);
702 }else{
704 /* Add root object */
705 $ldap->cd($cv['base']);
706 $res = $ldap->create_missing_trees($cv['base']);
708 /* If adding failed, tell the user */
709 if(!$res){
710 $this->checks['root']['STATUS'] = FALSE;
711 $this->checks['root']['STATUS_MSG']= _("Failed");
712 $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
713 $this->checks['root']['ERROR_MSG'].= " <button type='submit' name='retry_root_create'>"._("Try to create root object")."</button>";
714 return($res);;
715 }
716 }
717 }
719 /* Create & remove of dummy object was successful */
720 $this->checks['root']['STATUS'] = TRUE;
721 $this->checks['root']['STATUS_MSG']= _("Ok");
722 }
725 /* Check if the root object includes the required object classes, e.g. gosaDepartment is required for ACLs.
726 * If the parameter just_check is true, then just check for the OCs.
727 * If the Parameter is false, try to add the required object classes.
728 */
729 function checkBaseOC($just_check = TRUE)
730 {
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 /* Check if root object exists */
742 $ldap->cd($cv['base']);
743 $ldap->cat($cv['base']);
744 if(!$ldap->count()){
745 $this->checks['rootOC']['STATUS'] = FALSE;
746 $this->checks['rootOC']['STATUS_MSG']= _("LDAP query failed");
747 $this->checks['rootOC']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
748 return;
749 }
751 $attrs = $ldap->fetch();
753 /* Root object doesn't exists
754 */
755 if(!in_array("gosaDepartment",$attrs['objectClass'])){
756 if($just_check){
758 $this->rootOC_details = array();
759 $mods = array();
761 /* Get list of possible container objects, to be able to detect naming
762 * attributes and missing attribute types.
763 */
764 if(!class_available("departmentManagement")){
765 $this->checks['rootOC']['STATUS'] = FALSE;
766 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
767 $this->checks['rootOC']['ERROR_MSG'] = sprintf(_("Missing GOsa object class '%s'!"),"departmentManagement").
768 " "._("Please check your installation.");
769 return;
770 }
772 /* Try to detect base class type, e.g. is it a dcObject.
773 */
774 $dep_types = departmentManagement::get_support_departments();
775 $dep_type ="";
776 foreach($dep_types as $dep_name => $dep_class){
777 if(in_array($dep_class['CLASS'], $attrs['objectClass'])){
778 $dep_type = $dep_name;
779 break;
780 }
781 }
783 /* If no known base class was detect, abort with message
784 */
785 if(empty($dep_type)){
786 $this->checks['rootOC']['STATUS'] = FALSE;
787 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
788 $this->checks['rootOC']['ERROR_MSG'] =
789 sprintf(_("Cannot handle the structural object type of your root object. Please try to add the object class '%s' manually."),"gosaDepartment");
790 return;
791 }
793 /* Create 'current' and 'target' object properties, to be able to display
794 * a set of modifications required to create a valid GOsa department.
795 */
796 $str = "dn: ".$cv['base']."\n";
797 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
798 $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
799 }
800 $this->rootOC_details['current'] = $str;
802 /* Create target infos
803 */
804 $str = "dn: ".$cv['base']."\n";
805 for($i = 0 ; $i<$attrs['objectClass']['count'];$i++){
806 $str .= "objectClass: ".$attrs['objectClass'][$i]."\n";
807 $mods['objectClass'][] = $attrs['objectClass'][$i];
808 }
809 $mods['objectClass'][] = "gosaDepartment";
810 $str .= "<b>objectClass: gosaDepartment</b>\n";
812 /* Append attribute 'ou', it is required by gosaDepartment
813 */
814 if(!isset($attrs['ou'])){
815 $val = "GOsa";
816 if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
817 $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
818 }
819 $str .= "<b>ou: ".$val."</b>\n";
820 $mods['ou'] =$val;
821 }
823 /*Append description, it is required by gosaDepartment too.
824 */
825 if(!isset($attrs['description'])){
826 $val = "GOsa";
827 if(isset($attrs[$dep_types[$dep_type]['ATTR']][0])){
828 $val = $attrs[$dep_types[$dep_type]['ATTR']][0];
829 }
830 $str .= "<b>description: ".$val."</b>\n";
831 $mods['description'] = $val;
832 }
833 $this->rootOC_details['target'] = $str;
834 $this->rootOC_details['mods'] = $mods;
836 /* Add button that allows to open the migration details
837 */
838 $this->checks['rootOC']['STATUS'] = FALSE;
839 $this->checks['rootOC']['STATUS_MSG']= _("Failed");
840 $this->checks['rootOC']['ERROR_MSG'] = " <button type='submit'
841 name='root_add_objectclasses'>"._("Migrate")."</button>";
843 return(FALSE);
844 }else{
846 /* Add root object */
847 $ldap->cd($cv['base']);
848 if(isset($this->rootOC_details['mods'])){
849 $res = $ldap->modify($this->rootOC_details['mods']);
850 if(!$res){
851 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $cv['base'], LDAP_MOD, get_class()));
852 }
853 $this->checkBaseOC();
854 $this->check_administrativeAccount();
855 return($res);
856 }else{
857 trigger_error("No modifications to make... ");
858 }
859 }
860 return(TRUE);
861 }
863 /* Create & remove of dummy object was successful */
864 $this->checks['rootOC']['STATUS'] = TRUE;
865 $this->checks['rootOC']['STATUS_MSG']= _("Ok");
866 $this->checks['rootOC']['ERROR_MSG'] = "";
867 }
870 /* Return ldif information for a
871 * given attribute array
872 */
873 function array_to_ldif($atts)
874 {
875 $ret = "";
876 unset($atts['count']);
877 unset($atts['dn']);
878 foreach($atts as $name => $value){
879 if(is_numeric($name)) {
880 continue;
881 }
882 if(is_array($value)){
883 unset($value['count']);
884 foreach($value as $a_val){
885 $ret .= $name.": ". $a_val."\n";
886 }
887 }else{
888 $ret .= $name.": ". $value."\n";
889 }
890 }
891 return(preg_replace("/\n$/","",$ret));
892 }
895 }
896 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
897 ?>