expiration date for Windows

This commit is contained in:
Roland Gruber 2015-11-02 20:53:20 +00:00
parent 89421417fe
commit 54a5672bc2
2 changed files with 250 additions and 2 deletions

View File

@ -399,6 +399,10 @@ class shadowAccount extends baseModule implements passwordService {
$this->getAccountContainer()->getAccountModule('sambaSamAccount')->setExpirationDate( $this->getAccountContainer()->getAccountModule('sambaSamAccount')->setExpirationDate(
$_POST['shadowExpire_yea'], $_POST['shadowExpire_mon'], $_POST['shadowExpire_day']); $_POST['shadowExpire_yea'], $_POST['shadowExpire_mon'], $_POST['shadowExpire_day']);
} }
if (isset($_POST['syncWindows']) && ($_POST['syncWindows'] == 'on')) {
$this->getAccountContainer()->getAccountModule('windowsUser')->setExpirationDate(
$_POST['shadowExpire_yea'], $_POST['shadowExpire_mon'], $_POST['shadowExpire_day']);
}
if (isset($_POST['syncHeimdal']) && ($_POST['syncHeimdal'] == 'on')) { if (isset($_POST['syncHeimdal']) && ($_POST['syncHeimdal'] == 'on')) {
$this->getAccountContainer()->getAccountModule('heimdalKerberos')->setExpirationDate( $this->getAccountContainer()->getAccountModule('heimdalKerberos')->setExpirationDate(
$_POST['shadowExpire_yea'], $_POST['shadowExpire_mon'], $_POST['shadowExpire_day']); $_POST['shadowExpire_yea'], $_POST['shadowExpire_mon'], $_POST['shadowExpire_day']);
@ -416,6 +420,10 @@ class shadowAccount extends baseModule implements passwordService {
elseif (isset($_POST['form_subpage_shadowAccount_attributes_del'])) { elseif (isset($_POST['form_subpage_shadowAccount_attributes_del'])) {
unset($this->attributes['shadowExpire']); unset($this->attributes['shadowExpire']);
// sync other modules // sync other modules
if (isset($_POST['syncWindows']) && ($_POST['syncWindows'] == 'on')) {
$this->getAccountContainer()->getAccountModule('windowsUser')->setExpirationDate(
null, null, null);
}
if (isset($_POST['syncSamba']) && ($_POST['syncSamba'] == 'on')) { if (isset($_POST['syncSamba']) && ($_POST['syncSamba'] == 'on')) {
$this->getAccountContainer()->getAccountModule('sambaSamAccount')->setExpirationDate( $this->getAccountContainer()->getAccountModule('sambaSamAccount')->setExpirationDate(
null, null, null); null, null, null);
@ -461,6 +469,9 @@ class shadowAccount extends baseModule implements passwordService {
if ($this->getAccountContainer()->getAccountModule('sambaSamAccount') != null) { if ($this->getAccountContainer()->getAccountModule('sambaSamAccount') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncSamba', false, _('Set also for Samba 3')), true); $return->addElement(new htmlTableExtendedInputCheckbox('syncSamba', false, _('Set also for Samba 3')), true);
} }
if ($this->getAccountContainer()->getAccountModule('windowsUser') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncWindows', false, _('Set also for Windows')), true);
}
if ($this->getAccountContainer()->getAccountModule('heimdalKerberos') != null) { if ($this->getAccountContainer()->getAccountModule('heimdalKerberos') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncHeimdal', false, _('Set also for Kerberos')), true); $return->addElement(new htmlTableExtendedInputCheckbox('syncHeimdal', false, _('Set also for Kerberos')), true);
} }

View File

@ -96,7 +96,7 @@ class windowsUser extends baseModule implements passwordService {
'l', 'mail', 'otherTelephone', 'physicalDeliveryOfficeName', 'postalCode', 'postOfficeBox', 'sn', 'st', 'l', 'mail', 'otherTelephone', 'physicalDeliveryOfficeName', 'postalCode', 'postOfficeBox', 'sn', 'st',
'streetAddress', 'telephoneNumber', 'url', 'wWWHomePage', 'userAccountControl', 'profilePath', 'scriptPath', 'streetAddress', 'telephoneNumber', 'url', 'wWWHomePage', 'userAccountControl', 'profilePath', 'scriptPath',
'pwdLastSet', 'otherMailbox', 'homeDirectory', 'homeDrive', 'msSFU30Name', 'msSFU30NisDomain', 'pwdLastSet', 'pwdLastSet', 'otherMailbox', 'homeDirectory', 'homeDrive', 'msSFU30Name', 'msSFU30NisDomain', 'pwdLastSet',
'lastLogonTimestamp' 'lastLogonTimestamp', 'accountExpires'
); );
// help Entries // help Entries
$return['help'] = array( $return['help'] = array(
@ -266,6 +266,18 @@ class windowsUser extends baseModule implements passwordService {
"Headline" => _('Last login'), 'attr' => 'lastLogonTimestamp', "Headline" => _('Last login'), 'attr' => 'lastLogonTimestamp',
"Text" => _('Time of user\'s last login.') "Text" => _('Time of user\'s last login.')
), ),
'accountExpires' => array(
"Headline" => _('Account expiration date'), 'attr' => 'accountExpires',
"Text" => _('This is the date when the account will expire.')
),
'accountExpiresUpload' => array(
"Headline" => _('Account expiration date'), 'attr' => 'accountExpires',
"Text" => _('This is the date when the account will expire. Format: DD-MM-YYYY')
),
'accountExpiresProfile' => array(
"Headline" => _('Account expiration'), 'attr' => 'accountExpires',
"Text" => _('Number of days after which the account will expire.')
),
); );
// upload fields // upload fields
$return['upload_columns'] = array( $return['upload_columns'] = array(
@ -407,6 +419,12 @@ class windowsUser extends baseModule implements passwordService {
'default' => _('no'), 'default' => _('no'),
'values' => _('yes') . ', ' . _('no') 'values' => _('yes') . ', ' . _('no')
), ),
array(
'name' => 'windowsUser_accountExpires',
'description' => _('Account expiration date'),
'help' => 'accountExpiresUpload',
'example' => _('21-11-2030'),
),
array( array(
'name' => 'windowsUser_requireCard', 'name' => 'windowsUser_requireCard',
'description' => _('Require smartcard'), 'description' => _('Require smartcard'),
@ -490,7 +508,13 @@ class windowsUser extends baseModule implements passwordService {
if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) { if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
$profileContainer->addElement(new htmlTableExtendedInputField(_('NIS domain'), 'windowsUser_msSFU30NisDomain', null, 'msSFU30NisDomain'), true); $profileContainer->addElement(new htmlTableExtendedInputField(_('NIS domain'), 'windowsUser_msSFU30NisDomain', null, 'msSFU30NisDomain'), true);
} }
$profileContainer->addElement(new htmlTableExtendedInputField(_('Account expiration'), 'windowsUser_accountExpires', null, 'accountExpiresProfile'), true);
$return['profile_options'] = $profileContainer; $return['profile_options'] = $profileContainer;
// profile checks
$return['profile_checks']['windowsUser_accountExpires'] = array(
'type' => 'ext_preg',
'regex' => 'digit',
'error_message' => $this->messages['accountExpires'][0]);
// profile mappings // profile mappings
$return['profile_mappings'] = array( $return['profile_mappings'] = array(
'windowsUser_displayName' => 'displayName', 'windowsUser_displayName' => 'displayName',
@ -534,6 +558,7 @@ class windowsUser extends baseModule implements passwordService {
'password' => _('Password'), 'password' => _('Password'),
'homeDrive' => _('Home drive'), 'homeDrive' => _('Home drive'),
'homeDirectory' => _('Home directory'), 'homeDirectory' => _('Home directory'),
'accountExpires' => _('Account expiration date'),
); );
if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) { if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
$return['PDF_fields']['sAMAccountName'] = _('User name (pre W2K)'); $return['PDF_fields']['sAMAccountName'] = _('User name (pre W2K)');
@ -563,7 +588,8 @@ class windowsUser extends baseModule implements passwordService {
'postOfficeBox' => _('Post office box'), 'postOfficeBox' => _('Post office box'),
'postalCode' => _('Postal code'), 'postalCode' => _('Postal code'),
'unicodePwd' => _('Password'), 'unicodePwd' => _('Password'),
'pwdLastSet' => _('Last password change (read-only)') 'pwdLastSet' => _('Last password change (read-only)'),
'accountExpires' => _('Account expiration date (read-only)'),
); );
// possible self service read-only fields // possible self service read-only fields
$return['selfServiceReadOnlyFields'] = array('physicalDeliveryOfficeName', 'telephoneNumber', $return['selfServiceReadOnlyFields'] = array('physicalDeliveryOfficeName', 'telephoneNumber',
@ -638,6 +664,8 @@ class windowsUser extends baseModule implements passwordService {
$this->messages['homeDirectory'][1] = array('ERROR', _('Account %s:') . ' windowsUser_homeDirectory', _('Homedirectory contains invalid characters.')); $this->messages['homeDirectory'][1] = array('ERROR', _('Account %s:') . ' windowsUser_homeDirectory', _('Homedirectory contains invalid characters.'));
$this->messages['msSFU30Name'][0] = array('ERROR', _('NIS name'), _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); $this->messages['msSFU30Name'][0] = array('ERROR', _('NIS name'), _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
$this->messages['msSFU30Name'][1] = array('ERROR', _('Account %s:') . ' windowsUser_msSFU30Name', _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !')); $this->messages['msSFU30Name'][1] = array('ERROR', _('Account %s:') . ' windowsUser_msSFU30Name', _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
$this->messages['accountExpires'][0] = array('ERROR', _('Account expiration'), _('Please enter a number.'));
$this->messages['accountExpires'][1] = array('ERROR', _('Account %s:') . ' windowsUser_accountExpires', _('Please enter a valid date in format DD-MM-YYYY.'));
} }
/** /**
@ -767,6 +795,14 @@ class windowsUser extends baseModule implements passwordService {
// require smartcard // require smartcard
$requireCard = windowsUser::isSmartCardRequired($this->attributes); $requireCard = windowsUser::isSmartCardRequired($this->attributes);
$containerLeft->addElement(new htmlTableExtendedInputCheckbox('requireCard', $requireCard, _("Require smartcard"), 'requireCard'), true); $containerLeft->addElement(new htmlTableExtendedInputCheckbox('requireCard', $requireCard, _("Require smartcard"), 'requireCard'), true);
// account expiration
$containerLeft->addElement(new htmlOutputText(_('Account expiration date')));
$accountExpiresGroup = new htmlGroup();
$accountExpiresGroup->addElement(new htmlOutputText($this->formatAccountExpires()));
$accountExpiresGroup->addElement(new htmlSpacer('5px', null));
$accountExpiresGroup->addElement(new htmlAccountPageButton(get_class($this), 'accountExpires', 'edit', _('Change')));
$containerLeft->addElement($accountExpiresGroup);
$containerLeft->addElement(new htmlHelpLink('accountExpires'), true);
// last password change // last password change
if (!$this->isBooleanConfigOptionSet('windowsUser_hidepwdLastSet')) { if (!$this->isBooleanConfigOptionSet('windowsUser_hidepwdLastSet')) {
$containerLeft->addElement(new htmlOutputText(_('Last password change'))); $containerLeft->addElement(new htmlOutputText(_('Last password change')));
@ -1048,6 +1084,115 @@ class windowsUser extends baseModule implements passwordService {
return $return; return $return;
} }
/**
* This function will create the meta HTML code to show a page to change account expiration.
*
* @return htmlElement meta HTML code
*/
function display_html_accountExpires() {
$return = new htmlTable();
$attr = 'accountExpires';
$text = _('Account expiration date');
$help = "accountExpires";
$datetime = new DateTime('now', getTimeZone());
if (!empty($this->attributes[$attr][0]) && !($this->attributes[$attr][0] == '0')) {
$datetime = $this->getFileTime($this->attributes[$attr][0]);
}
for ( $i=1; $i<=31; $i++ ) $mday[] = $i;
for ( $i=1; $i<=12; $i++ ) $mon[] = $i;
for ( $i=2003; $i<=2050; $i++ ) $year[] = $i;
$return->addElement(new htmlOutputText($text));
$return->addElement(new htmlSelect('expire_day', $mday, array($datetime->format('d'))));
$return->addElement(new htmlSelect('expire_mon', $mon, array($datetime->format('m'))));
$return->addElement(new htmlSelect('expire_yea', $year, array($datetime->format('Y'))));
$return->addElement(new htmlHelpLink($help), true);
if ($this->getAccountContainer()->getAccountModule('shadowAccount') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncShadow', false, _('Set also for Shadow')), true);
}
if ($this->getAccountContainer()->getAccountModule('heimdalKerberos') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncHeimdal', false, _('Set also for Kerberos')), true);
}
if ($this->getAccountContainer()->getAccountModule('mitKerberos') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncMIT', false, _('Set also for Kerberos')), true);
}
if ($this->getAccountContainer()->getAccountModule('mitKerberosStructural') != null) {
$return->addElement(new htmlTableExtendedInputCheckbox('syncMITStructural', false, _('Set also for Kerberos')), true);
}
$return->addElement(new htmlSpacer(null, '10px'), true);
$buttons = new htmlTable();
$buttons->addElement(new htmlAccountPageButton(get_class($this), 'attributes', 'change' . $attr, _('Change')));
if (isset($this->attributes[$attr][0])) {
$buttons->addElement(new htmlAccountPageButton(get_class($this), 'attributes', 'del' . $attr, _('Remove')));
}
$buttons->addElement(new htmlAccountPageButton(get_class($this), 'attributes', 'back' . $attr, _('Cancel')));
$buttons->colspan = 6;
$return->addElement($buttons);
return $return;
}
/**
* Processes user input of the account expiration page.
*
* @return array list of info/error messages
*/
function process_accountExpires() {
$return = array();
// find button name
$buttonName = '';
$postKeys = array_keys($_POST);
for ($i = 0; $i < sizeof($postKeys); $i++) {
if (strpos($postKeys[$i], 'form_subpage_windowsUser_attributes_') !== false) {
$buttonName = $postKeys[$i];
}
}
if (($buttonName == '') || (strpos($buttonName, '_back') !== false)) return array();
$attr = 'accountExpires';
// determine action
if (strpos($buttonName, '_change') !== false) {
// set new time
$this->setExpirationDate($_POST['expire_yea'], $_POST['expire_mon'], $_POST['expire_day']);
// sync other modules
if (isset($_POST['syncShadow']) && ($_POST['syncShadow'] == 'on')) {
$this->getAccountContainer()->getAccountModule('shadowAccount')->setExpirationDate(
$_POST['expire_yea'], $_POST['expire_mon'], $_POST['expire_day']);
}
if (isset($_POST['syncHeimdal']) && ($_POST['syncHeimdal'] == 'on')) {
$this->getAccountContainer()->getAccountModule('heimdalKerberos')->setExpirationDate(
$_POST['expire_yea'], $_POST['expire_mon'], $_POST['expire_day']);
}
if (isset($_POST['syncMIT']) && ($_POST['syncMIT'] == 'on')) {
$this->getAccountContainer()->getAccountModule('mitKerberos')->setExpirationDate(
$_POST['expire_yea'], $_POST['expire_mon'], $_POST['expire_day']);
}
if (isset($_POST['syncMITStructural']) && ($_POST['syncMITStructural'] == 'on')) {
$this->getAccountContainer()->getAccountModule('mitKerberosStructural')->setExpirationDate(
$_POST['expire_yea'], $_POST['expire_mon'], $_POST['expire_day']);
}
}
elseif (strpos($buttonName, '_del') !== false) {
// remove attribute value
unset($this->attributes[$attr]);
// sync other modules
if (isset($_POST['syncShadow']) && ($_POST['syncShadow'] == 'on')) {
$this->getAccountContainer()->getAccountModule('shadowAccount')->setExpirationDate(
null, null, null);
}
if (isset($_POST['syncHeimdal']) && ($_POST['syncHeimdal'] == 'on')) {
$this->getAccountContainer()->getAccountModule('heimdalKerberos')->setExpirationDate(
null, null, null);
}
if (isset($_POST['syncMIT']) && ($_POST['syncMIT'] == 'on')) {
$this->getAccountContainer()->getAccountModule('mitKerberos')->setExpirationDate(
null, null, null);
}
if (isset($_POST['syncMITStructural']) && ($_POST['syncMITStructural'] == 'on')) {
$this->getAccountContainer()->getAccountModule('mitKerberosStructural')->setExpirationDate(
null, null, null);
}
}
return $return;
}
/** /**
* Displays the group selection. * Displays the group selection.
* *
@ -1388,6 +1533,18 @@ class windowsUser extends baseModule implements passwordService {
$this->setIsNeverExpiring($userAccountControlAttr, $booleanOptions[$rawAccounts[$i][$ids['windowsUser_noExpire']]]); $this->setIsNeverExpiring($userAccountControlAttr, $booleanOptions[$rawAccounts[$i][$ids['windowsUser_noExpire']]]);
} }
} }
// account expiration
if (!empty($rawAccounts[$i][$ids['windowsUser_accountExpires']])) {
if (get_preg($rawAccounts[$i][$ids['windowsUser_accountExpires']], 'date')) {
$dateParts = explode('-', $rawAccounts[$i][$ids['windowsUser_accountExpires']]);
$partialAccounts[$i]['accountExpires'] = $this->buildExpirationDate($dateParts[2], $dateParts[1], $dateParts[0]);
}
else {
$errMsg = $this->messages['accountExpires'][1];
array_push($errMsg, array($i));
$errors[] = $errMsg;
}
}
// require smartcard // require smartcard
if ($rawAccounts[$i][$ids['windowsUser_requireCard']] != "") { if ($rawAccounts[$i][$ids['windowsUser_requireCard']] != "") {
if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_requireCard']]])) { if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_requireCard']]])) {
@ -1641,6 +1798,7 @@ class windowsUser extends baseModule implements passwordService {
$noExpire = _('yes'); $noExpire = _('yes');
} }
$this->addPDFKeyValue($return, 'noExpire', _('Password does not expire'), $noExpire); $this->addPDFKeyValue($return, 'noExpire', _('Password does not expire'), $noExpire);
$this->addPDFKeyValue($return, 'accountExpires', _('Account expiration date'), $this->formatAccountExpires());
$requireCard = _('no'); $requireCard = _('no');
if ($this->isSmartCardRequired($this->attributes)) { if ($this->isSmartCardRequired($this->attributes)) {
$requireCard = _('yes'); $requireCard = _('yes');
@ -1721,6 +1879,14 @@ class windowsUser extends baseModule implements passwordService {
if (!empty($profile['windowsUser_otherMailbox'][0])) { if (!empty($profile['windowsUser_otherMailbox'][0])) {
$this->attributes['otherMailbox'] = preg_split('/;[ ]*/', $profile['windowsUser_otherMailbox'][0]); $this->attributes['otherMailbox'] = preg_split('/;[ ]*/', $profile['windowsUser_otherMailbox'][0]);
} }
// account expiration date
if (!empty($profile['windowsUser_accountExpires'][0]) && is_numeric($profile['windowsUser_accountExpires'][0])) {
$numDays = $profile['windowsUser_accountExpires'][0];
$date = new DateTime('now', getTimeZone());
$toAdd = new DateInterval('P' . $numDays . 'D');
$dateTarget = $date->add($toAdd);
$this->setExpirationDate($dateTarget->format('Y'), $dateTarget->format('m'), $dateTarget->format('d'));
}
} }
/** /**
@ -1769,6 +1935,11 @@ class windowsUser extends baseModule implements passwordService {
$row->addLabel(new htmlOutputText($this->getSelfServiceLabel('pwdLastSet', _('Last password change')))); $row->addLabel(new htmlOutputText($this->getSelfServiceLabel('pwdLastSet', _('Last password change'))));
$row->addField(new htmlOutputText($this->formatPwdLastSet($attributes))); $row->addField(new htmlOutputText($this->formatPwdLastSet($attributes)));
$return['pwdLastSet'] = $row; $return['pwdLastSet'] = $row;
// account expiration
$row = new htmlResponsiveRow();
$row->addLabel(new htmlOutputText($this->getSelfServiceLabel('accountExpires', _('Account expiration date'))));
$row->addField(new htmlOutputText($this->formatAccountExpires($attributes)));
$return['accountExpires'] = $row;
return $return; return $return;
} }
@ -2190,6 +2361,23 @@ class windowsUser extends baseModule implements passwordService {
return $this->formatFileTime($this->attributes['lastLogonTimestamp'][0]); return $this->formatFileTime($this->attributes['lastLogonTimestamp'][0]);
} }
/**
* Returns the formatted value for the account expiration date.
*
* @param array $attributes user attributes ($this->attributes if null)
* @return String date or -
*/
private function formatAccountExpires($attributes = null) {
if ($attributes == null) {
$attributes = &$this->attributes;
}
if (empty($attributes['accountExpires'][0]) || ($attributes['accountExpires'][0] == '0')
|| ($attributes['accountExpires'][0] == '9223372036854775807')) {
return ' - ';
}
return $this->formatFileTime($attributes['accountExpires'][0]);
}
/** /**
* Formats a value in file time (100 ns since 1601-01-01). * Formats a value in file time (100 ns since 1601-01-01).
* *
@ -2207,6 +2395,55 @@ class windowsUser extends baseModule implements passwordService {
return $time->format('Y-m-d H:i:s'); return $time->format('Y-m-d H:i:s');
} }
/**
* Returns a value in file time (100 ns since 1601-01-01).
*
* @param integer $value time value as int
* @return DateTime time value
*/
private function getFileTime($value) {
if (empty($value)) {
return null;
}
$seconds = substr($value, 0, -7);
$time = new DateTime('1601-01-01', new DateTimeZone('UTC'));
$time->add(new DateInterval('PT' . $seconds . 'S'));
$time->setTimezone(getTimeZone());
return $time;
}
/**
* Sets the expiration date of this account.
* If all parameters are null the expiration date will be removed.
*
* @param String $year year (e.g. 2040)
* @param String $month month (e.g. 8)
* @param String $day day (e.g. 27)
*/
public function setExpirationDate($year, $month, $day) {
if (($year == null) && ($month == null) && ($day == null)) {
unset($this->attributes['accountExpires']);
return;
}
$this->attributes['accountExpires'][0] = $this->buildExpirationDate($year, $month, $day);
}
/**
* Builds the value for the expiration date.
*
* @param int $year year
* @param int $month month
* @param int $day day
*/
private function buildExpirationDate($year, $month, $day) {
$timeBase = new DateTime('1601-01-01', getTimeZone());
$time = new DateTime("$year-$month-$day", getTimeZone());
$timeDiff = $time->diff($timeBase);
$days = $timeDiff->format('%a');
$seconds = $days * 24 * 3600 - ($time->getOffset());
return $seconds . '0000000';
}
} }
?> ?>