?
Solved

Php based ldap password reset, will not expire passwords.

Posted on 2008-06-24
12
Medium Priority
?
4,281 Views
Last Modified: 2010-04-21
I am trying to rewrite the following function into php. I can get the php code to reset the password and that is usable, but can not get it to set the password expiration time or warnings.

The function that works on the ldap server:

assrst()
{
print -n "Please enter a valid userid:                  "
read USERID
print -n "Please enter a new password:                  "
stty -echo
read PASS
stty echo
print ""
print -n "Please enter the password again:              "
stty -echo
read PASS2
stty echo
print ""
if [[ $PASS != $PASS2 ]];then
        print "Password not the same...restarting"
        passrst
fi

print $USERID
$LDAPSMOD << EOF
dn: uid=$USERID,ou=people,dc=gds,o=company.com
changetype: modify
replace: userPassword
userPassword: $PASS
EOF
geterr
if [[ $errcode -ne "0" ]];then
        print "Password not changed due to above error"
        return
fi
sleep 1
$LDAPSMOD << EOF
dn: uid=$USERID,ou=people,dc=gds,o=company.com
changetype: modify
replace: passwordExpirationTime
passwordExpirationTime: 19700101000000Z
-
replace: passwordExpWarned
passwordExpWarned: 0
EOF

}


and the code I"m trying to use to do the same thing :

<?
include('../includes/config.php');

      $userpassword = "{SHA}" . base64_encode( pack( "H*", sha1( strtolower($_POST["userpassword"]) ) ) );
      $ld = ldap_connect($ldap_server) or die("Couldn't connect to Lepton!");
      ldap_set_option($ld, LDAP_OPT_PROTOCOL_VERSION, 3);
      $lbd = ldap_bind($ld,$ldap_username,$ldap_password) or die("Couldn't log into LDAP, verify your username and password.");
      $reset_dn = "uid=".$_POST["user_to_reset"].",ou=people,dc=gds,o=company.com";
      $entry["userpassword"] = $userpassword;
      $entry["passwordexpirationtime"] = "19700101000000Z";
      $entry["passwordexpwarned"] = "0";
      $results = ldap_mod_replace($ld, $reset_dn, $entry);
      ldap_unbind($ld);


As I mentioned, it will reset the password, but doesn't change the passwordexpirationtime to the past in order to force a reset, it does alter it to be one month from the date it was reset. If I reset a password today the passwordexpirationtime becomes 20080823184033Z.

Any ideas?
0
Comment
Question by:Klainn
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
12 Comments
 
LVL 14

Expert Comment

by:agriesser
ID: 21859501
It took me hours to figure out what to do to set the password Expiration from within PHP.

As you can see in the example below, the user account will expire on 12th january 2006.

Here's the code:
// $dateLargeInt='128068956000000000'; // nano seconds (yes, nano seconds) since jan 1st 1601
// $secsAfterADEpoch = $dateLargeInt / (10000000); // seconds since jan 1st 1601
// $ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // unix epoch - AD epoch * number of tropical days * seconds in a day
// $unixTsLastLogon=intval($secsAfterADEpoch-$ADToUnixConvertor); // unix Timestamp version of AD timestamp
// $lastlogon=date("d-m-Y", $unixTsLastLogon); // formatted date
 
$user['accountExpires'] = round(date("U", mktime(0, 0, 0, 12, 1, 2006)) + ADS_TIME_DIFFERENCE) . '0000000';

Open in new window

0
 
LVL 14

Expert Comment

by:agriesser
ID: 21859509
Sorry, I forgot to tell you the defined ADS_TIME_DIFFERENCE, it's:


// Magic time conversion value
define("ADS_TIME_DIFFERENCE",                           11644505404.704);

Open in new window

0
 

Author Comment

by:Klainn
ID: 21859587
Unless I used it wrong, very possible, still no good..

      define("ADS_TIME_DIFFERENCE",11644505404.704);
      $entry["passwordexpirationtime"] = round(date(mktime(0, 0, 0, 12, 1, 2006)) + $ADS_TIME_DIFFERENCE) . '0000000' + "Z";
      $entry["userpassword"] = $userpassword;
      $entry["passwordexpwarned"] = "0";
      $results = ldap_modify($ld, $reset_dn, $entry);

And the results:

Array
(
    [count] => 2
    [0] => Array
        (
            [passwordexpirationtime] => Array
                (
                    [count] => 1
                    [0] => 20080823194109Z
                )
 
            [0] => passwordexpirationtime
            [passwordexpwarned] => Array
                (
                    [count] => 1
                    [0] => 0
                )
 
            [1] => passwordexpwarned
            [userpassword] => Array
                (
                    [count] => 1
                    [0] => {SHA}LUSTo+9rydkjrc4lMNGGp8kFHaY=
                )
 
            [2] => userpassword
            [count] => 3
            [dn] => uid=ldaptest,ou=people,dc=gds,o=lilly.com
        )

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 14

Expert Comment

by:agriesser
ID: 21859645
Well, you really used it wrong :)
ADS_TIME_DIFFERENCE was declared using define(), so no $ in front of ADS_TIME_DIFFERENCE (the variable $ADS_TIME_DIFFERNCE is not declared and therefore returns nothing, so you're missing the time difference itself).

Change

$entry["passwordexpirationtime"] = round(date(mktime(0, 0, 0, 12, 1, 2006)) + $ADS_TIME_DIFFERENCE) . '0000000' + "Z";

to

$entry["passwordexpirationtime"] = round(date(mktime(0, 0, 0, 12, 1, 2006)) + ADS_TIME_DIFFERENCE) . '0000000' + "Z";

BTW: What's the Z here at the end?
0
 

Author Comment

by:Klainn
ID: 21859763
Using the following:
      define("ADS_TIME_DIFFERENCE",11644505404.704);
      $entry["passwordexpirationtime"] = round(date("U", mktime(0, 0, 0, 12, 1, 2006)) + ADS_TIME_DIFFERENCE) . '0000000';


I still get

Array
(
    [count] => 2
    [0] => Array
        (
            [passwordexpirationtime] => Array
                (
                    [count] => 1
                    [0] => 20080823195604Z
                )


It's still not changing the expiration time.
0
 
LVL 14

Expert Comment

by:agriesser
ID: 21859940
Ah, I guess I did not read your question carefully.
You don't want to convert a date into the passwordexpiration date, sorry for that.

Have you tried to set the pwdLastSet option? It should force the user to change the password the next time he logs in...

$entry["pwdLastSet"] = "0"   // or 1, don't know for sure how MS interprets this value.
0
 

Author Comment

by:Klainn
ID: 21860006
pwdLastSet isn't defined on the iplanet we're using. This is iplanet ldap, not microsoft ad.
0
 
LVL 14

Expert Comment

by:agriesser
ID: 21860067
Oh, I assumed it would be Microsoft AD.
So you're saying that when you set the value of passwordexpirationtime to the value it should have, it's not working?

Maybe it's a timing issue... The shell script above makes a "sleep 1" before resetting the value of passwordexpirationdate. Furthermore, the script uses two subsequent ldap replacement calls. Maybe the author of the original script had the same issue as you're currently experiencing and didn't want to comment on it in the code? ;)

Try to add a sleep(1) here too and divide the ldap calls up into two separate calls.
0
 

Author Comment

by:Klainn
ID: 21875621
After looking at it again, I don't believe it's a timing issue. The order of things would suggest that it first changes the expiration time, then the password itself, then the warnings, but it's only changing the second item.

Still looking for a solution if anyone has something.
0
 

Author Comment

by:Klainn
ID: 21875633
Currently how the code looks:

	$ld = ldap_connect($ldap_server) or die("Couldn't connect to Lepton!");
	ldap_set_option($ld, LDAP_OPT_PROTOCOL_VERSION, 3);
	$lbd = ldap_bind($ld,$ldap_username,$ldap_password) or die("Couldn't log into LDAP, verify your username and password.");
	$reset_dn = "uid=".$_POST["user_to_reset"].",ou=people,dc=gds,o=company.com";
	$entry["passwordexpirationtime"] = "19700101000000Z";
	$entry["userpassword"] = $userpassword;
	$entry["passwordexpwarned"] = "0";
	$results = ldap_modify($ld, $reset_dn, $entry);
	ldap_unbind($ld);

Open in new window

0
 
LVL 14

Accepted Solution

by:
agriesser earned 500 total points
ID: 21878543
Erm, no, the script shown above first changes the password, then sleeps for a second. After that, it changes the expiration time and the warning at the same time.

You should try to split it up in two distinct ldap_modify() invocations.
Please do me a favour and try this code and report wheter it works or not.


$ld = ldap_connect($ldap_server) or die("Couldn't connect to Lepton!");
ldap_set_option($ld, LDAP_OPT_PROTOCOL_VERSION, 3);
$lbd = ldap_bind($ld,$ldap_username,$ldap_password) or die("Couldn't log into LDAP, verify your username and password.");
$reset_dn = "uid=".$_POST["user_to_reset"].",ou=people,dc=gds,o=company.com";
$entry["userpassword"] = $userpassword;
$results = ldap_modify($ld, $reset_dn, $entry);
sleep(1);
unset($entry["userpassword"]);
$entry["passwordexpirationtime"] = "19700101000000Z";
$entry["passwordexpwarned"] = "0";
$results = ldap_modify($ld, $reset_dn, $entry);
ldap_unbind($ld);

Open in new window

0
 

Author Closing Comment

by:Klainn
ID: 31470323
Sure enough, that worked.
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Styling your websites can become very complex. Here I'll show how SASS can help you better organize, maintain and reuse your CSS code.
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…
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).
Suggested Courses

762 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