Forum Moderators: coopster

Message Too Old, No Replies

LDAP search - making filter my search term

ldap AD search filter

         

urbanmac

3:24 pm on Jan 30, 2007 (gmt 0)

10+ Year Member



Hi,

I've been using a PHP script to query an AD/LDAP server and retrieve people information. The search criteria (filter) works by selecting either First Name, Surname, Phone Number from a drop down list and then entering a search term.

EG: Select Firstname from drop down enter 'Ma' into the search field and anyone in the AD/LDAP Firstname beginning with 'Ma' is returned, eg Martha, Margaret etc.

What I'd like to do and have been trying to do is remove the drop down and then make the field you enter the search term in to search across all the options that are dropdown box at the same time.

Therefore if I search for 'Ma' not only do I get Martha, Margaret etc. I also get Macallister, Malloy etc. (surnames)

But I'm stumped on how to go about this. Heres my AD search:

<form action="adsearch.php" method="post">
Search criteria:<br />
<input type="text" name="keyword" size="20"
maxlength="20" value="" /><br />
Filter:<br />
<select name="filter">
<option value="sn">Choose One:</option>
<option value="sn">Last Name</option>
<option value="telephonenumber">Phone</option>
<option value="givenname">First Name</option>
<option value="mail">Email Address</option>

</select><br />
<input type="submit" value="Search!" />
</form>
</p>

<?php

// Designate a few variables
$host = "HOSTNAME";
$user = "USER";
$pswd = "PASSWORD";

$ad = ldap_connect($host)
or die( "Could not connect!" );

// Set version number
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3)
or die ("Could not set ldap protocol");

// Binding to ldap server
$bd = ldap_bind($ad, $user, $pswd)
or die ("Could not bind");

// Create the DN
$dn = "OU=USERS,DC=DOMAIN,DC=COM";

// Specify only those parameters we're interested in displaying
$attrs = array("displayname","mail","samaccountname","telephonenumber","givenname");

// Create the filter from the search parameters
$filter = $_POST['filter']."=".$_POST['keyword']."*";

$search = ldap_search($ad, $dn, $filter, $attrs)
or die ("");

$entries = ldap_get_entries($ad, $search);

if ($entries["count"] > 0) {

for ($i=0; $i<$entries["count"]; $i++) {
echo "<p>Name: ".$entries[$i]["displayname"][0]."<br />";
echo "Email: <a href=mailto:".$entries[$i]["mail"][0].">".$entries[$i]["mail"][0]."</a><br />";
echo "Short name: ".$entries[$i]["samaccountname"][0]."<br />";
echo "Phone: ".$entries[$i]["telephonenumber"][0]."</p>";

}

} else {
echo "<p>No results found!</p>";
}

ldap_unbind($ad);

?>

[The script above is from a developer.com article]

mcibor

3:39 pm on Jan 30, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Tell me, have you tried:

$filter = "givenname=".$_POST['keyword']."*";

and if it works?

I believe, that ldap_search [de3.php.net] requires filter in a special way:

(givenname=$keyword*)
$filter = "({$_POST['filter']}={$_POST['keyword']}*)";

Hope this is it.

If not, then check what's within
$ad, $dn, $filter and $attrs

Michal

urbanmac

4:10 pm on Jan 30, 2007 (gmt 0)

10+ Year Member



Thanks for the reponse.

$filter = "givenname=".$_POST['keyword']."*";

With this if I search for a 'Gra' the search results only work for the first name e.g it will show Grace Smith but not the John Graham.

Using your second filter I get no results at all returned!

The goal of this is to produce an AJAX AD/LDAP search so as the user types the results begin to appear :D

whoisgregg

6:21 pm on Jan 30, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I think your filter needs to look something like this:

(¦(givenName=Jo*) (sn=Jo*))

So, you'd construct it in PHP with something like:

$filter = "(¦(givenName=".$_POST['keyword']."*) (sn=".$_POST['keyword']."*))";

Although I'd be sure to do some data cleaning before passing that $_POST variable to an LDAP query... I'm not sure if escaping is required but I'd definitely remove anything that is not a letter. :)

Note: WebmasterWorld software breaks the pipe character. Replace all occurences of "¦" with a solid unbroken pipe before running this code. < Shift + \ >

urbanmac

4:09 pm on Feb 5, 2007 (gmt 0)

10+ Year Member



hi there.

that works nicely - well sort of.

When I load my search page it immediately connects to the ldap server and pulls back all the data even before I've entered any search term.

However on the good side when I enter a search term the right results are displayed :)

So what I need my script to do is not show anything until the user enters somehting in the search box

heres my code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=" http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>
<?php
if (isset($filter)) {
echo "Search for ".$keyword." ";
}
else echo "ACTIVEDIRECTORY SEARCH TOOL";
?>
</title>
<style type="text/css">
<!--
body,td,th {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
}
-->
</style></head>

<body>

<p>
<form action="livesearch.php" method="post">
Search criteria:<br />
<input type="text" name="q" size="20"
maxlength="20" value="" /><br />
Filter:<br />
<select name="filter">
<option value="sn">Choose One:</option>
<option value="sn">Last Name</option>
<!--<option value="telephonenumber">Phone</option>-->
<option value="givenname">First Name</option>
<!--<option value="phonenumber">Phone Number</option>-->
<option value="mail">Email Address</option>

</select><br />
<input type="submit" value="Search!" />
</form>
</p>

<?php

// Designate a few variables
$host = "10.10.10.10";
$user = "LDAPUSER";
$pswd = "PASSWORD";

$ad = ldap_connect($host)
or die( "Could not connect!" );

// Set version number
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3)
or die ("Could not set ldap protocol");

// Binding to ldap server
$bd = ldap_bind($ad, $user, $pswd)
or die ("Could not bind");

// Create the DN
$dn = "OU=user,DC=mydomain,DC=com";

// Specify only those parameters we're interested in displaying
$attrs = array("displayname","mail","telephonenumber","givenname");

// Create the filter from the search parameters
$filter = "(¦(givenName=".$_POST['q']."*) (sn=".$_POST['q']."*))";

$search = ldap_search($ad, $dn, $filter, $attrs)
or die ("");

$entries = ldap_get_entries($ad, $search);

if ($entries["count"] > 0) {

for ($i=0; $i<$entries["count"]; $i++) {
echo "<p>Name: ".$entries[$i]["displayname"][0]."<br />";
echo "Email: <a href=mailto:".$entries[$i]["mail"][0].">".$entries[$i]["mail"][0]."</a><br />";
echo "Phone: ".$entries[$i]["telephonenumber"][0]."</p>";

}

} else {
echo "<p>No results found!</p>";
}

ldap_unbind($ad);

?>
</body>
</html>

whoisgregg

4:44 pm on Feb 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Just wrap the entire LDAP section with this IF statement:

if( isset($_POST['q']) &&!empty($_POST['q']) ){
// all your ldap code
}

Don't forget to escape your variables that you are passing to LDAP... I don't know what characters shouldn't be allowed but to be on the safe side I'd probably remove anything that isn't standard alphanumeric input. (I'd definitely remove parentheses, commas, equal signs, pipes, etc.)

urbanmac

5:01 pm on Feb 5, 2007 (gmt 0)

10+ Year Member



wow that's great :D - im learning loads.

So now I need to pass the q to my live search but the url is not constructed like this:

[whatever...]

if I could type the exact url and term into the URL bar then I'd know what to pass on

StupidScript

8:49 pm on Feb 5, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What you describe uses a GET request, instead of a POST request. Check your AJAX documentation for the correct format to use for a GET request, and keep in mind that Opera has some issues with it.

(And please try to limit your posts about a single problem to one thread so you don't get two or more separate threads going about the same thing.)

StupidScript

8:26 pm on Feb 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



For anyone interested, this thread: [webmasterworld.com...] is about this same issue ... stitch together the answers.

urbanmac

8:31 pm on Feb 6, 2007 (gmt 0)

10+ Year Member



apologies for that.

I plan to post all the code for others to use and also I thanks the forums for their help

whoisgregg

8:57 pm on Feb 6, 2007 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you read the manual page for ldap_search [php.net], you'll find this helpful detail to solve your multiple DN search dilemma:

From 4.0.5 on it's also possible to do parallel searches. To do this you use an array of link identifiers, rather than a single identifier, as the first argument. If you don't want the same base DN and the same filter for all the searches, you can also use an array of base DNs and/or an array of filters. ...

We should be able to better deal with the multiple DN issue here in the PHP forum than in the Javascript forum, so go ahead and keep comments to this thread. If you have new, distinct issues with your LDAP script you should probably start a new thread... it makes it much easier for people to help when there is one distinct problem that requires a solution. :)