OpenLdap won't retrieve the userpassword - php

My problem is that when i try to retrieve the value of the attribute 'userPassword' it won't work i'm working under PHP , the problem is that the attribute exist when i open Phpldapadmin i can see it , but when i try to retrieve it using this lines of code it won't work
$sr = ldap_search($ds,"ou=people,dc=powerm,dc=com","uid=".$login);
$data = ldap_get_entries($ds,$sr);
$password = $data[0]["userpassword"][0];
$displayName = $data[0]["displayname"][0];
$num_tel =$data[0]["mobile"][0];
$mail =$data[0]["mail"][0]
the others attributes work fine expect the userpassword
can any one help ?
thanks.

Try specifying the attributes you want returned explicitly.
$dn = 'ou=people,dc=powerm,dc=com';
$filter = 'uid=' . $login;
$attrs = ['displayname', 'userpassword', 'mobile', 'mail'];
$sr = ldap_search($ds, $dn, $filter, $attrs);
The directory may be configured not to return this security-sensitive attribute unless you explicitly ask for it.
It may also be that the attribute requires special privileges to access it - are you using the same credentials to connect to the database in your code as you did in phpLDAPAdmin?
The server may also be configured not to return the password unless it's over an encrypted connection - initiated using an ldaps:// URL passed to ldap_connect(), or using ldap_start_tls().

Related

PHP-LDAP change password

We use LDAP (Samba) for authentication and now I want to make user able to change their password. I'm using this script:
$username = $request->request->get('username');
$oldpasswd = $request->request->get('oldpasswd');
$newpasswd = $request->request->get('newpasswd');
$userPassword = mb_convert_encoding('"'.$newpasswd.'"', 'utf-16le');
$ldapPasswd = $this->getParameter('LDAP_PASSWD');
$ldap->bind("CN=LDAPADMIN,CN=Users,DC=DOMAIN,DC=net", $ldapPasswd);
$query = $ldap->query('CN=users,DC=DOMAIN,DC=net', "(&(objectclass=person)(sAMAccountName=$username))");
$result = $query->execute()->toArray();
$entry = $result[0];
$newEntry = new Entry($entry->getDn(), [
'unicodePwd' => [$userPassword],
]);
$ldap->getEntryManager()->update($newEntry);
It is working ok but with this, all security settings are not valid: Don't repeat password, password length > 6 characters etc etc... And, the script uses an Adminstrator account to change password.Is there any other way to update the user password using user account for that and validating password security configs?
Based on your code, it seems you're using Symfony and you have an Active Directory server.
Your code is doing a "password reset", which is something an administrator would do if a user forgets their password. It requires administrative rights and does not require knowing the previous password, and thus it does not enforce previous history.
What you want to do is a "password change". The documentation for unicodePwd explains how to do this:
If the Modify request contains a delete operation containing a value Vdel for unicodePwd followed by an add operation containing a value Vadd for unicodePwd, the server considers the request to be a request to change the password. The server decodes Vadd and Vdel using the password decoding procedure documented later in this section. Vdel is the old password, while Vadd is the new password.
In LDAP, this is called a "batch request", which contains both a delete instruction and an add instruction, all in the same single request to the server. The Symfony documentation includes a section on how to do Batch Updating. In your case, it should look something like this:
$username = $request->request->get('username');
$oldpasswd = $request->request->get('oldpasswd');
$newpasswd = $request->request->get('newpasswd');
$oldUserPassword = mb_convert_encoding('"'.$oldpasswd.'"', 'utf-16le');
$userPassword = mb_convert_encoding('"'.$newpasswd.'"', 'utf-16le');
$ldapPasswd = $this->getParameter('LDAP_PASSWD');
$ldap->bind("CN=LDAPADMIN,CN=Users,DC=DOMAIN,DC=net", $ldapPasswd);
$query = $ldap->query('CN=users,DC=DOMAIN,DC=net', "(&(objectclass=person)(sAMAccountName=$username))");
$result = $query->execute()->toArray();
$entry = $result[0];
$entryManager->applyOperations($entry->getDn(), [
new UpdateOperation(LDAP_MODIFY_BATCH_REMOVE, 'unicodePwd', $oldUserPassword),
new UpdateOperation(LDAP_MODIFY_BATCH_ADD, 'unicodePwd', $userPassword),
]);
Notice that you have to encode the old password the same way you encoded the new password.

PHP LDAP Multiple Binds

Quite new to PHP and LDAP here, looking for some assistance with a personal project (trying to teach myself!).
I would like to password protect certain pages on our website using a simple login box.
My login.php page contains a simple login form with username and password inputs. I have managed to get the login process working using the code below. I am able to use my Active Directory username/pass to login via this form and proceed to the desired page, no issues.
However I'm not sure if I am doing it the 'correct' way.
My code;
ldap.php
session_start();
function authenticate($user, $password) {
if(empty($user) || empty($password)) return false;
$ldaphost = "ad.example.com";
$ldap_dn = "DC=ad,DC=example,DC=com";
$ldap_user_group = "Staff";
$ldap_usr_dom = '#ad.example.com';
$ldap = ldap_connect($ldaphost);
if($bind = ldap_bind($ldap, $user.$ldap_usr_dom, $password) or die ("Error: ".ldap_error($ldap))) {
$filter = "(sAMAccountName=".$user.")";
$attr = array("");
$result = ldap_search($ldap, $ldap_dn, $filter) or exit("Unable to search LDAP server") or die ("Error searching: ".ldap_error($ldap));
$entries = ldap_get_entries($ldap, $result);
ldap_unbind($ldap);
}
foreach($entries[0]['memberof'] as $grps) {
if(empty($grps) || empty($ldap_user_group)) return false;
if(strpos($grps, $ldap_user_group)) {
$access = 1;
} else {
}
}
if($access != 0) {
$_SESSION['user'] = $user;
$_SESSION['access'] = $access;
return true;
} else {
return false;
}
}
I've been told (by someone else) that this particular LDAP authentication process should work in two steps, as follows;
A search is made for the entered user name. I would recommend you use a search user DN and password for this – a user that has search permissions. It binds with these credentials before making the search. If the search succeeds it retrieves the DN of the found user and the search attribute which will later be used to look up the member record.
A second bind is then made with the retrieved user DN and the entered password. If this bind succeeds then the user is authenticated.
My questions are;
Is the above statement correct?
Are two 'binds' necessary?
Can't I just bind the LDAP connection with the credentials the user entered?
Any advice is appreciated, I'm struggling to get my head round the authentication process really :s
Short Answers:
yes
yes
no
Long answer:
Currently you can only bind with the users username and email-address. And that only works with AD as backend. So when you want to do an AD-Authenticator that's OK. But you specificslly asked for an LDAP-Authenticator. And an LDAP bind only works witha DN as the "username". As most of your users will not know that it's easier for them to remember an email-address or a username for a login. So you will need to find the DN to the users login-data. So you will need to do a search in the LDAP and for that you have to bind. So to bind as the user you need to bind... To get around that circular dependency you need to bind first as someone that has read access to the Directory and use that session to find the DN of the user. When found you use that DN and the user-provided password to do a second bind to verify the users credentials.
I did a talk about that just two days ago at zendcon. You can find the slides with some examples at https://heiglandreas.github.io/slidedeck/Directory_Authentication_with_LDAP/20161019%20-%20zendcon/index_online.html

Add password user using LDAP PHP

I searched every days for my problem, I tried many solutions and I didn't find... :(
I want to create an user using ldap_add with PHP. Working fine without enable account and without password. You find the code below.
Can you help me, please?
Config :
PHP 5.6
Windows Server 2012 R2 with AD
I can enable an account when I use $info["useraccountcontrol"]=544; but the account isn't with a password... User must loggon without password and type his new password at the first connection. *
I tried to add a password with $info['userPassword'] and chand useraccountontrol at 512 and I get this error :
ldap_add(): Add: Server is unwilling to perform
Here is my code :
<?php
$name = htmlspecialchars($_POST["name_build"]);
$lastname = htmlspecialchars($_POST["lastname_build"]);
$department = utf8_encode(htmlspecialchars($_POST["department_build"]));
$title = utf8_encode(htmlspecialchars($_POST["title_build"]));
$dn="CN=$name OU=Users, o=Domocom, c=net";
$ds = ldap_connect("192.168.1.1",389);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // IMPORTANT
ldap_bind($ds, "administrateur#domocom.net", "password");
// Prépareles données
$cn = $info["cn"] = "$lastname $name";
$info["sn"]="$name";
$info["givenname"]="$lastname";
$info["displayname"]="$lastname $name";
$info["name"]="$lastname $name";
$info["userprincipalname"]= "$lastname.$name#domocom.net";
$info["samaccountname"]= "$lastname.$name";
$info["title"]="$title";
$info["department"]="$department";
$info["mail"]="$lastname.$name#domocom.fr";
$info["postalcode"]="69009";
$info["objectClass"][0]="user";
//$info['userPassword'] = "password";
//$info["useraccountcontrol"]=544;
$r = ldap_add($ds,"CN=$cn,OU=Users,OU=Direction,OU=Domocom-SP,DC=domocom,DC=net", $info);
ldap_close($ds);
} else {
echo "unable to connect to ldap server";
}
?>
Thanks a lot.
PS : it's fake society for my school. :p
If it's an AD you might need to use a secure LDAP-Connection.
For that you'll need to call ldap_connect('ldaps://192.168.1.1:<port of the AD>');. Calling ldap_connect with two parameters is deprecated and should be avoided. Use it with an LDAP-URI!
You can also omit the if…else around the ldap_connect as it will return true in almost all cases. And a true return-value does not mean that a connection to the server actually as established. A connection is first established on the first ldap_-command that needs a connection which is typically ldap_bind.
And then you might want to have a look at Change AD password using PHP, Issue updating AD password using PHP and Change AD Password using PHP/COM/ADSI/LDAP

Android: Mysql, php, json, http and security

I'm quite new to the Android and Java world; I'm trying to develop an app that need to get and insert information in a database.
I searched on the net, and I found that the best solution is to use HTTP connection using PHP files with Jsons outputs as an interface between the application and the Mysql Db.
However, I can't figure out how to 'secure' everything.
Example:
To change the nickname of an user i connect my app to a php page with this code:
$nickname = $_POST['nickname'];
$id = $_POST['id'];
nicknameChange($id,$nickname);
function nicknameChange($id,$nickname){
global $mysqli;
$sql = "UPDATE users SET nickname = ? WHERE id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('si',$nickname,$id);
$stmt->execute();
}
Via post i pass the id of the user that wanna change nickname and the new nickname, how can i be sure that no one will 'manipulate' that page passing to it ids of other users to change their nickname?
I read on the Net that an HTTPS connection may solve the problem, is that enough?
In your client (android) and in server(php) you need use a key like 'API KEY'
In server
$message = 'Access denied';
$checkApi = false;
if(function_exists('apache_request_headers')){
if(apache_request_headers()['Authorization'] == '2d30ff242f8650954bfe8c993f084f4f')
$checkApi = true;
}
or
if(isset($_SERVER["Authorization"]) && $_SERVER["Authorization"] == '2d30ff242f8650954bfe8c993f084f4f'){
$checkApi = true;
}
Client: in your request you will put string '2d30ff242f8650954bfe8c993f084f4f' with key 'Authorization' to Header request.
This is a private key!

Change user's distinguishedname using LDAP and PHP

I'm new(ish) to LDAP, I have managed to list everything fine and I can unlock accounts, however my current task is to do a "name change" for when a user gets married or if we set them up incorrectly etc, what I have so far is failing, please can anyone advise?
thanks
if current $distinguishedname & dn is: CN=Lambo Innit,OU=Services,OU=UserDepartments,OU=North,DC=eng,DC=company,DC=co,DC=uk
and I want to change the distinguishedname and the dn, I'm having problems.$ds is working as I can do other ldap things with this (mod_replace etc)
$newdn = CN=New Name;
$newOU = OU=Services,OU=UserDepartments,OU=North,DC=eng,DC=company,DC=co,DC=uk;
ldap_rename($ds,$distinguishedName,$newdn,$newOU,true);
EDITED to make it easier to read
Thanks for your post, you helped me figure out how to move a user from the OU=Contractors group to the OU=Employees Group
//variables
$ds1 = ldap_connect( <<your ldap connection>> );
$cn = 'firstname lastname';
$dn = 'CN='.$cn.',OU=Contractors,DC=AD,DC=MYCOMPANYNAME,DC=COM';
$newcn = 'CN='.$cn; //I use same value, since I don't want to change it
$newOU = 'OU=employees,DC=AD,DC=MYCOMPANYNAME,DC=COM';
//update Active Directory
ldap_rename($ds1, $dn, $newcn, $newOU, true);

Categories