1 <?php
2 /*****************************************************************************
3 newldap.inc - version 1.0
4 Copyright (C) 2003 Alejandro Escanero Blanco <alex@ofmin.com>
5 Copyright (C) 2004-2006 Cajus Pollmeier <pollmeier@gonicus.de>
7 Based in code of ldap.inc of
8 Copyright (C) 1998 Eric Kilfoil <eric@ipass.net>
9 *****************************************************************************/
11 define("ALREADY_EXISTING_ENTRY",-10001);
12 define("UNKNOWN_TOKEN_IN_LDIF_FILE",-10002);
13 define("NO_FILE_UPLOADED",10003);
14 define("INSERT_OK",10000);
15 define("SPECIALS_OVERRIDE", TRUE);
17 class LDAP{
19 var $hascon =false;
20 var $hasres =false;
21 var $reconnect=false;
22 var $tls = false;
23 var $basedn ="";
24 var $cid;
25 var $error = ""; // Any error messages to be returned can be put here
26 var $start = 0; // 0 if we are fetching the first entry, otherwise 1
27 var $objectClasses = array(); // Information read from slapd.oc.conf
28 var $binddn = "";
29 var $bindpw = "";
30 var $hostname = "";
31 var $follow_referral = FALSE;
32 var $referrals= array();
35 function LDAP($binddn,$bindpw, $hostname, $follow_referral= FALSE, $tls= FALSE)
36 {
37 $this->follow_referral= $follow_referral;
38 $this->tls=$tls;
39 $this->binddn=$this->convert($binddn);
41 $this->bindpw=$bindpw;
42 $this->hostname=$hostname;
43 $this->connect();
44 }
47 /* Function to replace all problematic characters inside a DN by \001XX, where
48 \001 is decoded to chr(1) [ctrl+a]. It is not impossible, but very unlikely
49 that this character is inside a DN.
51 Currently used codes:
52 , => CO
53 \2C => CO
54 ( => OB
55 ) => CB
56 / => SL */
57 function convert($dn)
58 {
59 if (SPECIALS_OVERRIDE == TRUE){
60 return (preg_replace(array("/\\\\,/", "/\\\\2C/", "/\(/", "/\)/", "/\//"),
61 array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL"),
62 $dn));
63 } else {
64 return ($dn);
65 }
66 }
69 /* Function to fix all problematic characters inside a DN by replacing \001XX
70 codes to their original values. See "convert" for mor information.
71 ',' characters are always expanded to \, (not \2C), since all tested LDAP
72 servers seem to take it the correct way. */
73 function fix($dn)
74 {
75 if (SPECIALS_OVERRIDE == TRUE){
76 return (preg_replace(array("/\001CO/", "/\001OB/", "/\001CB/", "/\001SL/"),
77 array("\,", "(", ")", "/"),
78 $dn));
79 } else {
80 return ($dn);
81 }
82 }
85 function connect()
86 {
87 $this->hascon=false;
88 $this->reconnect=false;
89 if ($this->cid= @ldap_connect($this->hostname)) {
90 @ldap_set_option($this->cid, LDAP_OPT_PROTOCOL_VERSION, 3);
91 if (function_exists("ldap_set_rebind_proc") && $this->follow_referral) {
92 @ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1);
93 @ldap_set_rebind_proc($this->cid, array(&$this, "rebind"));
94 }
95 if (function_exists("ldap_start_tls") && $this->tls){
96 @ldap_start_tls($this->cid);
97 }
99 $this->error = "No Error";
100 if ($bid = @ldap_bind($this->cid, $this->fix($this->binddn), $this->bindpw)) {
101 $this->error = "Success";
102 $this->hascon=true;
103 } else {
104 if ($this->reconnect){
105 if ($this->error != "Success"){
106 $this->error = "Could not rebind to " . $this->binddn;
107 }
108 } else {
109 $this->error = "Could not bind to " . $this->binddn;
110 }
111 }
112 } else {
113 $this->error = "Could not connect to LDAP server";
114 }
115 }
117 function rebind($ldap, $referral)
118 {
119 $credentials= $this->get_credentials($referral);
120 if (@ldap_bind($ldap, $this->fix($credentials['ADMIN']), $credentials['PASSWORD'])) {
121 $this->error = "Success";
122 $this->hascon=true;
123 $this->reconnect= true;
124 return (0);
125 } else {
126 $this->error = "Could not bind to " . $credentials['ADMIN'];
127 return NULL;
128 }
129 }
131 function reconnect()
132 {
133 if ($this->reconnect){
134 @ldap_unbind($this->cid);
135 $this->cid = NULL;
136 }
137 }
139 function unbind()
140 {
141 @ldap_unbind($this->cid);
142 $this->cid = NULL;
143 }
145 function disconnect()
146 {
147 if($this->hascon){
148 @ldap_close($this->cid);
149 $this->hascon=false;
150 }
151 }
153 function cd($dir)
154 {
155 if ($dir == "..")
156 $this->basedn = $this->getParentDir();
157 else
158 $this->basedn = $this->convert($dir);
159 }
161 function getParentDir($basedn = "")
162 {
163 if ($basedn=="")
164 $basedn = $this->basedn;
165 else
166 $basedn = $this->convert($this->basedn);
167 return(ereg_replace("[^,]*[,]*[ ]*(.*)", "\\1", $basedn));
168 }
170 function search($filter, $attrs= array())
171 {
172 if($this->hascon){
173 if ($this->reconnect) $this->connect();
174 $this->clearResult();
175 $this->sr = @ldap_search($this->cid, $this->fix($this->basedn), $filter, $attrs);
176 $this->error = @ldap_error($this->cid);
177 $this->resetResult();
178 $this->hasres=true;
180 return($this->sr);
181 }else{
182 $this->error = "Could not connect to LDAP server";
183 return("");
184 }
185 }
187 function ls($filter = "(objectclass=*)", $basedn = "",$attrs = array("*"))
188 {
189 if($this->hascon){
190 if ($this->reconnect) $this->connect();
191 $this->clearResult();
192 if ($basedn == "")
193 $basedn = $this->basedn;
194 else
195 $basedn= $this->convert($basedn);
196 $this->sr = @ldap_list($this->cid, $this->fix($basedn), $filter,$attrs);
197 $this->error = @ldap_error($this->cid);
198 $this->resetResult();
199 $this->hasres=true;
200 return($this->sr);
201 }else{
202 $this->error = "Could not connect to LDAP server";
203 return("");
204 }
205 }
207 function cat($dn,$attrs= array("*"))
208 {
209 if($this->hascon){
210 if ($this->reconnect) $this->connect();
211 $this->clearResult();
212 $filter = "(objectclass=*)";
213 $this->sr = @ldap_read($this->cid, $this->fix($dn), $filter,$attrs);
214 $this->error = @ldap_error($this->cid);
215 $this->resetResult();
216 $this->hasres=true;
217 return($this->sr);
218 }else{
219 $this->error = "Could not connect to LDAP server";
220 return("");
221 }
222 }
224 function set_size_limit($size)
225 {
226 /* Ignore zero settings */
227 if ($size == 0){
228 @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000);
229 }
230 if($this->hascon){
231 @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size);
232 } else {
233 $this->error = "Could not connect to LDAP server";
234 }
235 }
237 function fetch()
238 {
239 if($this->hascon){
240 if($this->hasres){
241 if ($this->start == 0)
242 {
243 $this->start = 1;
244 $this->re= @ldap_first_entry($this->cid, $this->sr);
245 } else {
246 $this->re= @ldap_next_entry($this->cid, $this->re);
247 }
248 if ($this->re)
249 {
250 $att= @ldap_get_attributes($this->cid, $this->re);
251 $att['dn']= $this->convert(@ldap_get_dn($this->cid, $this->re));
252 }
253 $this->error = @ldap_error($this->cid);
254 if (!isset($att)){
255 $att= array();
256 }
257 return($att);
258 }else{
259 $this->error = "Perform a Fetch with no Search";
260 return("");
261 }
262 }else{
263 $this->error = "Could not connect to LDAP server";
264 return("");
265 }
266 }
268 function resetResult()
269 {
270 $this->start = 0;
271 }
273 function clearResult()
274 {
275 if($this->hasres){
276 $this->hasres = false;
277 @ldap_free_result($this->sr);
278 }
279 }
281 function getDN()
282 {
283 if($this->hascon){
284 if($this->hasres){
286 if(!$this->re)
287 {
288 $this->error = "Perform a Fetch with no valid Result";
289 }
290 else
291 {
292 $rv = @ldap_get_dn($this->cid, $this->re);
294 $this->error = @ldap_error($this->cid);
295 return($this->convert($rv));
296 }
297 }else{
298 $this->error = "Perform a Fetch with no Search";
299 return("");
300 }
301 }else{
302 $this->error = "Could not connect to LDAP server";
303 return("");
304 }
305 }
307 function count()
308 {
309 if($this->hascon){
310 if($this->hasres){
311 $rv = @ldap_count_entries($this->cid, $this->sr);
312 $this->error = @ldap_error($this->cid);
313 return($rv);
314 }else{
315 $this->error = "Perform a Fetch with no Search";
316 return("");
317 }
318 }else{
319 $this->error = "Could not connect to LDAP server";
320 return("");
321 }
322 }
324 function rm($attrs = "", $dn = "")
325 {
326 if($this->hascon){
327 if ($this->reconnect) $this->connect();
328 if ($dn == "")
329 $dn = $this->basedn;
331 $r = @ldap_mod_del($this->cid, $this->fix($dn), $attrs);
332 $this->error = @ldap_error($this->cid);
333 return($r);
334 }else{
335 $this->error = "Could not connect to LDAP server";
336 return("");
337 }
338 }
340 function rename($attrs, $dn = "")
341 {
342 if($this->hascon){
343 if ($this->reconnect) $this->connect();
344 if ($dn == "")
345 $dn = $this->basedn;
347 $r = @ldap_mod_replace($this->cid, $this->fix($dn), $attrs);
348 $this->error = @ldap_error($this->cid);
349 return($r);
350 }else{
351 $this->error = "Could not connect to LDAP server";
352 return("");
353 }
354 }
356 function rmdir($deletedn)
357 {
358 if($this->hascon){
359 if ($this->reconnect) $this->connect();
360 $r = @ldap_delete($this->cid, $this->fix($deletedn));
361 $this->error = @ldap_error($this->cid);
362 return($r ? $r : 0);
363 }else{
364 $this->error = "Could not connect to LDAP server";
365 return("");
366 }
367 }
369 /**
370 * Function rmdir_recursive
371 *
372 * Description: Based in recursive_remove, adding two thing: full subtree remove, and delete own node.
373 * Parameters: The dn to delete
374 * GiveBack: True on sucessfull , 0 in error, and "" when we don't get a ldap conection
375 *
376 */
378 function rmdir_recursive($deletedn)
379 {
380 if($this->hascon){
381 if ($this->reconnect) $this->connect();
382 $delarray= array();
384 /* Get sorted list of dn's to delete */
385 $this->ls ("(objectClass=*)",$deletedn);
386 while ($this->fetch()){
387 $deldn= $this->getDN();
388 $delarray[$deldn]= strlen($deldn);
389 }
390 arsort ($delarray);
391 reset ($delarray);
393 /* Really Delete ALL dn's in subtree */
394 foreach ($delarray as $key => $value){
395 $this->rmdir_recursive($key);
396 }
398 /* Finally Delete own Node */
399 $r = @ldap_delete($this->cid, $this->fix($deletedn));
400 $this->error = @ldap_error($this->cid);
401 return($r ? $r : 0);
402 }else{
403 $this->error = "Could not connect to LDAP server";
404 return("");
405 }
406 }
408 /* Copy given attributes and sub-dns with attributes to destination dn
409 */
410 function copy_FAI_resource_recursive($sourcedn,$destinationdn,$type="branch",$is_first = true,$depth=0)
411 {
412 error_reporting(E_ALL);
414 if($is_first){
415 echo "<h2>".sprintf(_("Creating copy of %s"),"<i>".$sourcedn."</i>")."</h2>";
416 }else{
417 if(preg_match("/^ou=/",$sourcedn)){
418 echo "<h3>"._("Processing")." <i>$destinationdn</i></h3>";
419 }else{
420 $tmp = split(",",$sourcedn);
422 echo " <b>"._("Object").":</b> ";
424 $deststr = $destinationdn;
425 if(strlen($deststr) > 96){
426 $deststr = substr($deststr,0,96)."...";
427 }
429 echo $deststr."<br>";
430 }
431 }
433 flush();
435 if($this->hascon){
436 if ($this->reconnect) $this->connect();
438 /* Save base dn */
439 $basedn= $this->basedn;
440 $delarray= array();
442 /* Check if destination entry already exists */
443 $this->cat($destinationdn);
445 if($this->count()){
446 return;
447 }else{
449 $this->clearResult();
451 /* Get source entry */
452 $this->cd($basedn);
453 $this->cat($sourcedn);
454 $attr = $this->fetch();
456 /* Error while fetching object / attribute abort*/
457 if((!$attr) || (count($attr)) ==0) {
458 echo _("Error while fetching source dn - aborted!");
459 return;
460 }
462 /* check if this is a department */
463 if(in_array("organizationalUnit",$attr['objectClass'])){
464 $attr['dn'] = $this->convert($destinationdn);
465 $this->cd($basedn);
466 $this->create_missing_trees($destinationdn);
467 $this->cd($destinationdn);
469 /* If is first entry, append FAIbranch to department entry */
470 if($is_first){
471 $this->cat($destinationdn);
472 $attr= $this->fetch();
474 /* Filter unneeded informations */
475 foreach($attr as $key => $value){
476 if(is_numeric($key)) unset($attr[$key]);
477 if(isset($attr[$key]['count'])){
478 if(is_array($attr[$key])){
479 unset($attr[$key]['count']);
480 }
481 }
482 }
484 unset($attr['count']);
485 unset($attr['dn']);
487 /* Add marking attribute */
488 $attr['objectClass'][] = "FAIbranch";
490 /* Add this entry */
491 $this->modify($attr);
492 }
493 }else{
495 /* If this is no department */
496 foreach($attr as $key => $value){
497 if(in_array($key ,array("FAItemplateFile","FAIscript", "gotoLogonScript", "gosaApplicationIcon"))){
498 $sr= ldap_read($this->cid, $this->fix($sourcedn), "$key=*", array($key));
499 $ei= ldap_first_entry($this->cid, $sr);
500 if ($tmp= @ldap_get_values_len($this->cid, $ei,$key)){
501 $attr[$key] = $tmp;
502 }
503 }
505 if(is_numeric($key)) unset($attr[$key]);
506 if(isset($attr[$key]['count'])){
507 if(is_array($attr[$key])){
508 unset($attr[$key]['count']);
509 }
510 }
511 }
512 unset($attr['count']);
513 unset($attr['dn']);
515 if(!in_array("gosaApplication" , $attr['objectClass'])){
516 if($type=="branch"){
517 $attr['FAIstate'] ="branch";
518 }elseif($type=="freeze"){
519 $attr['FAIstate'] ="freeze";
520 }else{
521 print_red(_("Unknown FAIstate %s"),$type);
522 }
523 }
525 /* Add entry */
526 $this->cd($destinationdn);
527 $this->cat($destinationdn);
528 $a = $this->fetch();
529 if(!count($a)){
530 $this->add($attr);
531 }
533 if($this->error != "Success"){
534 /* Some error occured */
535 print "---------------------------------------------";
536 print $this->get_error()."<br>";
537 print $sourcedn."<br>";
538 print $destinationdn."<br>";
539 print_a( $attr);
540 exit();
541 }
542 }
543 }
545 $this->ls ("(objectClass=*)",$sourcedn);
546 while ($this->fetch()){
547 $deldn= $this->getDN();
548 $delarray[$deldn]= strlen($deldn);
549 }
550 asort ($delarray);
551 reset ($delarray);
553 $depth ++;
554 foreach($delarray as $dn => $bla){
555 if($dn != $destinationdn){
556 $this->cd($basedn);
557 $item = $this->fetch($this->cat($dn));
558 if(!in_array("FAIbranch",$item['objectClass'])){
559 $this->copy_FAI_resource_recursive($dn,str_replace($sourcedn,$destinationdn,$dn),$type,false,$depth);
560 }
561 }
562 }
563 }
564 if($is_first){
565 echo "<p class='seperator'> </p>";
566 }
568 }
570 function modify($attrs)
571 {
572 if(count($attrs) == 0){
573 return (0);
574 }
575 if($this->hascon){
576 if ($this->reconnect) $this->connect();
577 $r = @ldap_modify($this->cid, $this->fix($this->basedn), $attrs);
578 $this->error = @ldap_error($this->cid);
579 return($r ? $r : 0);
580 }else{
581 $this->error = "Could not connect to LDAP server";
582 return("");
583 }
584 }
586 function add($attrs)
587 {
588 if($this->hascon){
589 if ($this->reconnect) $this->connect();
590 $r = @ldap_add($this->cid, $this->fix($this->basedn), $attrs);
591 $this->error = @ldap_error($this->cid);
592 return($r ? $r : 0);
593 }else{
594 $this->error = "Could not connect to LDAP server";
595 return("");
596 }
597 }
599 function create_missing_trees($target)
600 {
601 /* Ignore create_missing trees if the base equals target */
602 if ($target == $this->basedn){
603 return;
604 }
606 $real_path= substr($target, 0, strlen($target) - strlen($this->basedn) -1 );
607 $l= array_reverse(ldap_explode_dn($real_path,0));
608 unset($l['count']);
609 $cdn= $this->basedn;
611 foreach ($l as $part){
612 $cdn= "$part,$cdn";
614 /* Ignore referrals */
615 $found= false;
616 foreach($this->referrals as $ref){
617 $base= preg_replace('!^[^:]+://[^/]+/([^?]+).*$!', '\\1', $ref['URL']);
618 if ($base == $cdn){
619 $found= true;
620 break;
621 }
622 }
623 if ($found){
624 continue;
625 }
627 $this->cat ($cdn);
628 $attrs= $this->fetch();
630 /* Create missing entry? */
631 if (!count ($attrs)){
632 $type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
633 $param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn);
635 $na= array();
636 switch ($type){
637 case 'ou':
638 $na["objectClass"]= "organizationalUnit";
639 $na["ou"]= $param;
640 break;
641 case 'dc':
642 $na["objectClass"]= array("dcObject", "top", "locality");
643 $na["dc"]= $param;
644 break;
645 default:
646 print_red(sprintf(_("Autocreation of type '%s' is currently not supported. Please report to the GOsa team."), $type));
647 echo $_SESSION['errors'];
648 exit;
649 }
650 $this->cd($cdn);
651 $this->add($na);
652 }
653 }
654 }
656 function recursive_remove()
657 {
658 $delarray= array();
660 /* Get sorted list of dn's to delete */
661 $this->search ("(objectClass=*)");
662 while ($this->fetch()){
663 $deldn= $this->getDN();
664 $delarray[$deldn]= strlen($deldn);
665 }
666 arsort ($delarray);
667 reset ($delarray);
669 /* Delete all dn's in subtree */
670 foreach ($delarray as $key => $value){
671 $this->rmdir($key);
672 }
673 }
675 function get_attribute($dn, $name,$r_array=0)
676 {
677 $data= "";
678 if ($this->reconnect) $this->connect();
679 $sr= @ldap_read($this->cid, $this->fix($dn), "objectClass=*", array("$name"));
681 /* fill data from LDAP */
682 if ($sr) {
683 $ei= @ldap_first_entry($this->cid, $sr);
684 if ($ei) {
685 if ($info= @ldap_get_values_len($this->cid, $ei, "$name")){
686 $data= $info[0];
687 }
689 }
690 }
691 if($r_array==0)
692 return ($data);
693 else
694 return ($info);
697 }
701 function get_additional_error()
702 {
703 $error= "";
704 @ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error);
705 return ($error);
706 }
708 function get_error()
709 {
710 if ($this->error == 'Success'){
711 return $this->error;
712 } else {
713 $error= $this->error." (".$this->get_additional_error().")";
714 return $error;
715 }
716 }
718 function get_credentials($url, $referrals= NULL)
719 {
720 $ret= array();
721 $url= preg_replace('!\?\?.*$!', '', $url);
722 $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
724 if ($referrals == NULL){
725 $referrals= $this->referrals;
726 }
728 if (isset($referrals[$server])){
729 return ($referrals[$server]);
730 } else {
731 $ret['ADMIN']= $this->fix($this->binddn);
732 $ret['PASSWORD']= $this->bindpw;
733 }
735 return ($ret);
736 }
739 function gen_ldif ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE)
740 {
741 $display= "";
743 if ($recursive){
744 $this->cd($dn);
745 $this->search("$filter", array('dn'));
746 while ($attrs= $this->fetch()){
747 $display.= $this->gen_one_entry($attrs['dn'], $filter, $attributes);
748 $display.= "\n";
749 }
750 } else {
751 $display.= $this->gen_one_entry($dn);
752 }
754 return ($display);
755 }
757 function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
758 {
759 $display= "";
761 $this->cd($dn);
762 $this->search("$filter");
764 $i=0;
765 while ($attrs= $this->fetch()){
766 $j=0;
768 foreach ($attributes as $at){
769 $display[$i][$j]= $this->get_attribute($attrs['dn'], $at,$r_array);
770 $j++;
771 }
773 $i++;
774 }
776 return ($display);
777 }
780 function gen_one_entry($dn, $filter= "(objectClass=*)" , $name= array("*"))
781 {
782 $ret = "";
783 $data = "";
784 if($this->reconnect){
785 $this->connect();
786 }
788 /* Searching Ldap Tree */
789 $sr= @ldap_read($this->cid, $this->fix($dn), $filter, $name);
791 /* Get the first entry */
792 $entry= @ldap_first_entry($this->cid, $sr);
794 /* Get all attributes related to that Objekt */
795 $atts = array();
797 /* Assemble dn */
798 $atts[0]['name'] = "dn";
799 $atts[0]['value'] = array('count' => 1, 0 => $dn);
801 /* Reset index */
802 $i = 1 ;
803 $identifier = array();
804 $attribute= @ldap_first_attribute($this->cid,$entry,$identifier);
805 while ($attribute) {
806 $i++;
807 $atts[$i]['name'] = $attribute;
808 $atts[$i]['value'] = @ldap_get_values_len($this->cid, $entry, "$attribute");
810 /* Next one */
811 $attribute= @ldap_next_attribute($this->cid,$entry,$identifier);
812 }
814 foreach($atts as $at)
815 {
816 for ($i= 0; $i<$at['value']['count']; $i++){
818 /* Check if we must encode the data */
819 if(!preg_match('/^[a-z0-9+@#.=, \/ -]+$/i', $at['value'][$i])) {
820 $ret .= $at['name'].":: ".base64_encode($at['value'][$i])."\n";
821 } else {
822 $ret .= $at['name'].": ".$at['value'][$i]."\n";
823 }
824 }
825 }
827 return($ret);
828 }
831 function dn_exists($dn)
832 {
833 return @ldap_list($this->cid, $this->fix($dn), "(objectClass=*)", array("objectClass"));
834 }
838 function import_complete_ldif($str_attr,&$error,$overwrite,$cleanup)
839 {
840 if($this->reconnect) $this->connect();
842 /* First we have to splitt the string ito detect empty lines
843 An empty line indicates an new Entry */
844 $entries = split("\n",$str_attr);
846 $data = "";
847 $cnt = 0;
848 $current_line = 0;
850 /* Every single line ... */
851 foreach($entries as $entry) {
852 $current_line ++;
854 /* Removing Spaces to ..
855 .. test if a new entry begins */
856 $tmp = str_replace(" ","",$data );
858 /* .. prevent empty lines in an entry */
859 $tmp2 = str_replace(" ","",$entry);
861 /* If the Block ends (Empty Line) */
862 if((empty($entry))&&(!empty($tmp))) {
863 /* Add collected lines as a complete block */
864 $all[$cnt] = $data;
865 $cnt ++;
866 $data ="";
867 } else {
869 /* Append lines ... */
870 if(!empty($tmp2)) {
871 /* check if we need base64_decode for this line */
872 if(ereg("::",$tmp2))
873 {
874 $encoded = split("::",$entry);
875 $attr = $encoded[0];
876 $value = base64_decode($encoded[1]);
877 /* Add linenumber */
878 $data .= $current_line."#".$attr.":".$value."\n";
879 }
880 else
881 {
882 /* Add Linenumber */
883 $data .= $current_line."#".$entry."\n";
884 }
885 }
886 }
887 }
889 /* The Data we collected is not in the array all[];
890 For example the Data is stored like this..
892 all[0] = "1#dn : .... \n
893 2#ObjectType: person \n ...."
895 Now we check every insertblock and try to insert */
896 foreach ( $all as $single) {
897 $lineone = split("\n",$single);
898 $ndn = split("#", $lineone[0]);
899 $line = $ndn[1];
901 $dnn = split (":",$line);
902 $current_line = $ndn[0];
903 $dn = $dnn[0];
904 $value = $dnn[1];
906 /* Every block must begin with a dn */
907 if($dn != "dn") {
908 $error= sprintf(_("This is not a valid DN: '%s'. A block for import should begin with 'dn: ...' in line %s"), $line, $current_line);
909 return -2;
910 }
912 /* Should we use Modify instead of Add */
913 $usemodify= false;
915 /* Delete before insert */
916 $usermdir= false;
918 /* The dn address already exists! */
919 if (($this->dn_exists($value))&&((!$overwrite)&&(!$cleanup))) {
921 $error= sprintf(_("The dn: '%s' (from line %s) already exists in the LDAP database."), $line, $current_line);
922 return ALREADY_EXISTING_ENTRY;
924 } elseif(($this->dn_exists($value))&&($cleanup)){
926 /* Delete first, then add */
927 $usermdir = true;
929 } elseif(($this->dn_exists($value))&&($overwrite)) {
931 /* Modify instead of Add */
932 $usemodify = true;
933 }
935 /* If we can't Import, return with a file error */
936 if(!$this->import_single_entry($single,$usemodify,$usermdir) ) {
937 $error= sprintf(_("Error while importing dn: '%s', please check your LDIF from line %s on!"), $line,
938 $current_line);
939 return UNKNOWN_TOKEN_IN_LDIF_FILE; }
940 }
942 return (INSERT_OK);
943 }
946 /* Imports a single entry */
947 function import_single_entry($str_attr,$modify,$delete)
948 {
949 if($this->reconnect) $this->connect();
951 $ret = false;
952 $rows= split("\n",$str_attr);
953 $data= false;
955 foreach($rows as $row) {
957 /* Check if we use Linenumbers (when import_complete_ldif is called we use
958 Linenumbers) Linenumbers are use like this 123#attribute : value */
959 if(!empty($row)) {
960 if((strpos($row,"#")!=FALSE)&&(strpos($row,"#")<strpos($row,":"))) {
962 /* We are using line numbers
963 Because there is a # before a : */
964 $tmp1= split("#",$row);
965 $current_line= $tmp1[0];
966 $row= $tmp1[1];
967 }
969 /* Split the line into attribute and value */
970 $attr = split(":", $row);
971 $attr[0]= trim($attr[0]); /* attribute */
972 $attr[1]= trim($attr[1]); /* value */
974 /* Check for attributes that are used more than once */
975 if(!isset($data[$attr[0]])) {
976 $data[$attr[0]]=$attr[1];
977 } else {
978 $tmp = $data[$attr[0]];
980 if(!is_array($tmp)) {
981 $new[0]=$tmp;
982 $new[1]=$attr[1];
983 $datas[$attr[0]]['count']=1;
984 $data[$attr[0]]=$new;
985 } else {
986 $cnt = $datas[$attr[0]]['count'];
987 $cnt ++;
988 $data[$attr[0]][$cnt]=$attr[1];
989 $datas[$attr[0]]['count'] = $cnt;
990 }
991 }
992 }
993 }
995 /* If dn is an index of data, we should try to insert the data */
996 if(isset($data['dn'])) {
997 /* Creating Entry */
998 $this->cd($data['dn']);
1000 /* Delete existing entry */
1001 if($delete){
1002 $this->rmdir($data['dn']);
1003 }
1005 /* Create missing trees */
1006 $this->create_missing_trees($data['dn']);
1007 unset($data['dn']);
1009 /* If entry exists use modify */
1010 if(!$modify){
1011 $ret = $this->add($data);
1012 } else {
1013 $ret = $this->modify($data);
1014 }
1015 }
1017 return($ret);
1018 }
1021 function importcsv($str)
1022 {
1023 $lines = split("\n",$str);
1024 foreach($lines as $line)
1025 {
1026 /* continue if theres a comment */
1027 if(substr(trim($line),0,1)=="#"){
1028 continue;
1029 }
1031 $line= str_replace ("\t\t","\t",$line);
1032 $line= str_replace ("\t" ,"," ,$line);
1033 echo $line;
1035 $cells = split(",",$line ) ;
1036 $linet= str_replace ("\t\t",",",$line);
1037 $cells = split("\t",$line);
1038 $count = count($cells);
1039 }
1041 }
1043 }
1045 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1046 ?>