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 }
175 function check_uidNumber()
176 {
177 $cv = $this->parent->captured_values;
178 $ldap = new LDAP($cv['admin'],
179 $cv['password'],
180 $cv['connection'],
181 FALSE,
182 $cv['tls']);
184 $ldap->cd($cv['base']);
185 $res = $ldap->search("uidNumber=*",array("dn","uidNumber"));
186 if(!$res){
187 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
188 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
189 $this->checks['uidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
190 return(false);
191 }
193 $this->check_uidNumbers= array();
194 $tmp = array();
195 while($attrs = $ldap->fetch()){
196 $tmp[$attrs['uidNumber'][0]][] = $attrs;
197 }
199 foreach($tmp as $id => $entries){
200 if(count($entries) > 1){
201 foreach($entries as $entry){
202 $this->check_uidNumbers[base64_encode($entry['dn'])] = $entry;
203 }
204 }
205 }
207 if($this->check_uidNumbers){
208 $this->checks['uidNumber_usage']['STATUS'] = FALSE;
209 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Failed");
210 $this->checks['uidNumber_usage']['ERROR_MSG'] =
211 sprintf(_("Found %s duplicated uidNumber values."),count($this->check_uidNumbers));
212 return(false);
213 }else{
214 $this->checks['uidNumber_usage']['STATUS'] = TRUE;
215 $this->checks['uidNumber_usage']['STATUS_MSG']= _("Ok");
216 $this->checks['uidNumber_usage']['ERROR_MSG'] = "";
217 return(TRUE);
218 }
219 }
221 function check_gidNumber()
222 {
223 $cv = $this->parent->captured_values;
224 $ldap = new LDAP($cv['admin'],
225 $cv['password'],
226 $cv['connection'],
227 FALSE,
228 $cv['tls']);
230 $ldap->cd($cv['base']);
231 $res = $ldap->search("gidNumber=*",array("dn","gidNumber"));
232 if(!$res){
233 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
234 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ldap query failed.");
235 $this->checks['gidNumber_usage']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
236 return(false);
237 }
239 $this->check_gidNumbers= array();
240 $tmp = array();
241 while($attrs = $ldap->fetch()){
242 $tmp[$attrs['gidNumber'][0]][] = $attrs;
243 }
245 foreach($tmp as $id => $entries){
246 if(count($entries) > 1){
247 foreach($entries as $entry){
248 $this->check_gidNumbers[base64_encode($entry['dn'])] = $entry;
249 }
250 }
251 }
253 if($this->check_gidNumbers){
254 $this->checks['gidNumber_usage']['STATUS'] = FALSE;
255 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Failed");
256 $this->checks['gidNumber_usage']['ERROR_MSG'] =
257 sprintf(_("Found %s duplicated gidNumber values."),count($this->check_gidNumbers));
258 return(false);
259 }else{
260 $this->checks['gidNumber_usage']['STATUS'] = TRUE;
261 $this->checks['gidNumber_usage']['STATUS_MSG']= _("Ok");
262 $this->checks['gidNumber_usage']['ERROR_MSG'] = "";
263 return(TRUE);
264 }
265 }
268 /* Search for winstations outside the winstation ou */
269 function search_outside_winstations()
270 {
271 $cv = $this->parent->captured_values;
272 $ldap = new LDAP($cv['admin'],
273 $cv['password'],
274 $cv['connection'],
275 FALSE,
276 $cv['tls']);
278 /* Get winstation ou */
279 if($cv['generic_settings']['wws_ou_active']) {
280 $winstation_ou = $cv['generic_settings']['ws_ou'];
281 }else{
282 $winstation_ou = "ou=winstations";
283 }
285 $ldap->cd($cv['base']);
286 $res = $ldap->search("(&(objectClass=posixGroup)(sambaGroupType=2)(sambaSID=*))",array("dn","sambaSID"));
287 if(!$res){
288 $this->checks['outside_winstations']['STATUS'] = FALSE;
289 $this->checks['outside_winstations']['STATUS_MSG']= _("Ldap query failed.");
290 $this->checks['outside_winstations']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
291 return(false);
292 }
294 $this->outside_winstations = array();
295 while($attrs = $ldap->fetch()){
296 if(preg_match("/-516$/","",$attrs['sambaSID'][0]) && !preg_match("/^[^,]+,".normalizePreg($winstation_ou)."/",$attrs['dn'])){
297 $this->outside_winstations[base64_encode($attrs['dn'])] = $attrs;
298 }
299 }
301 if(count($this->outside_winstations)){
302 $this->checks['outside_winstations']['STATUS'] = FALSE;
303 $this->checks['outside_winstations']['STATUS_MSG']= _("Failed");
304 $this->checks['outside_winstations']['ERROR_MSG'] =
305 sprintf(_("Found %s winstations outside the predefined winstation department ou '%s'."),count($this->outside_winstations),$winstation_ou);
306 return(false);
307 }else{
308 $this->checks['outside_winstations']['STATUS'] = TRUE;
309 $this->checks['outside_winstations']['STATUS_MSG']= _("Ok");
310 $this->checks['outside_winstations']['ERROR_MSG'] = "";
311 return(TRUE);
312 }
313 }
316 /* Search for groups outside the group ou */
317 function search_outside_groups()
318 {
319 $cv = $this->parent->captured_values;
320 $ldap = new LDAP($cv['admin'],
321 $cv['password'],
322 $cv['connection'],
323 FALSE,
324 $cv['tls']);
326 $group_ou = $cv['groupou'];
327 $ldap->cd($cv['base']);
328 $res = $ldap->search("(objectClass=posixGroup)",array("dn"));
329 if(!$res){
330 $this->checks['outside_groups']['STATUS'] = FALSE;
331 $this->checks['outside_groups']['STATUS_MSG']= _("Ldap query failed.");
332 $this->checks['outside_groups']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
333 return(false);
334 }
337 $this->outside_groups = array();
338 while($attrs = $ldap->fetch()){
339 if(!preg_match("/^[^,]+,".normalizePreg($group_ou)."/",$attrs['dn'])){
340 $this->outside_groups[base64_encode($attrs['dn'])] = $attrs;
341 }
342 }
344 if(count($this->outside_groups)){
345 $this->checks['outside_groups']['STATUS'] = FALSE;
346 $this->checks['outside_groups']['STATUS_MSG']= _("Failed");
347 $this->checks['outside_groups']['ERROR_MSG'] =
348 sprintf(_("Found %s groups outside the selected group ou '%s'."),count($this->outside_groups),$group_ou);
349 return(false);
350 }else{
351 $this->checks['outside_groups']['STATUS'] = TRUE;
352 $this->checks['outside_groups']['STATUS_MSG']= _("Ok");
353 $this->checks['outside_groups']['ERROR_MSG'] = "";
354 return(TRUE);
355 }
356 }
358 /* Search for users outside the people ou */
359 function search_outside_users()
360 {
361 $cv = $this->parent->captured_values;
362 $ldap = new LDAP($cv['admin'],
363 $cv['password'],
364 $cv['connection'],
365 FALSE,
366 $cv['tls']);
367 $people_ou = $cv['peopleou'];
368 $ldap->cd($cv['base']);
369 $res = $ldap->search("(objectClass=gosaAccount)",array("dn"));
370 if(!$res){
371 $this->checks['outside_users']['STATUS'] = FALSE;
372 $this->checks['outside_users']['STATUS_MSG']= _("Ldap query failed.");
373 $this->checks['outside_users']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
374 return(false);
375 }
378 $this->outside_users = array();
379 while($attrs = $ldap->fetch()){
380 if(!preg_match("/^[^,]+,".normalizePreg($people_ou)."/",$attrs['dn'])){
381 $attrs['selected'] = FALSE;
382 $attrs['ldif'] = "";
383 $this->outside_users[base64_encode($attrs['dn'])] = $attrs;
384 }
385 }
387 if(count($this->outside_users)){
388 $this->checks['outside_users']['STATUS'] = FALSE;
389 $this->checks['outside_users']['STATUS_MSG']= _("Failed");
390 $this->checks['outside_users']['ERROR_MSG'] =
391 sprintf(_("Found %s users outside the selected user ou '%s'."),count($this->outside_users),$people_ou);
392 $this->checks['outside_users']['ERROR_MSG'].= "<input type='submit' name='outside_users_dialog' value='"._("Migrate")."'>";
393 return(false);
394 }else{
395 $this->checks['outside_users']['STATUS'] = TRUE;
396 $this->checks['outside_users']['STATUS_MSG']= _("Ok");
397 $this->checks['outside_users']['ERROR_MSG'] = "";
398 return(TRUE);
399 }
400 }
403 /* Check ldap accessibility
404 * Create and remove a dummy object,
405 * to ensure that we have the necessary permissions
406 */
407 function check_ldap_permissions()
408 {
409 $cv = $this->parent->captured_values;
410 $ldap = new LDAP($cv['admin'],
411 $cv['password'],
412 $cv['connection'],
413 FALSE,
414 $cv['tls']);
416 /* Create dummy entry
417 */
418 $name = "GOsa_setup_text_entry_".session_id().rand(0,999999);
419 $dn = "ou=".$name.",".$cv['base'];
420 $testEntry= array();
421 $testEntry['objectClass'][]= "top";
422 $testEntry['objectClass'][]= "organizationalUnit";
423 $testEntry['objectClass'][]= "gosaDepartment";
424 $testEntry['description']= "Created by GOsa setup, this object can be removed.";
425 $testEntry['ou'] = $name;
427 /* check if simple ldap cat will be successful
428 */
429 $res = $ldap->cat($cv['base']);
430 if(!$res){
431 $this->checks['permissions']['STATUS'] = FALSE;
432 $this->checks['permissions']['STATUS_MSG']= _("Ldap query failed.");
433 $this->checks['permissions']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
434 return(false);
435 }
437 /* Try to create dummy object
438 */
439 $ldap->cd ($dn);
440 $ldap->create_missing_trees($dn);
441 $res = $ldap->add($testEntry);
442 if(!$res){
443 gosa_log($ldap->get_error());
444 $this->checks['permissions']['STATUS'] = FALSE;
445 $this->checks['permissions']['STATUS_MSG']= _("Failed");
446 $this->checks['permissions']['ERROR_MSG'] =
447 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
448 return(false);
449 }
451 /* Try to remove created entry
452 */
453 $res = $ldap->rmDir($dn);
454 if(!$res){
455 gosa_log($ldap->get_error());
456 $this->checks['permissions']['STATUS'] = FALSE;
457 $this->checks['permissions']['STATUS_MSG']= _("Failed");
458 $this->checks['permissions']['ERROR_MSG'] =
459 sprintf(_("The specified user '%s' does not have full access to your ldap database."),$cv['admin']);
460 return(false);
461 }
463 /* Create & remove of dummy object was successful */
464 $this->checks['permissions']['STATUS'] = TRUE;
465 $this->checks['permissions']['STATUS_MSG']= _("Ok");
466 $this->checks['permissions']['ERROR_MSG'] = "";
467 return(true);
468 }
471 /* Check if there are users which will
472 * be invisible for GOsa
473 */
474 function check_gosaAccounts()
475 {
476 /* Remember old list of ivisible users, to be able to set
477 * the 'html checked' status for the checkboxes again
478 */
479 $cnt_ok = 0;
480 $old = $this->users_to_migrate;
481 $this->users_to_migrate = array();
483 /* Get collected configuration settings */
484 $cv = $this->parent->captured_values;
486 /* Establish ldap connection */
487 $ldap = new LDAP($cv['admin'],
488 $cv['password'],
489 $cv['connection'],
490 FALSE,
491 $cv['tls']);
493 /* Get all invisible users
494 */
495 $ldap->cd($cv['base']);
496 $res =$ldap->search("(&(|(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))(!(objectClass=gosaAccount)))",array("sn","givenName","cn","uid"));
497 while($attrs = $ldap->fetch()){
498 if(!preg_match("/,dc=addressbook,/",$attrs['dn'])){
499 $attrs['checked'] = FALSE;
500 $attrs['before'] = "";
501 $attrs['after'] = "";
503 /* Set objects to selected, that were selected before reload */
504 if(isset($old[base64_encode($attrs['dn'])])){
505 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
506 }
507 $this->users_to_migrate[base64_encode($attrs['dn'])] = $attrs;
508 }
509 }
511 /* No invisible */
512 if(!$res){
513 $this->checks['users_visible']['STATUS'] = FALSE;
514 $this->checks['users_visible']['STATUS_MSG']= _("Ldap query failed.");
515 $this->checks['users_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
516 }elseif(count($this->users_to_migrate) == 0){
517 $this->checks['users_visible']['STATUS'] = TRUE;
518 $this->checks['users_visible']['STATUS_MSG']= _("Ok");
519 $this->checks['users_visible']['ERROR_MSG'] = "";
520 }else{
521 $this->checks['users_visible']['STATUS'] = FALSE;
522 $this->checks['users_visible']['STATUS_MSG']= "";
523 $this->checks['users_visible']['ERROR_MSG'] = sprintf(_("Found %s users that will not be visible in GOsa."),
524 count($this->users_to_migrate));
525 $this->checks['users_visible']['ERROR_MSG'] .= "<input type='submit' name='users_visible_migrate' value='"._("Migrate")."'>";
526 }
527 }
530 /* Start user account migration
531 */
532 function migrate_gosaAccounts($only_ldif = FALSE)
533 {
534 /* Get collected configuration settings */
535 $cv = $this->parent->captured_values;
537 /* Establish ldap connection */
538 $ldap = new LDAP($cv['admin'],
539 $cv['password'],
540 $cv['connection'],
541 FALSE,
542 $cv['tls']);
544 /* Add gosaAccount objectClass to the selected users
545 */
546 foreach($this->users_to_migrate as $key => $dep){
547 if($dep['checked']){
549 /* Get old objectClasses */
550 $ldap->cat($dep['dn'],array("objectClass"));
551 $attrs = $ldap->fetch();
553 /* Create new objectClass array */
554 $new_attrs = array();
555 $new_attrs['objectClass']= array("gosaAccount","inetOrgPerson","organizationalPerson");
556 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
557 if(!in_array_ics($attrs['objectClass'][$i], $new_attrs['objectClass'])){
558 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
559 }
560 }
562 /* Set info attributes for current object,
563 * or write changes to the ldap database
564 */
565 if($only_ldif){
566 $this->users_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
567 $this->users_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
568 }else{
569 $ldap->cd($attrs['dn']);
570 if(!$ldap->modify($new_attrs)){
571 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
572 return(false);
573 }
574 }
575 }
576 }
577 return(TRUE);
578 }
581 /* Check if there are invisible organizational Units
582 */
583 function check_organizationalUnits()
584 {
585 $cnt_ok = 0;
586 $old = $this->deps_to_migrate;
587 $this->deps_to_migrate = array();
589 /* Get collected configuration settings */
590 $cv = $this->parent->captured_values;
592 /* Establish ldap connection */
593 $ldap = new LDAP($cv['admin'],
594 $cv['password'],
595 $cv['connection'],
596 FALSE,
597 $cv['tls']);
599 /* Skip GOsa internal departments */
600 $skip_dns = array("/^ou=people,/","/^ou=groups,/","/(,|)ou=configs,/","/(,|)ou=systems,/",
601 "/^ou=apps,/","/^ou=mime,/","/^ou=aclroles,/","/^ou=incoming,/",
602 "/ou=snapshots,/","/(,|)dc=addressbook,/","/^(,|)ou=machineaccounts,/",
603 "/(,|)ou=winstations,/");
606 /* Get all invisible departments */
607 $ldap->cd($cv['base']);
608 $res = $ldap->search("(&(objectClass=organizationalUnit)(!(objectClass=gosaDepartment)))",array("ou","description","dn"));
609 while($attrs = $ldap->fetch()){
610 $attrs['checked'] = FALSE;
611 $attrs['before'] = "";
612 $attrs['after'] = "";
614 /* Set objects to selected, that were selected before reload */
615 if(isset($old[base64_encode($attrs['dn'])])){
616 $attrs['checked'] = $old[base64_encode($attrs['dn'])]['checked'];
617 }
618 $this->deps_to_migrate[base64_encode($attrs['dn'])] = $attrs;
619 }
621 /* Filter returned list of departments and ensure that
622 * GOsa internal departments will not be listed
623 */
624 foreach($this->deps_to_migrate as $key => $attrs){
625 $dn = $attrs['dn'];
626 $skip = false;
627 foreach($skip_dns as $skip_dn){
628 if(preg_match($skip_dn,$dn)){
629 $skip = true;
630 }
631 }
632 if($skip){
633 unset($this->deps_to_migrate[$key]);
634 }
635 }
637 /* If we have no invisible departments found
638 * tell the user that everything is ok
639 */
640 if(!$res){
641 $this->checks['deps_visible']['STATUS'] = FALSE;
642 $this->checks['deps_visible']['STATUS_MSG']= _("Ldap query failed.");
643 $this->checks['deps_visible']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
644 }elseif(count($this->deps_to_migrate) == 0 ){
645 $this->checks['deps_visible']['STATUS'] = TRUE;
646 $this->checks['deps_visible']['STATUS_MSG']= _("Ok");
647 $this->checks['deps_visible']['ERROR_MSG'] = "";
648 }else{
649 $this->checks['deps_visible']['STATUS'] = FALSE;
650 $this->checks['deps_visible']['STATUS_MSG']= "";//sprintf(_("%s entries found"),count($this->deps_to_migrate));
651 $this->checks['deps_visible']['ERROR_MSG'] = sprintf(_("Found %s departments that will not be visible in GOsa."),count($this->deps_to_migrate));
652 $this->checks['deps_visible']['ERROR_MSG'] .= "<input type='submit' name='deps_visible_migrate' value='"._("Migrate")."'>";
653 }
654 }
658 /* Start deparmtment migration */
659 function migrate_organizationalUnits($only_ldif = FALSE)
660 {
661 /* Get collected configuration settings */
662 $cv = $this->parent->captured_values;
664 /* Establish ldap connection */
665 $ldap = new LDAP($cv['admin'],
666 $cv['password'],
667 $cv['connection'],
668 FALSE,
669 $cv['tls']);
671 /* Add gosaDepartment objectClass to each selected entry
672 */
673 foreach($this->deps_to_migrate as $key => $dep){
674 if($dep['checked']){
676 /* Get current objectClasses */
677 $ldap->cat($dep['dn'],array("objectClass","description"));
678 $attrs = $ldap->fetch();
680 /* Create new objectClass attribute including gosaDepartment*/
681 $new_attrs = array();
682 for($i = 0 ; $i < $attrs['objectClass']['count']; $i ++ ){
683 $new_attrs['objectClass'][] = $attrs['objectClass'][$i];
684 }
685 $new_attrs['objectClass'][] = "gosaDepartment";
687 /* Append description it is missing */
688 if(!isset($attrs['description'])){
689 $new_attrs['description'][] = "GOsa department";
690 }
692 /* Depending on the parameter >only_diff< we save the changes as ldif
693 * or we write our changes directly to the ldap database
694 */
695 if($only_ldif){
696 $this->deps_to_migrate[$key]['before'] = $this->array_to_ldif($attrs);
697 $this->deps_to_migrate[$key]['after'] = $this->array_to_ldif($new_attrs);
698 }else{
699 $ldap->cd($attrs['dn']);
700 if(!$ldap->modify($new_attrs)){
701 print_red(sprintf(_("Failed to migrate the department '%s' into GOsa, error message is as follows '%s'."),$attrs['dn'],$ldap->get_error()));
702 return(false);
703 }
704 }
705 }
706 }
707 return(TRUE);
708 }
711 /* Check Acls if there is at least one object with acls defined
712 */
713 function check_administrativeAccount()
714 {
715 /* Establish ldap connection */
716 $cv = $this->parent->captured_values;
717 $ldap = new LDAP($cv['admin'],
718 $cv['password'],
719 $cv['connection'],
720 FALSE,
721 $cv['tls']);
723 /* Search for gosaAcls */
724 $ldap->cd($cv['base']);
725 $res = $ldap->search("(&(objectClass=gosaAccount)(|(objectClass=posixAccount)".
726 "(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))");
727 if(!$res){
728 $this->checks['acls']['STATUS'] = FALSE;
729 $this->checks['acls']['STATUS_MSG']= _("Ldap query failed.");
730 $this->checks['acls']['ERROR_MSG'] = _("Possibly the 'root object' is missing.");
731 }elseif($ldap->count()){
732 $this->checks['acls']['STATUS'] = TRUE;
733 $this->checks['acls']['STATUS_MSG']= _("Ok");
734 }else{
735 $this->checks['acls']['STATUS'] = FALSE;
736 $this->checks['acls']['STATUS_MSG']= _("Failed");
737 $this->checks['acls']['ERROR_MSG'].= "<input type='submit' name='create_acls' value='"._("Create adminitrational account")."'>";
738 }
739 return($ldap->count()>=1);
740 }
744 function create_admin($only_ldif = FALSE)
745 {
746 /* Reset '' */
747 $this->acl_create_changes="";
749 /* Object that should receive admin acls */
750 $dn = $this->acl_create_selected;
752 /* Get collected configuration settings */
753 $cv = $this->parent->captured_values;
755 /* Establish ldap connection */
756 $ldap = new LDAP($cv['admin'],
757 $cv['password'],
758 $cv['connection'],
759 FALSE,
760 $cv['tls']);
762 /* Get current base attributes */
763 $ldap->cd($cv['base']);
764 $ldap->cat($cv['base'],array("dn","objectClass","gosaAclEntry"));
765 $attrs = $ldap->fetch();
767 /* Add acls for the selcted user to the base */
768 $attrs_new['objectClass'] = array("gosaACL");
770 for($i = 0; $i < $attrs['objectClass']['count']; $i ++){
771 if(!in_array_ics($attrs['objectClass'][$i],$attrs_new['objectClass'])){
772 $attrs_new['objectClass'][] = $attrs['objectClass'][$i];
773 }
774 }
776 $acl = "0:sub:".base64_encode($dn).":all;cmdrw";
777 $attrs_new['gosaAclEntry'][] = $acl;
778 if(isset($attrs['gosaAclEntry'])){
779 for($i = 0 ; $i < $attrs['gosaAclEntry']['count']; $i ++){
781 $prio = preg_replace("/[:].*$/","",$attrs['gosaAclEntry'][$i]);
782 $rest = preg_replace("/^[^:]/","",$attrs['gosaAclEntry'][$i]);
784 $data = ($prio+1).$rest;
785 $attrs_new['gosaAclEntry'][] = $data;
786 }
787 }
789 if($only_ldif){
790 $this->acl_create_changes ="\n".$cv['base']."\n";
791 $this->acl_create_changes.=$this->array_to_ldif($attrs)."\n";
792 $this->acl_create_changes.="\n".$cv['base']."\n";
793 $this->acl_create_changes.=$this->array_to_ldif($attrs_new);
794 }else{
796 $ldap->cd($cv['base']);
797 if(!$ldap->modify($attrs_new)){
798 print_red(sprintf(_("Adding acls for user '%s' failed, ldap says '%s'."),$dn,$ldap->get_error()));
799 }
800 }
801 }
804 function create_admin_user()
805 {
806 if(isset($_POST['new_user_password']) && !empty($_POST['new_user_password'])){
807 $pwd = $_POST['new_user_password'];
808 }else{
809 print_red(_("Please specify a valid password for the new GOsa admin user."));
810 return(FALSE);
811 }
813 /* Establish ldap connection */
814 $cv = $this->parent->captured_values;
815 $ldap = new LDAP($cv['admin'],
816 $cv['password'],
817 $cv['connection'],
818 FALSE,
819 $cv['tls']);
821 /* Get current base attributes */
822 $ldap->cd($cv['base']);
824 if($cv['peopledn'] == "cn"){
825 $dn = "cn=System Administrator,".$cv['peopleou'].",".$cv['base'];
826 }else{
827 $dn = "uid=admin,".$cv['peopleou'].",".$cv['base'];
828 }
830 $methods = @passwordMethod::get_available_methods_if_not_loaded();
831 $p_m = $methods[$cv['encryption']];
832 $p_c = new $p_m(array());
833 $hash = $p_c->generate_hash($pwd);
835 $new_user=array();
836 $new_user['objectClass']= array("top","person","gosaAccount","organizationalPerson","inetOrgPerson");
837 $new_user['givenName'] = "System";
838 $new_user['sn'] = "Administrator";
839 $new_user['cn'] = "System Administrator";
840 $new_user['uid'] = "admin";
841 $new_user['userPassword'] = $hash;
843 $ldap->cd($cv['base']);
844 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dn));
845 $ldap->cd($dn);
846 $res = $ldap->add($new_user);
847 $this->acl_create_selected = $dn;
848 $this->create_admin();
850 if(!$res){
851 print_red($ldap->get_error());
852 }
854 $this->acl_create_dialog=FALSE;
855 $this->check_administrativeAccount();
856 }
859 function migrate_outside_users($perform = FALSE)
860 {
861 /* Check if there was a destination department posted */
862 if(isset($_POST['move_user_to'])){
863 $destination_dep = $_POST['move_user_to'];
864 }else{
865 print_red(_("Couldn't move users to specified department."));
866 return(false);
867 }
869 foreach($this->outside_users as $b_dn => $data){
870 $this->outside_users[$b_dn]['ldif'] ="";
871 if($data['selected']){
872 $dn = base64_decode($b_dn);
873 $d_dn = preg_replace("/,.*$/",",".base64_decode($destination_dep),$dn);
874 if(!$perform){
875 $this->outside_users[$b_dn]['ldif'] = $dn."<br>".$d_dn;
876 }else{
877 $this->move($dn,$d_dn);
878 }
879 }
880 }
881 }
884 function execute()
885 {
886 /* Initialise checks if this is the first call */
887 if(!$this->checks_initialised || isset($_POST['reload'])){
888 $this->initialize_checks();
889 $this->checks_initialised = TRUE;
890 }
892 /*************
893 * User outside the people ou
894 *************/
896 if(isset($_POST['outside_users_dialog_cancel'])){
897 $this->outside_users_dialog = FALSE;
898 $this->dialog = FALSE;
899 }
901 if(isset($_POST['outside_users_dialog_whats_done'])){
902 $this->migrate_outside_users(FALSE);
903 }
905 if(isset($_POST['outside_users_dialog_perform'])){
906 $this->migrate_outside_users(TRUE);
907 $this->search_outside_users();
908 }
910 if(isset($_POST['outside_users_dialog'])){
911 $this->outside_users_dialog = TRUE;
912 $this->dialog = TRUE;
913 }
915 if($this->outside_users_dialog){
916 $smarty = get_smarty();
917 $smarty->assign("ous",$this->get_all_people_ous());
918 $smarty->assign("method","outside_users");
919 $smarty->assign("outside_users",$this->outside_users);
920 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
921 }
923 /*************
924 * Root object check
925 *************/
927 if(isset($_POST['retry_root_create'])){
929 $state = $this->checks['root']['STATUS'];
930 $this->checkBase(FALSE);
931 if($state != $this->checks['root']['STATUS']){
932 $this->initialize_checks();
933 }
934 }
936 /*************
937 * User Migration handling
938 *************/
940 if(isset($_POST['retry_acls'])){
941 $this->check_administrativeAccount();
942 }
944 if(isset($_POST['create_acls'])){
945 $this->acl_create_dialog = TRUE;
946 $this->dialog = TRUE;
947 }
949 if(isset($_POST['create_acls_cancel'])){
950 $this->acl_create_dialog = FALSE;
951 $this->dialog = FALSE;
952 }
954 if(isset($_POST['create_acls_create_confirmed'])){
955 $this->create_admin();
956 }
958 if(isset($_POST['create_acls_create'])){
959 $this->create_admin(TRUE);
960 }
962 if(isset($_POST['create_admin_user'])){
963 $this->create_admin_user();
964 }
966 if($this->acl_create_dialog){
967 $smarty = get_smarty();
968 $smarty->assign("new_user_password",@$_POST['new_user_password']);
969 $smarty->assign("users" ,$this->get_user_list());
970 $smarty->assign("users_cnt" ,count($this->get_user_list()));
971 $smarty->assign("groups",$this->get_group_list());
972 $smarty->assign("groups_cnt",count($this->get_group_list()));
973 $smarty->assign("type" ,$this->acl_create_type);
974 $smarty->assign("method","create_acls");
975 $smarty->assign("acl_create_selected",$this->acl_create_selected);
976 $smarty->assign("what_will_be_done_now",$this->acl_create_changes);
977 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
978 }
980 /*************
981 * User Migration handling
982 *************/
984 /* Refresh list of deparments */
985 if(isset($_POST['users_visible_migrate_refresh'])){
986 $this->check_gosaAccounts();
987 }
989 /* Open migration dialog */
990 if(isset($_POST['users_visible_migrate'])){
991 $this->users_migration_dialog = TRUE;
992 $this->dialog =TRUE;
993 }
995 /* Close migration dialog */
996 if(isset($_POST['users_visible_migrate_close'])){
997 $this->users_migration_dialog = FALSE;
998 $this->dialog =FALSE;
999 }
1001 /* Start migration */
1002 if(isset($_POST['users_visible_migrate_migrate'])){
1003 if($this->migrate_gosaAccounts()){
1004 $this->check_gosaAccounts();
1005 }
1006 }
1008 /* Start migration */
1009 if(isset($_POST['users_visible_migrate_whatsdone'])){
1010 $this->migrate_gosaAccounts(TRUE);
1011 }
1013 /* Display migration dialog */
1014 if($this->users_migration_dialog){
1015 $smarty = get_smarty();
1016 $smarty->assign("users_to_migrate",$this->users_to_migrate);
1017 $smarty->assign("method","migrate_users");
1018 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1019 }
1022 /*************
1023 * Department Migration handling
1024 *************/
1026 /* Refresh list of deparments */
1027 if(isset($_POST['deps_visible_migrate_refresh'])){
1028 $this->check_organizationalUnits();
1029 }
1031 /* Open migration dialog */
1032 if(isset($_POST['deps_visible_migrate'])){
1033 $this->dep_migration_dialog = TRUE;
1034 $this->dialog =TRUE;
1035 }
1037 /* Close migration dialog */
1038 if(isset($_POST['deps_visible_migrate_close'])){
1039 $this->dep_migration_dialog = FALSE;
1040 $this->dialog =FALSE;
1041 }
1043 /* Start migration */
1044 if(isset($_POST['deps_visible_migrate_migrate'])){
1045 if($this->migrate_organizationalUnits()){
1046 $this->check_organizationalUnits();
1047 }
1048 }
1050 /* Start migration */
1051 if(isset($_POST['deps_visible_migrate_whatsdone'])){
1052 $this->migrate_organizationalUnits(TRUE);
1053 }
1055 /* Display migration dialog */
1056 if($this->dep_migration_dialog){
1057 $smarty = get_smarty();
1058 $smarty->assign("deps_to_migrate",$this->deps_to_migrate);
1059 $smarty->assign("method","migrate_deps");
1060 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1061 }
1063 $smarty = get_smarty();
1064 $smarty->assign("checks",$this->checks);
1065 $smarty->assign("method","default");
1066 return($smarty->fetch(get_template_path("setup_migrate.tpl",TRUE,dirname(__FILE__))));
1067 }
1070 function save_object()
1071 {
1072 /* Capture all selected users from outside_users_dialog */
1073 if($this->outside_users_dialog){
1074 foreach($this->outside_users as $dn => $data){
1075 if(isset($_POST['select_user_'.$dn])){
1076 $this->outside_users[$dn]['selected'] = TRUE;
1077 }else{
1078 $this->outside_users[$dn]['selected'] = FALSE;
1079 }
1080 }
1081 }
1083 /* Get "create acl" dialog posts */
1084 if($this->acl_create_dialog){
1085 if(isset($_POST['create_acls_create'])){
1086 if(isset($_POST['create_acls_selected'])){
1087 $this->acl_create_selected = base64_decode($_POST['create_acls_selected']);
1088 }else{
1089 $this->acl_create_selected = "";
1090 }
1091 }
1093 if(isset($_POST['create_acls_create_abort'])){
1094 $this->acl_create_selected = "";
1095 }
1097 if(isset($_POST['acl_create_type'])){
1098 $this->acl_create_type = $_POST['acl_create_type'];
1099 }
1100 }
1102 /* Get selected departments */
1103 if($this->dep_migration_dialog){
1104 foreach($this->deps_to_migrate as $id => $data){
1105 if(isset($_POST['migrate_'.$id])){
1106 $this->deps_to_migrate[$id]['checked'] = TRUE;
1107 }else{
1108 $this->deps_to_migrate[$id]['checked'] = FALSE;
1109 }
1110 }
1111 }
1113 /* Get selected users */
1114 if($this->users_migration_dialog){
1115 foreach($this->users_to_migrate as $id => $data){
1116 if(isset($_POST['migrate_'.$id])){
1117 $this->users_to_migrate[$id]['checked'] = TRUE;
1118 }else{
1119 $this->users_to_migrate[$id]['checked'] = FALSE;
1120 }
1121 }
1122 }
1123 }
1126 /* Check if the root object exists.
1127 * If the parameter just_check is true, then just check if the
1128 * root object is missing and update the info messages.
1129 * If the Parameter is false, try to create a new root object.
1130 */
1131 function checkBase($just_check = TRUE)
1132 {
1133 /* Get collected setup informations */
1134 $cv = $this->parent->captured_values;
1136 /* Establish ldap connection */
1137 $ldap = new LDAP($cv['admin'],
1138 $cv['password'],
1139 $cv['connection'],
1140 FALSE,
1141 $cv['tls']);
1143 /* Check if root object exists */
1144 $ldap->cd($cv['base']);
1145 $res = $ldap->search("(objectClass=*)");
1146 $err = ldap_errno($ldap->cid);
1148 if( !$res ||
1149 $err == 0x20 || # LDAP_NO_SUCH_OBJECT
1150 $err == 0x40) { # LDAP_NAMING_VIOLATION
1152 /* Root object doesn't exists
1153 */
1154 if($just_check){
1155 $this->checks['root']['STATUS'] = FALSE;
1156 $this->checks['root']['STATUS_MSG']= _("Failed");
1157 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1158 return(FALSE);
1159 }else{
1161 echo "REMOVE this : Autocreation of the root object will be done by create_missing_tree later. !!!!!!!";
1163 /* Try to find out which values are necessary */
1164 $tmp = $ldap->get_objectclasses();
1165 $oc = $tmp['organization'];
1167 $must_attrs = $oc['MUST'];
1168 if(!is_array($must_attrs)){
1169 $must_attrs = array($must_attrs);
1170 }
1172 /* Root object does not exists try to create it */
1173 $ldapadd["objectclass"][0]="top";
1174 $ldapadd["objectclass"][1]="organization";
1176 /* Try to fill all collected must attributes */
1177 $base_parts = preg_split("/,/",$cv['base']);
1178 foreach($must_attrs as $attr){
1179 foreach($base_parts as $part){
1180 if(preg_match("/^".$attr."=/",$part) && !isset($ldapadd[$attr])){
1181 $ldapadd[$attr]= preg_replace("/^[^=]*+=/","",$part);
1182 }
1183 }
1184 }
1186 /* Add root object */
1187 $ldap->cd($cv['base']);
1188 $res = $ldap->add($ldapadd);
1190 /* Add root object */
1191 $ldap->cd($cv['base']);
1192 # $res = $ldap->create_missing_trees($cv['base']);
1194 /* If adding failed, tell the user */
1195 if(!$res){
1196 $this->checks['root']['STATUS'] = FALSE;
1197 $this->checks['root']['STATUS_MSG']= _("Failed");
1198 $this->checks['root']['ERROR_MSG'] = _("Root object couldn't be created, you should try it on your own.");
1199 $this->checks['root']['ERROR_MSG'].= "<input type='submit' name='retry_root_create' value='"._("Try to create root object")."'>";
1200 return($res);;
1201 }
1202 }
1203 }
1205 /* Create & remove of dummy object was successful */
1206 $this->checks['root']['STATUS'] = TRUE;
1207 $this->checks['root']['STATUS_MSG']= _("Ok");
1208 }
1211 /* Return ldif information for a
1212 * given attribute array
1213 */
1214 function array_to_ldif($atts)
1215 {
1216 $ret = "";
1217 unset($atts['count']);
1218 unset($atts['dn']);
1219 foreach($atts as $name => $value){
1220 if(is_numeric($name)) {
1221 continue;
1222 }
1223 if(is_array($value)){
1224 unset($value['count']);
1225 foreach($value as $a_val){
1226 $ret .= $name.": ". $a_val."\n";
1227 }
1228 }else{
1229 $ret .= $name.": ". $value."\n";
1230 }
1231 }
1232 return(preg_replace("/\n$/","",$ret));
1233 }
1236 function get_user_list()
1237 {
1238 /* Get collected configuration settings */
1239 $cv = $this->parent->captured_values;
1241 /* Establish ldap connection */
1242 $ldap = new LDAP($cv['admin'],
1243 $cv['password'],
1244 $cv['connection'],
1245 FALSE,
1246 $cv['tls']);
1248 $ldap->cd($cv['base']);
1249 $ldap->search("(objectClass=gosaAccount)",array("dn"));
1251 $tmp = array();
1252 while($attrs = $ldap->fetch()){
1253 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
1254 }
1255 return($tmp);
1256 }
1259 function get_all_people_ous()
1260 {
1261 /* Get collected configuration settings */
1262 $cv = $this->parent->captured_values;
1264 /* Establish ldap connection */
1265 $ldap = new LDAP($cv['admin'],
1266 $cv['password'],
1267 $cv['connection'],
1268 FALSE,
1269 $cv['tls']);
1271 $ldap->cd($cv['base']);
1272 $ldap->search("(".$cv['peopleou'].")",array("dn"));
1274 if($ldap->count() == 0 ){
1275 $add_dn = $cv['peopleou'].",".$cv['base'];
1276 $naming_attr = preg_replace("/=.*$/","",$add_dn);
1277 $naming_value = preg_replace("/^[^=]*+=([^,]*).*$/","\\1",$add_dn);
1278 $add = array();
1279 $add['objectClass'] = array("organizationalUnit");
1280 $add[$naming_attr] = $naming_value;
1282 $ldap->cd($cv['base']);
1283 $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$add_dn));
1284 $ldap->cd($add_dn);
1285 $ldap->add($add);
1286 }
1288 $ldap->search("(".$cv['peopleou'].")",array("dn"));
1289 $tmp = array();
1290 while($attrs= $ldap->fetch()){
1291 if(!preg_match("/ou=snapshots,/",$attrs['dn'])){
1292 $tmp[base64_encode($attrs['dn'])] = $ldap->fix($attrs['dn']);
1293 }
1294 }
1295 return($tmp);
1296 }
1299 function get_group_list()
1300 {
1301 /* Get collected configuration settings */
1302 $cv = $this->parent->captured_values;
1304 /* Establish ldap connection */
1305 $ldap = new LDAP($cv['admin'],
1306 $cv['password'],
1307 $cv['connection'],
1308 FALSE,
1309 $cv['tls']);
1311 $ldap->cd($cv['base']);
1312 $ldap->search("(objectClass=posixGroup)",array("dn"));
1314 $tmp = array();
1315 while($attrs = $ldap->fetch()){
1316 $tmp[base64_encode($attrs['dn'])] = @LDAP::fix($attrs['dn']);
1317 }
1318 return($tmp);
1319 }
1322 function move($source,$destination)
1323 {
1324 /* Get collected configuration settings */
1325 $cv = $this->parent->captured_values;
1327 /* Establish ldap connection */
1328 $ldap = new LDAP($cv['admin'],
1329 $cv['password'],
1330 $cv['connection'],
1331 FALSE,
1332 $cv['tls']);
1334 /* Rename dn in possible object groups */
1335 # $ldap->cd($cv['base']);
1336 # $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::fix($source).'))',
1337 # array('cn'));
1338 # while ($attrs= $ldap->fetch()){
1339 # $og= new ogroup($this->config, $ldap->getDN());
1340 # unset($og->member[$src_dn]);
1341 # $og->member[$dst_dn]= $dst_dn;
1342 # $og->save ();
1343 # }
1345 $ldap->cat($source);
1346 $new_data = $this->cleanup_array($ldap->fetch());
1347 $ldap->cd($destination);
1348 $res = $ldap->add($new_data);
1350 if(!$res){
1351 print_red(_("Failed to copy '%s' to '%s'. Ldap says '%s'."),$source,$destination,$ldap->get_error());
1352 }else{
1353 $ldap->rmDir($source);
1354 show_ldap_error($ldap->get_error(),_("Something went wrong while copying dns."));
1355 }
1356 }
1359 /* Cleanup ldap result to be able to write it be to ldap */
1360 function cleanup_array($attrs)
1361 {
1362 foreach($attrs as $key => $value) {
1363 if(is_numeric($key) || in_array($key,array("count","dn"))){
1364 unset($attrs[$key]);
1365 }
1366 if(is_array($value) && isset($value['count'])){
1367 unset($attrs[$key]['count']);
1368 }
1369 }
1370 return($attrs);
1371 }
1372 }
1374 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1375 ?>