?
Solved

LDAP Search

Posted on 2006-05-08
38
Medium Priority
?
3,090 Views
Last Modified: 2008-01-09
Hello,

I plan on making a php script that employees can search for email addresses.

pretty much i got this info stored.  note not all employees have all information (such as mobile phone/fax)

First Last
Title
Dept
Address
City, State zip code
e-mail
phone
mobile
fax

i want links from A-Z (thaT will list all employees either given name or surname, perhaps both later on).
also a list all, and a search box where a user can type in a name (possibly searches for full name as i wont know if they search first or last).

i have never coded anything for ldap before and i have no idea where to even begin.  as you can see, my code is very bare indeed.

<?php

$ldaphost = "mail.blarg.com";
$ldapport = 389;

// Connecting to LDAP
$ldapconn = ldap_connect($ldaphost,$ldapport)
   or die("Could not connect to {$ldaphost}");

if ($ldapconn)
{

   $user  = "me@blarg.com";    // ldap rdn or dn
   $pass = "pa$$word";  // associated password

   // binding to ldap server
   $ldapbind = ldap_bind($ldapconn, $user, $pass);

   // verify binding
   if ($ldapbind)
      echo "LDAP bind successful...";
   else
       echo "LDAP bind failed...";
}

?>

i run the script and i have successful bind.  now i am clueless what to do  - please help!!!

as a side note, if i am in the terminal, on the server hosting the intranet, not mail, i can do a basic search and it works.

$ ldapsearch -x -p 389 -h mail -b "cn=mail.blarg.com" -D "mail=me@blarg.com" -w "pa$$word" uid="jane doe"
0
Comment
Question by:weinrj
  • 24
  • 14
38 Comments
 
LVL 9

Accepted Solution

by:
LinuxNubb earned 2000 total points
ID: 16632886
Just add a few more lines to get your search going after the bind:

// modify the search parameters to your liking
$search_string = "(&(objectClass=Person)(mail=*))";

// perform the search, replace company and com with your domain name info
$sr=ldap_search($ds, "DC=company,DC=com", $search_string );

// get the entries
$info = ldap_get_entries($ds, $sr);

You can change the (mail=*) part to use variables, like (mail=*bob*) or whatever.

If you want to see all the values that came back, just do a print_r($info);  This will show all the info for the returned record.  Otherwise the mail value will be like:
$info[0][emplid][0]
if only 1 record was returned.  If you are doing more of a blanket search, you may have to set up a loop to get all email addresses like:

for ($i=0; $i<$info["count"]; $i++) {
      $email = $info[$i][mail][0];
      // do something/////
}
0
 

Author Comment

by:weinrj
ID: 16633335
if ($ldapbind)
   {
      echo "LDAP bind successful...";
      // lets try to do a manual search first
      $search_string = "(&(objectClass=Person)(mail=*))";

      // search it
      $sr = ldap_search($ds, "DC=mail,DC=visionresearch,DC=com",$search_string );

      // get entries
      $info = ldap_get_entries($ds,$sr);

      for ( $i = 0; $i < $info["count"]; $i++ )
      {
         $email = $info[$i][mail][0];
         print $email;
      }

   }

   else
       echo "LDAP bind failed...";
}

gives me quite a few errors actually
LDAP bind successful...
Notice: Undefined variable: ds in /opt/intranet/stuff/ldap.php on line 30

Warning: ldap_search(): supplied argument is not a valid ldap link resource in /opt/intranet/stuff/ldap.php on line 30

Notice: Undefined variable: ds in /opt/intranet/stuff/ldap.php on line 33

Warning: ldap_get_entries(): supplied argument is not a valid ldap link resource in /opt/intranet/stuff/ldap.php on line 33

pretty much i want an example where i can have a variable in the search string so i can set that from a ldap.php?sn=johnson  or something and sn is grabbed in the search query..
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16633741
the $ds variable need to be set to whatever variable you used in your ldap_connect statement.  I'm assuming it's $ldapbind, so :

$info = ldap_get_entries($ldapbind,$sr);
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:weinrj
ID: 16633870
ah ok...

i still get error though

Notice: Undefined variable: ds in /opt/intranet/stuff/ldap.php on line 30

Warning: ldap_search(): supplied argument is not a valid ldap link resource in /opt/intranet/stuff/ldap.php on line 30

Warning: ldap_get_entries(): supplied argument is not a valid ldap link resource in /opt/intranet/stuff/ldap.php on line 33

line 30: $sr = ldap_search($ds, "DC=mail,DC=visionresearch,DC=com",$search_string );
line 33: $info = ldap_get_entries($ldapbind,$sr);

thanks for all your help on this
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16633943
lol, sorry, change that ldap_search as well to the $ldapbind:

$sr = ldap_search($ldapbind, "DC=mail,DC=visionresearch,DC=com",$search_string );

Anywhere I posted $ds, you will need to replace with $ldapbind.
0
 

Author Comment

by:weinrj
ID: 16634574
hmm i am going ot head out now, but i still get the same warnings on the same line #s...all refs of ds are gone
0
 

Author Comment

by:weinrj
ID: 16642362
i still get the errors, though i havent put much time into figuring this out today, todays been too hectic.
any more help is greatly appreciated.  
some more code to help me is even more appreciated esp at 500 point value...
0
 

Author Comment

by:weinrj
ID: 16648595
i still think this is the error:

$search_string = "(&(objectClass=person)(mail=*))";

which causes this to fail
$sr = ldap_search($ldapbind, "DC=mail,DC=visionresearch,DC=com",$search_string );
0
 

Author Comment

by:weinrj
ID: 16648787
i added some var_dumps and i got this:

for code:
 // search it
      $sr = ldap_search($ldapbind, "DC=mail,DC=visionresearch,DC=com",$search_string );
      var_dump($sr);
      var_dump(ldap_error($ldapconn));
      var_dump(ldap_errno($ldapconn));

output:
bool(false) string(7) "Success" int(0)
0
 

Author Comment

by:weinrj
ID: 16649088
ho!

<?php

// make sure your host is the correct one
// that you issued your secure certificate to

$ldaphost = "mail";
$ldapport = 389;

// Connecting to LDAP
$ds = ldap_connect($ldaphost,$ldapport)
   or die("Could not connect to {$ldaphost}");

if ($ds)
{

   $user  = "it@";    // ldap rdn or dn
   $pass = "";  // associated password

   // binding to ldap server
   $ldapbind = ldap_bind($ds, $user, $pass);

   // verify binding
   if ($ldapbind)
   {
      // search it
      $sr = ldap_search($ds, "cn=.net", "sn=W*");

      // get entries
      $info = ldap_get_entries($ds,$sr);
      echo "Data for " . $info["count"]." items returned: <p>";

      for ( $i = 0; $i < $info["count"]; $i++ )
      {

         // search it

         echo "dn is: ". $info[$i]["dn"] ."<br>";
         echo "first cn entry is: ". $info[$i]["cn"][0] ."<br>";
         echo "first email entry is: ". $info[$i]["mail"][0]."<p>";
      }
   }


   else
       echo "LDAP bind failed...";

}

?>

this actually works!
0
 

Author Comment

by:weinrj
ID: 16649153
this stuff doesnt however:

for ( $i = 0; $i < $info["count"]; $i++ )
      {

         // search it

         // this works
         //echo "dn is: ". $info[$i]["dn"] ."<br>";
         //echo "first cn entry is: ". $info[$i]["cn"][0] ."<br>";
         //echo "first email entry is: ". $info[$i]["mail"][0]."<p>";
         //
         echo "Name: " . $info[$i]["cn"][0] . "<br />";
         echo "Address: " . $info[$i]["postalAddress"][0] . "<br />";
         echo $info[$i]["l"][0] . ", " . $info[$i]["st"][0] . $info[$i]["postalCode"][0] . "<br />";


      }

and i get output:

Data for 1 items returned:

Name: John Doe

Notice: Undefined index: postalAddress in /opt/intranet/stuff/ldap.php on line 44
Address:

Notice: Undefined index: postalCode in /opt/intranet/stuff/ldap.php on line 45
New York, New York
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16649406
Are you sure it's not postaddress and postalcode, with no caps?  It will be case sensitive.
0
 

Author Comment

by:weinrj
ID: 16649450
aye it is, now it works!

i guess that answered my question too
0
 

Author Comment

by:weinrj
ID: 16649466
hmm i want to be fair so i am unsure how i should award points, i got this workign with your help but i used different code than what is given as well...
0
 

Author Comment

by:weinrj
ID: 16649638
well now i get more problems

<?php

for ( $c = 'A'; $c <= 'Z'; $c++ )
{
   echo "<a href=\"?q=$c\">$c</a>&nbsp;";  // doesnt work as expected get double letters
}


$surname=$_GET['q'];

// make sure your host is the correct one
// that you issued your secure certificate to

$ldaphost = "mail..com";
$ldapport = 389;

// Connecting to LDAP
$ds = ldap_connect($ldaphost,$ldapport)
   or die("Could not connect to {$ldaphost}");

if ($ds)
{

   $user  = "@.com";    // ldap rdn or dn
   $pass = "";  // associated password

   // binding to ldap server
   $ldapbind = ldap_bind($ds, $user, $pass);

   // verify binding
   if ($ldapbind)
   {
      // search it
      $sr = ldap_search($ds, "cn=v", "sn=$surname*");

      // get entries
      $info = ldap_get_entries($ds,$sr);

      for ( $i = 0; $i < $info["count"]; $i++ )
      {

         // search it

         // this works
         //echo "dn is: ". $info[$i]["dn"] ."<br>";
         //echo "first cn entry is: ". $info[$i]["cn"][0] ."<br>";
         //echo "first email entry is: ". $info[$i]["mail"][0]."<p>";
         //
         echo $info[$i]["cn"][0] . "<br />";
         echo $info[$i]["title"][0] . "<br />";
         echo $info[$i]["ou"][0] . "<br />";
         echo $info[$i]["postaladdress"][0] . "<br />";
         echo $info[$i]["l"][0] . ", " . $info[$i]["st"][0] . " " . $info[$i]["postalcode"][0] . "<br />";
         echo $info[$i]["telephonenumber"][0] . "<br />";
         // mobile phone stuff can go here, but can wait for now...
         echo $info[$i]["mail"][0] . "<br />";



      }
   }

i get this
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AB AC AD AE AF AG AH AI AJ AK...YY YZ

now info is missing, when opposed to i did a more direct search like sn=Smi

Notice: Undefined index: title in /opt/intranet/stuff/ldap.php on line 55


Notice: Undefined index: ou in /opt/intranet/stuff/ldap.php on line 56


Notice: Undefined index: postaladdress in /opt/intranet/stuff/ldap.php on line 57


Notice: Undefined index: l in /opt/intranet/stuff/ldap.php on line 58

Notice: Undefined index: st in /opt/intranet/stuff/ldap.php on line 58

Notice: Undefined index: postalcode in /opt/intranet/stuff/ldap.php on line 58
,

Notice: Undefined index: telephonenumber in /opt/intranet/stuff/ldap.php on line 59

0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16649965
echo "<a href=\"?q=$c\">$c</a>&nbsp;";  

Don't you need your page name in there?

like:

echo ""<a href=\"page.php?q=$c\">$c</a>&nbsp;";  

What do you see when you view the source of this page?

What does the link look like above?
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16649983
I'm guessing that all these undefined indexes are because the $surname is not being populated correctly.
0
 

Author Comment

by:weinrj
ID: 16650177
ok the alphabet works now...

i cant put hte page name directly in bc this is going into a CMS (durpal) and it supports php and i hope i can just plop all of this in.  right now i am just doing this in a test dir.
the undefines are being casued bc not all fields in LDAP are populated, such as titles, ph#s, etc.  and some are just group emails like it@

so i understand i have an objectlass with a few entries, i think objectlcass: CommuniGateAccount is for live human emails

also, the get command only works if its used, the page itself is ldap.php and only gets get if its called, so i need more trickery there..

<?php

echo "Search by last initial: ";
$range = range('A', 'Z');
foreach($range as $a)
{
   echo "<a href=\"?q=$a\">$a</a>&nbsp;";
}

echo "<br />";
$surname=$_GET['q'];

...

this also iusnt hte best

if ($ldapbind && strlen($surname) > 0 )
   {
      // search it
      $sr = ldap_search($ds, "cn=visionresearch.net", "sn=$surname*");

      // get entries
      $info = ldap_get_entries($ds,$sr);

      for ( $i = 0; $i < $info["count"]; $i++ )
      {

         // search it

         // this works
         //echo "dn is: ". $info[$i]["dn"] ."<br>";
         //echo "first cn entry is: ". $info[$i]["cn"][0] ."<br>";
         //echo "first email entry is: ". $info[$i]["mail"][0]."<p>";
         //
         echo "<p>";
         echo $info[$i]["givenname"][0] . " " . $info[$i]["sn"][0] . "<br />";
         echo $info[$i]["title"][0] . "<br />";
         echo $info[$i]["ou"][0] . "<br />";
         echo $info[$i]["postaladdress"][0] . "<br />";
         echo $info[$i]["l"][0] . ", " . $info[$i]["st"][0] . " " . $info[$i]["postalcode"][0] . "<br />";
         echo $info[$i]["telephonenumber"][0] . "<br />";
         // mobile phone stuff can go here, but can wait for now...
         echo $info[$i]["mail"][0] . "<br /></p>";



      }
   }


   else
       echo "LDAP bind failed...";


bc some are foreign people and dont have all what i have, and not all have all entries populated as said before..
and so do i use a filter? if so how do i use it?
so i can remove all the group/non human accounts.

also, i want people to search multiple ways

by first name A-Z, last name A-Z (so radio button so i dont need to print two alphabets ?first=a&last=z

and i like to have a input field where they can search full name.  now displayname i guess is best bc i believe all of them are populated...not all givenname, etc.

so i need additional ifs....thanks for all the help guys...this is really helping me learn this,
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16651377
Maybe you can just use a simple isset to see if there, and if it is then print it:

if (isset($info[$i]["postaladdress"])) {
           echo $info[$i]["postaladdress"][0] . "<br />";
}

etc, etc.....

For searching I would have it set like this:

FirstName: <dropdown box with search type> <textbox>
LastName: <dropdown box with search type> <textbox>

Where the dropdown list box would be like:
Starts with
Ends with
Contains
Equals

Then in your queries you just adjust your where clause to reflect this, like:

Starts with -----   WHERE (fieldname LIKE '%$variable')
Ends with -----   WHERE (fieldname LIKE '$variable%')
Contains -----    WHERE (fieldname LIKE '%$variable%')
Equals -----    WHERE (fieldname = '$variable')
 

0
 

Author Comment

by:weinrj
ID: 16651958
yea i was thinking if using isset thought might be an easier way but guess not...

the searching is a good idea
0
 

Author Comment

by:weinrj
ID: 16652461
any idea how i can setup a filter so only human accounts show up?
the ohjectclass is communigateaccount for human, group for non human.
but i have several objectclasses listed in the search query if i do a ldapsearch on the command line..
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16652531
I'm not sure about that, you'd have to search for each type of object.

I've only used objectClass=Person in Active Directory.
0
 

Author Comment

by:weinrj
ID: 16652737
i have

objectclass: top
oc: person
oc: organizationalPerson
oc: inetOrgPerson
oc: CommunigateAccount (human)  group for alias
..

i think thats the only thing unique between them
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16652935
So you would have to d 4 queries, one with each type of object class then.
0
 

Author Comment

by:weinrj
ID: 16658244
how can i do that?
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16659933
$search_string1 = "(&(objectClass=person))";
$search_string2 = "(&(objectClass=organizationalperson))";
$search_string3 = "(&(objectClass=inetorgperson))";
$search_string4 = "(&(objectClass=communigateaccount))";
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16659969
Or you could combine them to 1 string:

$search_string = "(|(objectClass=person)(objectClass=organizationalperson)(objectClass=inetorgperson)(objectClass=communigateaccount))";
0
 

Author Comment

by:weinrj
ID: 16660385
how do i incorporate it?

$search_string4 = "(&(objectClass=communigateaccount))";
      $sr = ldap_search($ds, "cn=visionresearch.net", "sn=$surname*", $search_string4);

gives error
0
 

Author Comment

by:weinrj
ID: 16660584
do i need to include them all? i also need the custom option that hte user submits as well
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16661379
i'm not sure what you'll need exactly.  You'll have to do some testing to see what types of results you get with each kind, and then go from there.
0
 

Author Comment

by:weinrj
ID: 16661411
well the search string, i get invalid filter if i include what you gave me.
0
 

Author Comment

by:weinrj
ID: 16668737
$search_string = "(&(objectcategory=communigateaccount)(sn=$surname))";

this wont return any results.  
0
 

Author Comment

by:weinrj
ID: 16669394
ican get it via if ( isset( $info[$i]["objectclass"][4] ) )
            echo $info[$i]["objectclass"][4] . "<br />";

vbut how do i put aht into the search?
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16669461
I thought that communigateaccount was a objectclass, not an objectcategory?
0
 

Author Comment

by:weinrj
ID: 16669543
i reckon i got my original search query wrong.

pretty much $info[$i]["objectclass"][4] has to be CommuniGateAccount AND whatever the user chose for the search query.  rigt now its just sn.  later on i will give option of givenname as well.  i have links A-Z so it searches sn=surname*.  later on, i will have text field so it searches displayname.
0
 
LVL 9

Expert Comment

by:LinuxNubb
ID: 16669604
OK, so where are we at right now?

What are you getting if you

print_r($info);

Is the array populated with the data you will need to export to the page?
0
 

Author Comment

by:weinrj
ID: 16669746
yes print_r prints everything

in my ldap directory i have human readable accounts and group accounts which just simply forward to people defined in it.  i dont want hte groups to be in the directory listing so i want to filter them out.

essentially, objectclass[4] = CommuniGateAccount is human and CommuniGateGroup is a group.
the second search term i want to display is what is selected in the form.

i use a querystring right now based on surnames.  so sn=surname* returns all of them.  this works, but i want to filter out the groups at the same time.
i also want to eventually have an if statement so i can search by given name via querystring and also displayname via textbox...
0
 

Author Comment

by:weinrj
ID: 16670419
screw it, this works: if ( $info[$i]["objectclass"][4] == "CommuniGateAccount" )
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Introduction This article is intended for those who are new to PHP error handling (https://www.experts-exchange.com/articles/11769/And-by-the-way-I-am-New-to-PHP.html).  It addresses one of the most common problems that plague beginning PHP develop…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses

571 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question