This is my LDAP code to authenticate a user. I have to show users full name once the user had logged in. How do I get the full name of the user from AD?
<?php
FUNCTION ldapCheckLogin ($username, $upasswd) {
$ldaphost = '10.20.30.40';
$ldapport = 389;
$ds = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to our login server!");
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
if ($ds)
{
//$username = 'na\'; //OK - Congratulations! na\spups is authenticated.
$upname = 'iap\\' . $username;
$ldapbind = #ldap_bind($ds, $upname, $upasswd);
if ($ldapbind) {
//print "Congratulations! $username is authenticated.<BR><BR>";
ldap_unbind( $ds );
return true;
} else { //print "$username - Access Denied!<BR><BR>";
return false;
}
} else {
return false;
}
}
?>
You need to retrieve the user's entry using ldap_search with the user's samAccountName e.g. (samaccountname=$username) or userPrincipalName e.g. (userprincipalname=$username . "#" . $domain.com ) as the filter attribute.
samaccountname is only unique in the domain whereas userPrincipalName is unique across the entire forest.
When you perform the ldap_search you need to include the cn or displayName in the attributes to return.
If the search is successful then you need to process the resulting entry and extract the cn and/or the displayName.
Related
I have a php file that connects and binds to AD with a service account no problem on that.
I have an HTML form asking for user name and password.
I need a way to verify the user's credentials against AD
when the user enters their user name and password in the form.
I cannot use the ldap_bind function, because our users don't have the permission to do that.
Suppose PHP has an auth class, but I cannot figure out how to get it to work. Can anyone help me with that? If auth class doesn't work, what other codes can I use to verify credentials and add it to my PHP page?
The following is my php page:
<?php
// Connect to AD========================================================
include('studentFormAuth.html');
$ldapusername = 'service_account_name';
$ldappassword = "service_account_password";
$server = 'xx.xx.xx.xx';
$domain = '#abc.com';
$port = 389;
$connection = ldap_connect($server, $port);
if (!$connection) {
exit('Connection failed');
}
// Settings for AD======================================================
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
$bind = #ldap_bind($connection, $ldapusername.$domain, $ldappassword);
if (!$bind) {
exit('Binding failed');
}
// Verify user credentials auth function=============================================
$auth = new Auth($connection, $_POST['usern'].$domain, $_POST['password']);
// begin validation
$auth->start();
if ($auth->getAuth()) {
// content for validated users
echo 'user name is: ' $_POST['usern'].$domain;
} else {
echo 'Cannot verify user';
}
// log users out
$auth->logout();
I want to use my system login password to php login page. So that i used the LDAP concept in my project. I have mentioned below my coding, that is everything fine. But When i run this code, the result shows "Invalid user". I don't know why this was showing wrongly.
$ldaphost = 'abc.co.in';
$ldapport = '389';
$username = '4444';
$password = '4444pass';
$ldap = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to $ldaphost");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
$user = "uid=$username,dc=abc,dc=co,dc=in";
$bind = #ldap_bind($ldap, $user, $password);
if ($bind) {
echo "<br />Valid user";
} else {
$msg = "<br />Invalid user";
echo $msg;
}
Below the result:
What is fault in my code or i need to anything add?
Please find and solve this request. That will more helpful to me.
Thank you advance...
This is how my ldap thing works. change your ldap host to be either "ldap://abd.asd.co:389' or "ldaps://asd.basd.co:636".
function verify_user() {
$user = $_REQUEST['user'];
$passwd = $_REQUEST['pass'];
// Bind to LDAP to check is user is valid
$server = "ldaps://ldap.server.com:636";
$dn = "uid=$user, ou=People, ou=something, dc=other, dc=whatever";
// Create a fake password if needed to keep people from anonymously
// binding to LDAP
if($passwd == '') { $passwd = "p"; }
$ldap = ldap_connect($server) or die("Can't connect to LDAP server!");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_start_tls($ldap);
if($ldap) {
$bnd = #ldap_bind($ldap, $dn, stripslashes($passwd));
if(!$bnd) {
sleep(5);
echo "<br>Error: Bad Username or Password!<br>";
exit;
}
}
header("Location: {$_REQUEST['url']}"); /* Redirect browser */
exit;
}
I am integrating my login form with Microsoft active directory. I authenticate
users via LDAP php library.
When user try to log in, they enter username & password.
Connecting to server go successfully, authentication via "LDAP_bind" also
give me true or false according to the values correctness.
Now i am not able to retrieve the user Real name to display it on the screen.
ALL Information I have are the ldap uri with the port number, and username & password entered via the webform.
here is my current code,
$ldap = ldap_connect("ldap://abc.xyz:123");
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'#abc.xyz',$_REQUEST['password']))
{ echo "Welcome". $_REQUEST['username'];}
the $_REQUEST['username'] is not human readable, so i need to read this user attributes or at least display name only.
ldap_search and ldap_read functions did not help, I tried this code:
$ldap_base_dn = 'DC=abc,DC=xyz';
$search_filter = "(objectclass=*)";
$result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter);
with no luck, is there any other information i must have in order to make the ldap_search or ldap_read work successfully. in other words can this be done by having the username and password and the ldap uri only?
You should be able to do the search like this:
$upn = $_REQUEST['username'].'#abc.xyz';
$attributes = ['displayname'];
$filter = "(&(objectClass=user)(objectCategory=person)(userPrincipalName=".ldap_escape($upn, null, LDAP_ESCAPE_FILTER)."))";
$baseDn = "DC=abc,DC=xyz";
$results = ldap_search($ldap, $baseDn, $filter, $attributes);
$info = ldap_get_entries($ldap, $results);
// This is what you're looking for...
var_dump($info[0]['displayname'][0]);
Also, make sure to do the bind with these options:
$ldap = ldap_connect("ldap://abc.xyz:123");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
if ($bind = ldap_bind($ldap, $_REQUEST['username'].'#abc.xyz',$_REQUEST['password']))
When returning the DisplayName value, I recommend that you use a search filter which looks for the samaccountname (username) using something as simple as (samaccountname=$u) with $u being the username from your LDAP connect. If your Active Directory/Open Directory has a lot of objects, I would most certainly recommend targeting OU's as this query can fall on it's bottom pretty quickly.
I've made some further changes to your code so it now runs inside a function which takes 3x params and returns false if the connection or authentication fails.
Check LDAP - Return DisplayName if success login or FALSE(BOOL) if fail login or connection.
function chkLDAP($u, $pass, $domain) {
$dom = "$domain\\"; //Domain Prefix for UNAME which ouputs "domain\"
$user = $dom . $u;
$hostname = 'ldap://abc.com';
$baseDN = 'OU=users, DC=abc, DC=com'; //Narrow down if you have alot of objects as search could take along time
$search = "(samaccountname=$u)"; //Compare with Username
$ldap = ldap_connect($hostname);
if ($ldap) {
$ldapbind = ldap_bind($ldap, $user, $pass);
if ($ldapbind) {
$ldapSearch = ldap_search($ldap, $baseDN, $search);
$entry = ldap_first_entry($ldap, $ldapSearch);
$info = ldap_get_values($ldap, $entry, "displayname");
return $info[0];
}
return false; //Failed Auth
}
return false; //Connection Failed
}
Just test the function for false to make sure you have a displayname before using it.
Run Function:
$displayName = chkLDAP($_REQUEST['username'], $_REQUEST['password'], 'abc.com'); //Run Function - Returns False if Failed or Displayname if True
if ($displayName !== false) {
echo $displayName;
} else {
echo "Username or Password Incorrect!";
}
See:
http://php.net/manual/en/function.ldap-get-values.php
This worked for me for people who need to validate if a user exists in a specific OU.
(by the help of #kitson88 response)
function validateLogin($username,$password)
{
$ldap_dn = "$username#alhait.com";
$ldap_password =$password;
$ldap_con = ldap_connect("server");
ldap_set_option($ldap_con, LDAP_OPT_PROTOCOL_VERSION, 3);
if(#ldap_bind($ldap_con,$ldap_dn,$ldap_password))
{
$baseDN = 'OU=trainers,DC=alhait,DC=com';
$search = "(samaccountname=$username)";
$ldapSearch = ldap_search($ldap_con, $baseDN, $search);
$entry = ldap_first_entry($ldap_con, $ldapSearch);
$info = ldap_get_values($ldap_con, $entry, "displayname");
// var_dump($info[0]);
if($info[0]!=null)
{
return true;
}
}else{
return false;
}
//echo "Invalid Credential";
return false;
}
I am trying to query Active directory for a given user group membership.
When I search a specific user's OU, the search works ok.
When I try to search the entire directory, the result is empty.
Since I have many user OU's, and specific user OU may vary.
The system is CentOS 6.4 with PHP+Apache.
Here is the code:
$ldap_dn = "dc=ccc,dc=bbb,dc=aaa,dc=com";
// Active Directory user for querying
$query_user = "ldap_bind#ccc.bbb.aaa.com";
$password = "xxxx";
// Connect to AD
$ldap = ldap_connect($ldap_host, 389) or die("Could not connect to LDAP");
ldap_bind($ldap,$query_user,$password) or die("Could not bind to LDAP");
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
// Search AD
$results = ldap_search($ldap,$ldap_dn,"(sAMAccountName=$user)",array("memberof","primarygroupid"));
$entries = ldap_get_entries($ldap, $results);
if($entries['count'] == 0) {
echo "No results\n";
return false;
}
Have anyone ever seen similar results? am I missing something or any configuration to support such search?
The correct code iss...
$ldap_dn = "dc=ccc,dc=bbb,dc=aaa,dc=com";
// Active Directory user for querying
$query_user = "ldap_bind#ccc.bbb.aaa.com";
$password = "xxxx";
// Connect to AD
$ldap = ldap_connect($ldap_host, 389) or die("Could not connect to LDAP");
->>> bfore ldap_bind<<<- ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
->>> bfore ldap_bind<<<- ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
ldap_bind($ldap,$query_user,$password) or die("Could not bind to LDAP");
// Search AD
$results = ldap_search($ldap,$ldap_dn,"(sAMAccountName=$user)",array("memberof","primarygroupid"));
$entries = ldap_get_entries($ldap, $results);
if($entries['count'] == 0) {
echo "No results\n";
return false;
}
My aim is to change passwords in Active Directory through a web interface using PHP & IIS.
I have been following the instructions on http://www.ashleyknowles.net/2011/07/iis-php-and-ldaps-with-active-directory/
Prior to following these instructions I could not get a bind to the AD for an LDAPS connection, however after following these instructions it seems to successfully connect, yet gives an error of "Server is unwilling to perform" when I attempt to change the "unicodePwd" value.
Please note that the code below will successfully change any other value of a user in the AD.
<?php
$ldaprdn = 'CN=Admin User,OU=*******,OU=Staff,OU=********,DC=********,DC=*******,DC=******,DC=*****';
$ldappass = "*******"; // associated password
$ldapconn = ldap_connect("ldaps://***.***.***.***:636" ) or die("Could not connect to LDAP server.");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
if ($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...";
$username = '******';
$dn = "CN=Bob Smith,OU=******,OU=******,OU=******,DC=******,DC=******,DC=******,DC=******";
$newPassword = 'blah';
$newEntry = array('unicodePwd' => encodePwd($newPassword));
print_r($newEntry);
if(ldap_mod_replace($ldapconn, $dn, $newEntry)) {
print "<p>succeded</p>";
} else {
print "<p>failed</p>";
}
print_r(ldap_error($ldapconn));
} else {
echo "LDAP bind failed...";
print_r(ldap_error($ldapconn));
}
}
// Credit: http://www.cs.bham.ac.uk/~smp/resources/ad-passwds/
function encodePwd($pw) {
$newpw = '';
$pw = "\"" . $pw . "\"";
$len = strlen($pw);
for ($i = 0; $i < $len; $i++)
$newpw .= "{$pw{$i}}\000";
$newpw = base64_encode($newpw);
return $newpw;
}
?>
SOLVED!!
It turns out that by following the Ashley Knowles tutorial, I was successfully establishing a SSL connection over LDAP, however the error was occurring because of the password encoding.
The credit for the successful password encoding goes to hd42 on this forum post, which enabled me to modify my code accordingly.
Therefore, once you have correctly installed the certificates etc in the harddrive on the IIS server, this code will successfully modify a user password in Active Directory using PHP through an IIS web server (assuming that the $ldaprdn user has sufficient admin rights):
<?php
$ldaprdn = 'CN=Admin User,OU=*******,OU=Staff,OU=********,DC=********,DC=*******,DC=******,DC=*****';
$ldappass = "*******"; // associated password
$ldapconn = ldap_connect("ldaps://***.***.***.***:636" ) or die("Could not connect to LDAP server.");
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
if ($ldapconn) {
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...";
$dn = "CN=Bob Smith,OU=******,OU=******,OU=******,DC=******,DC=******,DC=******,DC=******";
$newPassword = 'blah';
$newPassword = "\"" . $newPassword . "\"";
$newPass = mb_convert_encoding($newPassword, "UTF-16LE");
$newEntry = array('unicodePwd' => $newPass);
print_r($newEntry);
if(ldap_mod_replace($ldapconn, $dn, $newEntry)) {
print "<p>succeded</p>";
} else {
print "<p>failed</p>";
}
print_r(ldap_error($ldapconn));
} else {
echo "LDAP bind failed...";
print_r(ldap_error($ldapconn));
}
}