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