store sambaPasswordHistory
This commit is contained in:
		
							parent
							
								
									cf5132745d
								
							
						
					
					
						commit
						bdae11ff4a
					
				| 
						 | 
					@ -385,7 +385,9 @@ function search_domains($server = null, $suffix = null) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	$ret = array();
 | 
						$ret = array();
 | 
				
			||||||
	$attr = array("DN", "sambaDomainName", "sambaSID", "sambaNextRid", "sambaNextGroupRid",
 | 
						$attr = array("DN", "sambaDomainName", "sambaSID", "sambaNextRid", "sambaNextGroupRid",
 | 
				
			||||||
		"sambaNextUserRid", "sambaAlgorithmicRidBase", 'sambaMinPwdAge', 'sambaMaxPwdAge');
 | 
							"sambaNextUserRid", "sambaAlgorithmicRidBase", 'sambaMinPwdAge', 'sambaMaxPwdAge',
 | 
				
			||||||
 | 
							'sambaPwdHistoryLength'
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
	if ($server == null) {
 | 
						if ($server == null) {
 | 
				
			||||||
		$server = $_SESSION['ldap']->server();
 | 
							$server = $_SESSION['ldap']->server();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -402,6 +404,7 @@ function search_domains($server = null, $suffix = null) {
 | 
				
			||||||
		if (isset($units[$i]['sambaalgorithmicridbase'][0])) $ret[$i]->RIDbase = $units[$i]['sambaalgorithmicridbase'][0];
 | 
							if (isset($units[$i]['sambaalgorithmicridbase'][0])) $ret[$i]->RIDbase = $units[$i]['sambaalgorithmicridbase'][0];
 | 
				
			||||||
		if (isset($units[$i]['sambaminpwdage'][0])) $ret[$i]->minPwdAge = $units[$i]['sambaminpwdage'][0];
 | 
							if (isset($units[$i]['sambaminpwdage'][0])) $ret[$i]->minPwdAge = $units[$i]['sambaminpwdage'][0];
 | 
				
			||||||
		if (isset($units[$i]['sambamaxpwdage'][0])) $ret[$i]->maxPwdAge = $units[$i]['sambamaxpwdage'][0];
 | 
							if (isset($units[$i]['sambamaxpwdage'][0])) $ret[$i]->maxPwdAge = $units[$i]['sambamaxpwdage'][0];
 | 
				
			||||||
 | 
							if (isset($units[$i]['sambapwdhistorylength'][0])) $ret[$i]->pwdHistoryLength = $units[$i]['sambapwdhistorylength'][0];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return $ret;
 | 
						return $ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -439,6 +442,9 @@ class samba3domain {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** seconds after the password must be changed */
 | 
						/** seconds after the password must be changed */
 | 
				
			||||||
	public $maxPwdAge;
 | 
						public $maxPwdAge;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** password history length */
 | 
				
			||||||
 | 
						public $pwdHistoryLength;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@ $Id$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
					  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
				
			||||||
  Copyright (C) 2003 - 2006  Tilo Lutz
 | 
					  Copyright (C) 2003 - 2006  Tilo Lutz
 | 
				
			||||||
                2005 - 2015  Roland Gruber
 | 
					                2005 - 2016  Roland Gruber
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  This program is free software; you can redistribute it and/or modify
 | 
					  This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
  it under the terms of the GNU General Public License as published by
 | 
					  it under the terms of the GNU General Public License as published by
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,7 @@ class sambaSamAccount extends baseModule implements passwordService {
 | 
				
			||||||
			'sambaLogonTime', 'sambaLogoffTime', 'sambaKickoffTime', 'sambaAcctFlags',
 | 
								'sambaLogonTime', 'sambaLogoffTime', 'sambaKickoffTime', 'sambaAcctFlags',
 | 
				
			||||||
			'sambaPwdLastSet', 'displayName', 'sambaHomePath', 'sambaHomeDrive', 'sambaLogonScript', 'sambaProfilePath',
 | 
								'sambaPwdLastSet', 'displayName', 'sambaHomePath', 'sambaHomeDrive', 'sambaLogonScript', 'sambaProfilePath',
 | 
				
			||||||
			'sambaUserWorkstations', 'sambaPrimaryGroupSID', 'sambaDomainName', 'sambaLogonHours', 'sambaMungedDial',
 | 
								'sambaUserWorkstations', 'sambaPrimaryGroupSID', 'sambaDomainName', 'sambaLogonHours', 'sambaMungedDial',
 | 
				
			||||||
			'sambaPwdCanChange', 'sambaPwdMustChange'); // sambaPwdCanChange/sambaPwdMustChange only for extension removal
 | 
								'sambaPasswordHistory', 'sambaPwdCanChange', 'sambaPwdMustChange'); // sambaPwdCanChange/sambaPwdMustChange only for extension removal
 | 
				
			||||||
		// PHP extensions
 | 
							// PHP extensions
 | 
				
			||||||
		$return['extensions'] = array('hash', 'iconv');
 | 
							$return['extensions'] = array('hash', 'iconv');
 | 
				
			||||||
		// profile options
 | 
							// profile options
 | 
				
			||||||
| 
						 | 
					@ -2396,6 +2396,41 @@ class sambaSamAccount extends baseModule implements passwordService {
 | 
				
			||||||
		if ($forcePasswordChange) {
 | 
							if ($forcePasswordChange) {
 | 
				
			||||||
			$this->attributes['sambaPwdLastSet'][0] = '0';
 | 
								$this->attributes['sambaPwdLastSet'][0] = '0';
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							// password history entry
 | 
				
			||||||
 | 
							$sambaDomains = $this->getDomains();
 | 
				
			||||||
 | 
							if (sizeof($sambaDomains) > 0) {
 | 
				
			||||||
 | 
								if (isset($this->attributes['sambaSID'][0]) && $this->attributes['sambaSID'][0] != '') {
 | 
				
			||||||
 | 
									$domainSID = substr($this->attributes['sambaSID'][0], 0, strrpos($this->attributes['sambaSID'][0], "-"));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								$historyLength = 0;
 | 
				
			||||||
 | 
								for ($i = 0; $i < count($sambaDomains); $i++) {
 | 
				
			||||||
 | 
									if (!empty($domainSID)) {
 | 
				
			||||||
 | 
										if (($domainSID == $sambaDomains[$i]->SID) && !empty($sambaDomains[$i]->pwdHistoryLength)) {
 | 
				
			||||||
 | 
											$historyLength = $sambaDomains[$i]->pwdHistoryLength;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									elseif (isset($this->attributes['sambaDomainName'][0]) && ($this->attributes['sambaDomainName'][0]!='')) {
 | 
				
			||||||
 | 
										if (($this->attributes['sambaDomainName'][0] == $sambaDomains[$i]->name) && !empty($sambaDomains[$i]->pwdHistoryLength)) {
 | 
				
			||||||
 | 
											$historyLength = $sambaDomains[$i]->pwdHistoryLength;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!empty($historyLength) && is_numeric($historyLength) && ($historyLength > 0)) {
 | 
				
			||||||
 | 
									if (!empty($this->orig['sambaPasswordHistory'][0])) {
 | 
				
			||||||
 | 
										$this->attributes['sambaPasswordHistory'] = $this->orig['sambaPasswordHistory'];
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										$this->attributes['sambaPasswordHistory'] = array();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									while (sizeof($this->attributes['sambaPasswordHistory']) > ($historyLength - 1)) {
 | 
				
			||||||
 | 
										array_pop($this->attributes['sambaPasswordHistory']);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									$this->attributes['sambaPasswordHistory'][] = sambaSamAccount::createHistoryEntry($password);
 | 
				
			||||||
 | 
									$this->attributes['sambaPasswordHistory'] = array_values($this->attributes['sambaPasswordHistory']);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return array();
 | 
							return array();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2581,6 +2616,41 @@ class sambaSamAccount extends baseModule implements passwordService {
 | 
				
			||||||
		$this->attributes['sambaAcctFlags'][0] = str_replace(']', ' ]', $this->attributes['sambaAcctFlags'][0]);
 | 
							$this->attributes['sambaAcctFlags'][0] = str_replace(']', ' ]', $this->attributes['sambaAcctFlags'][0]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Creates the value to store in sambaPasswordHistory attribute.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param String $password password
 | 
				
			||||||
 | 
						 * @return String value for sambaPasswordHistory
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public static function createHistoryEntry($password) {
 | 
				
			||||||
 | 
							if (empty($password)) {
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							$salt = generateSalt(16);
 | 
				
			||||||
 | 
							$saltHex = bin2hex($salt);
 | 
				
			||||||
 | 
							$md4hash = ntPassword($password);
 | 
				
			||||||
 | 
							$md5hash = md5($salt . hex2bin($md4hash));
 | 
				
			||||||
 | 
							return strtoupper($saltHex . $md5hash);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Checks if the given password matches the history entry.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param String $password password
 | 
				
			||||||
 | 
						 * @param String $historyEntry sambaPasswordHistory entry
 | 
				
			||||||
 | 
						 * @return Boolean entry matches password
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public static function validateHistoryEntry($password, $historyEntry) {
 | 
				
			||||||
 | 
							if (empty($historyEntry) || (strlen($historyEntry) != 64)) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							$salt = hex2bin(substr($historyEntry, 0, 32));
 | 
				
			||||||
 | 
							$hash = substr($historyEntry, 32, 32);
 | 
				
			||||||
 | 
							$md4hash = ntPassword($password);
 | 
				
			||||||
 | 
							$md5hash = md5($salt . hex2bin($md4hash));
 | 
				
			||||||
 | 
							return strtolower($md5hash) == strtolower($hash);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
?>
 | 
					?>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					<?php
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 $Id$
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
				
			||||||
 | 
					 Copyright (C) 2016  Roland Gruber
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					 the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					 (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include_once (dirname ( __FILE__ ) . '/../../../lib/baseModule.inc');
 | 
				
			||||||
 | 
					include_once (dirname ( __FILE__ ) . '/../../../lib/modules.inc');
 | 
				
			||||||
 | 
					include_once (dirname ( __FILE__ ) . '/../../../lib/passwordExpirationJob.inc');
 | 
				
			||||||
 | 
					include_once (dirname ( __FILE__ ) . '/../../../lib/modules/sambaSamAccount.inc');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Checks the shadow expire job.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Roland Gruber
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class SambaSamAccountTest extends PHPUnit_Framework_TestCase {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function testValidateHistoryEntry() {
 | 
				
			||||||
 | 
							$this->assertFalse(sambaSamAccount::validateHistoryEntry("password", ""));
 | 
				
			||||||
 | 
							$this->assertFalse(sambaSamAccount::validateHistoryEntry("password", "123"));
 | 
				
			||||||
 | 
							$this->assertFalse(sambaSamAccount::validateHistoryEntry("password", "1234567890123456789012345678901234567890"));
 | 
				
			||||||
 | 
							$this->assertFalse(sambaSamAccount::validateHistoryEntry("password", "12345678901234567890123456789012"));
 | 
				
			||||||
 | 
							$this->assertTrue(sambaSamAccount::validateHistoryEntry("password", "8E36265C3B44B640CCB365040DE68E5A4BF09D61C23AB4A0CC9D1866E1C69191"));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function testCreateHistoryEntry() {
 | 
				
			||||||
 | 
							$this->assertEquals(sambaSamAccount::createHistoryEntry(""), null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							$password = 'password123';
 | 
				
			||||||
 | 
							$this->assertTrue(sambaSamAccount::validateHistoryEntry($password, sambaSamAccount::createHistoryEntry($password)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					?>
 | 
				
			||||||
		Loading…
	
		Reference in New Issue