2142 lines
		
	
	
		
			89 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			2142 lines
		
	
	
		
			89 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php
 | |
| /*
 | |
| $Id$
 | |
| 
 | |
|   This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | |
|   Copyright (C) 2013 - 2014  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
 | |
| */
 | |
| 
 | |
| /**
 | |
| * Manages Windows AD (e.g. Samba 4) users.
 | |
| *
 | |
| * @package modules
 | |
| * @author Roland Gruber
 | |
| */
 | |
| 
 | |
| /**
 | |
| * Manages Windows AD (e.g. Samba 4) users.
 | |
| *
 | |
| * @package modules
 | |
| */
 | |
| class windowsUser extends baseModule implements passwordService {
 | |
| 	
 | |
| 	/** initial account flags */
 | |
| 	const DEFAULT_ACCOUNT_CONTROL = 0x00000200;
 | |
| 	/** password never expires */
 | |
| 	const AC_PWD_NEVER_EXPIRES = 0x00010000;
 | |
| 	/** login requires smartcard */
 | |
| 	const AC_SMARTCARD_REQUIRED = 0x00040000;
 | |
| 	/** account is disabled */
 | |
| 	const AC_ACCOUNT_DISABLED = 0x00000002;
 | |
| 	/** currently locked out, read only flag */
 | |
| 	const AC_LOCKED_OUT = 0x00000010;
 | |
| 	
 | |
| 	/** current group of names list */
 | |
| 	private $groupList = array();
 | |
| 	/** original group of names list */
 | |
| 	private $groupList_orig = array();
 | |
| 	/** cache for groups */
 | |
| 	private $groupCache = null;
 | |
| 	/** option for forcing password change, used in postModifyActions */
 | |
| 	private $pwdLastSet = null;
 | |
| 	/** clear text password */
 | |
| 	private $clearTextPassword;
 | |
| 	
 | |
| 	
 | |
| 	/**
 | |
| 	* Returns meta data that is interpreted by parent class
 | |
| 	*
 | |
| 	* @return array array with meta data
 | |
| 	* 
 | |
| 	* @see baseModule::get_metaData()
 | |
| 	*/
 | |
| 	public function get_metaData() {
 | |
| 		$return = array();
 | |
| 		// icon
 | |
| 		$return['icon'] = 'samba.png';
 | |
| 		// manages user accounts
 | |
| 		$return["account_types"] = array('user');
 | |
| 		// this is a base module
 | |
| 		$return["is_base"] = true;
 | |
| 		// PHP extensions
 | |
| 		$return['extensions'] = array('iconv');
 | |
| 		// RDN attribute
 | |
| 		$return["RDN"] = array("cn" => "high");
 | |
| 		// LDAP filter
 | |
| 		$return["ldap_filter"] = array('and' => '(!(objectClass=computer))', 'or' => "(objectClass=user)");
 | |
| 		// alias name
 | |
| 		$return["alias"] = _("Windows");
 | |
| 		// module dependencies
 | |
| 		$return['dependencies'] = array('depends' => array(), 'conflicts' => array());
 | |
| 		// managed object classes
 | |
| 		$return['objectClasses'] = array('user', 'securityPrincipal');
 | |
| 		// managed attributes
 | |
| 		$return['attributes'] = array('userPrincipalName', 'cn', 'sAMAccountName', 'description', 'displayName', 'givenName', 'initials',
 | |
| 			'l', 'mail', 'otherTelephone', 'physicalDeliveryOfficeName', 'postalCode', 'postOfficeBox', 'sn', 'st',
 | |
| 			'streetAddress', 'telephoneNumber', 'url', 'wWWHomePage', 'userAccountControl', 'profilePath', 'scriptPath',
 | |
| 			'pwdLastSet', 'otherMailbox', 'homeDirectory', 'homeDrive', 'msSFU30Name', 'msSFU30NisDomain');
 | |
| 		// help Entries
 | |
| 		$return['help'] = array(
 | |
| 			'cn' => array(
 | |
| 				"Headline" => _('Common name'), 'attr' => 'cn',
 | |
| 				"Text" => _('This is the natural name of the user. If empty, the first and last name or user name is used.')
 | |
| 							 . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'userPrincipalName' => array(
 | |
| 				"Headline" => _('User name'), 'attr' => 'userPrincipalName',
 | |
| 				"Text" => _('Please enter the user\'s name.')
 | |
| 			),
 | |
| 			'userPrincipalNameDomain' => array(
 | |
| 				"Headline" => _('Domain'), 'attr' => 'userPrincipalName',
 | |
| 				"Text" => _('Windows domain name of account.')
 | |
| 			),
 | |
| 			'sAMAccountName' => array(
 | |
| 				"Headline" => _('User name (pre W2K)'), 'attr' => 'sAMAccountName',
 | |
| 				"Text" => _('Please enter the user\'s name.') . ' ' . _('This user name is only used for old Windows versions (e.g. NT4, W98).')
 | |
| 			),
 | |
| 			'description' => array(
 | |
| 				"Headline" => _('Description'), 'attr' => 'description',
 | |
| 				"Text" => _('Please enter a descriptive text for this user.')
 | |
| 			),
 | |
| 			'displayName' => array(
 | |
| 				"Headline" => _('Display name'), 'attr' => 'displayName',
 | |
| 				"Text" => _('This is the account\'s full name on Windows systems.')
 | |
| 							 . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'givenName' => array(
 | |
| 				"Headline" => _('First name'), 'attr' => 'givenName',
 | |
| 				"Text" => _('First name of user. Only letters, - and spaces are allowed.')
 | |
| 			),
 | |
| 			'initials' => array(
 | |
| 				"Headline" => _('Initials'), 'attr' => 'initials',
 | |
| 				"Text" => _('The initials of the user\'s first names.')
 | |
| 			),
 | |
| 			'l' => array(
 | |
| 				"Headline" => _('Location'), 'attr' => 'l',
 | |
| 				"Text" => _('This describes the location of the user.')
 | |
| 			),
 | |
| 			'mail' => array(
 | |
| 				"Headline" => _('Email address'), 'attr' => 'mail',
 | |
| 				"Text" => _('The user\'s email address.') . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'otherTelephone' => array(
 | |
| 				"Headline" => _('Other telephone numbers'), 'attr' => 'otherTelephone',
 | |
| 				"Text" => _('If the user has multiple telephone numbers then please enter it here.')
 | |
| 			),
 | |
| 			'otherTelephoneList' => array(
 | |
| 				"Headline" => _('Other telephone numbers'), 'attr' => 'otherTelephone',
 | |
| 				"Text" => _('If the user has multiple telephone numbers then please enter it here.') . ' ' . _("Multiple values are separated by semicolon.")
 | |
| 			),
 | |
| 			'physicalDeliveryOfficeName' => array(
 | |
| 				"Headline" => _('Office name'), 'attr' => 'physicalDeliveryOfficeName',
 | |
| 				"Text" => _('The office name of the user (e.g. YourCompany, Human Resources).')
 | |
| 			),
 | |
| 			'postalCode' => array(
 | |
| 				"Headline" => _('Postal code'), 'attr' => 'postalCode',
 | |
| 				"Text" => _('The postal code of the user\'s address.')
 | |
| 			),
 | |
| 			'postOfficeBox' => array(
 | |
| 				"Headline" => _('Post office box'), 'attr' => 'postOfficeBox',
 | |
| 				"Text" => _('The post office box of the user\'s address.')
 | |
| 			),
 | |
| 			'sn' => array(
 | |
| 				"Headline" => _('Last name'), 'attr' => 'sn',
 | |
| 				"Text" => _('Last name of user. Only letters, - and spaces are allowed.')
 | |
| 			),
 | |
| 			'st' => array(
 | |
| 				"Headline" => _('State'), 'attr' => 'st',
 | |
| 				"Text" => _('The state where the user resides or works.')
 | |
| 			),
 | |
| 			'streetAddress' => array(
 | |
| 				"Headline" => _('Street'), 'attr' => 'streetAddress',
 | |
| 				"Text" => _('The street name of the user\'s address.')
 | |
| 			),
 | |
| 			'telephoneNumber' => array(
 | |
| 				"Headline" => _('Telephone number'), 'attr' => 'telephoneNumber',
 | |
| 				"Text" => _('The user\'s telephone number.')
 | |
| 			),
 | |
| 			'url' => array(
 | |
| 				"Headline" => _('Other web sites'), 'attr' => 'url',
 | |
| 				"Text" => _('Here you can enter additional web sites for the user.')
 | |
| 			),
 | |
| 			'urlList' => array(
 | |
| 				"Headline" => _('Other web sites'), 'attr' => 'url',
 | |
| 				"Text" => _('Here you can enter additional web sites for the user.') . ' ' . _("Multiple values are separated by semicolon.")
 | |
| 			),
 | |
| 			'wWWHomePage' => array(
 | |
| 				"Headline" => _('Web site'), 'attr' => 'wWWHomePage',
 | |
| 				"Text" => _('The user\'s web site (e.g. http://www.company.com).')
 | |
| 			),
 | |
| 			"deactivated" => array(
 | |
| 				"Headline" => _("Account is deactivated"),
 | |
| 				"Text" => _("If checked then the account will be deactivated.")),
 | |
| 			"locked" => array(
 | |
| 				"Headline" => _("Account is locked"),
 | |
| 				"Text" => _("If checked then the account is locked. You may only unlock accounts but not lock them.")),
 | |
| 			"noExpire" => array(
 | |
| 				"Headline" => _("Password does not expire"),
 | |
| 				"Text" => _("If checked password does not expire.")),
 | |
| 			"requireCard" => array(
 | |
| 				"Headline" => _("Require smartcard"),
 | |
| 				"Text" => _("The user must log on using a smart card.")),
 | |
| 			"profilePath" => array(
 | |
| 				"Headline" => _("Profile path"), 'attr' => 'profilePath',
 | |
| 				"Text" => _('Path of the user profile (UNC-path, e.g. \\\\server\\share\\user). $user is replaced with user name.'). ' '. _("Can be left empty.")
 | |
| 							 . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			"scriptPath" => array(
 | |
| 				"Headline" => _("Logon script"), 'attr' => 'scriptPath',
 | |
| 				"Text" => _('File name and path relative to netlogon-share which should be executed on logon. $user is replaced with user name.'). ' '. _("Can be left empty.")
 | |
| 							  . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			"pwdMustChange" => array (
 | |
| 				"Headline" => _("Password change at next login"),
 | |
| 				"Text" => _("If you set this option then the user has to change his password at the next login.")),
 | |
| 			"groups" => array (
 | |
| 				"Headline" => _("Groups"),
 | |
| 				"Text" => _("Hold the CTRL-key to (de)select multiple groups.")),
 | |
| 			"groupsUpload" => array (
 | |
| 				"Headline" => _("Groups"),
 | |
| 				"Text" => _("The groups for this account. You can insert a group name or DN.") . ' ' . _("Multiple values are separated by semicolon.")),
 | |
| 			'password' => array(
 | |
| 					"Headline" => _("Password"),
 | |
| 					"Text" => _("Please enter the password which you want to set for this account.")
 | |
| 			),
 | |
| 			'otherMailbox' => array(
 | |
| 				"Headline" => _("Email alias"), 'attr' => 'otherMailbox',
 | |
| 				"Text" => _("Email alias for this account.") . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'otherMailboxList' => array(
 | |
| 				"Headline" => _("Email alias"), 'attr' => 'otherMailbox',
 | |
| 				"Text" => _("Email alias for this account.") . ' ' . _("Multiple values are separated by semicolon.")
 | |
| 							 . ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'hiddenOptions' => array(
 | |
| 				"Headline" => _("Hidden options"),
 | |
| 				"Text" => _("The selected options will not be managed inside LAM. You can use this to reduce the number of displayed input fields.")
 | |
| 			),
 | |
| 			'domains' => array(
 | |
| 				"Headline" => _('Domains'),
 | |
| 				"Text" => _('Please enter a list of Windows domains that can be selected for your user accounts.')
 | |
| 			),
 | |
| 			"homeDrive" => array(
 | |
| 				"Headline" => _("Home drive"), 'attr' => 'homeDrive',
 | |
| 				"Text" => _("The home directory will be connected under this drive letter.")),
 | |
| 			"homeDirectory" => array(
 | |
| 				"Headline" => _("Home directory"), 'attr' => 'homeDirectory',
 | |
| 				"Text" => _('UNC-path (\\\\server\\share\) of home directory. If no home drive is set then this directory must start with a drive letter (e.g. "c:\dir\user").')
 | |
| 							. ' ' . _('You can use "$user", "$firstname" and "$lastname" as wildcards for user name, first and last name.')
 | |
| 			),
 | |
| 			'msSFU30Name' => array(
 | |
| 				"Headline" => _('NIS name'), 'attr' => 'msSFU30Name',
 | |
| 				"Text" => _('User name for NIS.')
 | |
| 			),
 | |
| 			'msSFU30NisDomain' => array(
 | |
| 				"Headline" => _('NIS domain'), 'attr' => 'msSFU30NisDomain',
 | |
| 				"Text" => _('NIS domain name.')
 | |
| 			),
 | |
| 		);
 | |
| 		// upload fields
 | |
| 		$return['upload_columns'] = array(
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_userPrincipalName',
 | |
| 				'description' => _('User name'),
 | |
| 				'help' => 'userPrincipalName',
 | |
| 				'example' => _('smiller'),
 | |
| 				'required' => true,
 | |
| 				'unique' => true,
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_password',
 | |
| 				'description' => _('Password'),
 | |
| 				'help' => 'password',
 | |
| 				'example' => _('secret'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_firstName',
 | |
| 				'description' => _('First name'),
 | |
| 				'help' => 'givenName',
 | |
| 				'example' => _('Steve'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_lastName',
 | |
| 				'description' => _('Last name'),
 | |
| 				'help' => 'sn',
 | |
| 				'example' => _('Miller'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_cn',
 | |
| 				'description' => _('Common name'),
 | |
| 				'help' => 'cn',
 | |
| 				'example' => _('Steve Miller'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_displayName',
 | |
| 				'description' => _('Display name'),
 | |
| 				'help' => 'displayName',
 | |
| 				'example' => _('Steve Miller'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_initials',
 | |
| 				'description' => _('Initials'),
 | |
| 				'help' => 'initials',
 | |
| 				'example' => _('S.M.'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_description',
 | |
| 				'description' => _('Description'),
 | |
| 				'help' => 'description',
 | |
| 				'example' => _('Temp, contract till December'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_streetAddress',
 | |
| 				'description' => _('Street'),
 | |
| 				'help' => 'streetAddress',
 | |
| 				'example' => _('Mystreetname 42'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_postOfficeBox',
 | |
| 				'description' => _('Post office box'),
 | |
| 				'help' => 'postOfficeBox',
 | |
| 				'example' => _('12345'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_postalCode',
 | |
| 				'description' => _('Postal code'),
 | |
| 				'help' => 'postalCode',
 | |
| 				'example' => _('GB-12345'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_l',
 | |
| 				'description' => _('Location'),
 | |
| 				'help' => 'l',
 | |
| 				'example' => _('MyCity'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_state',
 | |
| 				'description' => _('State'),
 | |
| 				'help' => 'st',
 | |
| 				'example' => _('New York'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_officeName',
 | |
| 				'description' => _('Office name'),
 | |
| 				'help' => 'physicalDeliveryOfficeName',
 | |
| 				'example' => _('YourCompany'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_mail',
 | |
| 				'description' => _('Email address'),
 | |
| 				'help' => 'mail',
 | |
| 				'example' => _('user@company.com'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_otherMailbox',
 | |
| 				'description' => _('Email alias'),
 | |
| 				'help' => 'otherMailboxList',
 | |
| 				'example' => _('user@company.com'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_telephoneNumber',
 | |
| 				'description' => _('Telephone number'),
 | |
| 				'help' => 'telephoneNumber',
 | |
| 				'example' => _('123-124-1234'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_otherTelephone',
 | |
| 				'description' => _('Other telephone numbers'),
 | |
| 				'help' => 'otherTelephoneList',
 | |
| 				'example' => _('123-124-1234'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_webSite',
 | |
| 				'description' => _('Web site'),
 | |
| 				'help' => 'wWWHomePage',
 | |
| 				'example' => _('http://www.company.com'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_otherWebSites',
 | |
| 				'description' => _('Other web sites'),
 | |
| 				'help' => 'urlList',
 | |
| 				'example' => _('http://www.company.com'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_deactivated',
 | |
| 				'description' => _('Account is deactivated'),
 | |
| 				'help' => 'deactivated',
 | |
| 				'example' => _('no'),
 | |
| 				'default' => _('no'),
 | |
| 				'values' => _('yes') . ', ' . _('no')
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_noExpire',
 | |
| 				'description' => _('Password does not expire'),
 | |
| 				'help' => 'noExpire',
 | |
| 				'example' => _('no'),
 | |
| 				'default' => _('no'),
 | |
| 				'values' => _('yes') . ', ' . _('no')
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_requireCard',
 | |
| 				'description' => _('Require smartcard'),
 | |
| 				'help' => 'requireCard',
 | |
| 				'example' => _('no'),
 | |
| 				'default' => _('no'),
 | |
| 				'values' => _('yes') . ', ' . _('no')
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_pwdMustChange',
 | |
| 				'description' => _('Password change at next login'),
 | |
| 				'help' => 'pwdMustChange',
 | |
| 				'example' => _('no'),
 | |
| 				'default' => _('no'),
 | |
| 				'values' => _('yes') . ', ' . _('no')
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_profilePath',
 | |
| 				'description' => _('Profile path'),
 | |
| 				'help' => 'profilePath',
 | |
| 				'example' => _('\\\\server\\profiles\\smiller'),
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_scriptPath',
 | |
| 				'description' => _('Logon script'),
 | |
| 				'help' => 'scriptPath',
 | |
| 				'example' => 'logon.bat',
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_homeDrive',
 | |
| 				'description' => _('Home drive'),
 | |
| 				'help' => 'homeDrive',
 | |
| 				'example' => 'K:'
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_homeDirectory',
 | |
| 				'description' => _('Home directory'),
 | |
| 				'help' => 'homeDirectory',
 | |
| 				'example' => _('\\\\server\\homes\\smiller')
 | |
| 			),
 | |
| 			array(
 | |
| 				'name' => 'windowsUser_groups',
 | |
| 				'description' => _('Groups'),
 | |
| 				'help' => 'groupsUpload',
 | |
| 			),
 | |
| 		);
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
 | |
| 			$return['upload_columns'][] = array(
 | |
| 				'name' => 'windowsUser_sAMAccountName',
 | |
| 				'description' => _('User name (pre W2K)'),
 | |
| 				'help' => 'sAMAccountName',
 | |
| 				'example' => _('smiller'),
 | |
| 				'unique' => true,
 | |
| 			);
 | |
| 		}
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 			$return['upload_columns'][] = array(
 | |
| 				'name' => 'windowsUser_msSFU30Name',
 | |
| 				'description' => _('NIS name'),
 | |
| 				'help' => 'msSFU30Name',
 | |
| 				'example' => _('smiller'),
 | |
| 			);
 | |
| 		}
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 			$return['upload_columns'][] = array(
 | |
| 				'name' => 'windowsUser_msSFU30NisDomain',
 | |
| 				'description' => _('NIS domain'),
 | |
| 				'help' => 'msSFU30NisDomain',
 | |
| 				'example' => _('domain'),
 | |
| 			);
 | |
| 		}
 | |
| 		// profile options
 | |
| 		$profileContainer = new htmlTable();
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Common name'), 'windowsUser_cn', null, 'cn'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Display name'), 'windowsUser_displayName', null, 'displayName'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Email address'), 'windowsUser_mail', null, 'mail'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Email alias'), 'windowsUser_otherMailbox', null, 'otherMailboxList'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Logon script'), 'windowsUser_scriptPath', null, 'scriptPath'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Profile path'), 'windowsUser_profilePath', null, 'profilePath'), true);
 | |
| 		$profileContainer->addElement(new htmlTableExtendedInputField(_('Home directory'), 'windowsUser_homeDirectory', null, 'homeDirectory'), true);
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 			$profileContainer->addElement(new htmlTableExtendedInputField(_('NIS domain'), 'windowsUser_msSFU30NisDomain', null, 'msSFU30NisDomain'), true);
 | |
| 		}
 | |
| 		$return['profile_options'] = $profileContainer;
 | |
| 		// profile mappings
 | |
| 		$return['profile_mappings'] = array(
 | |
| 			'windowsUser_displayName' => 'displayName',
 | |
| 			'windowsUser_cn' => 'cn',
 | |
| 			'windowsUser_mail' => 'mail',
 | |
| 			'windowsUser_scriptPath' => 'scriptPath',
 | |
| 			'windowsUser_profilePath' => 'profilePath',
 | |
| 			'windowsUser_homeDirectory' => 'homeDirectory',
 | |
| 		);
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 			$return['profile_mappings']['windowsUser_msSFU30NisDomain'] = 'msSFU30NisDomain';
 | |
| 		}
 | |
| 		// available PDF fields
 | |
| 		$return['PDF_fields'] = array(
 | |
| 			'userPrincipalName' => _('User name'),
 | |
| 			'cn' => _('Common name'),
 | |
| 			'description' => _('Description'),
 | |
| 			'displayName' => _('Display name'),
 | |
| 			'givenName' => _('First name'),
 | |
| 			'initials' => _('Initials'),
 | |
| 			'l' => _('Location'),
 | |
| 			'mail' => _('Email address'),
 | |
| 			'otherMailbox' => _('Email alias'),
 | |
| 			'otherTelephone' => _('Other telephone numbers'),
 | |
| 			'physicalDeliveryOfficeName' => _('Office name'),
 | |
| 			'postalCode' => _('Postal code'),
 | |
| 			'postOfficeBox' => _('Post office box'),
 | |
| 			'sn' => _('Last name'),
 | |
| 			'st' => _('State'),
 | |
| 			'streetAddress' => _('Street'),
 | |
| 			'telephoneNumber' => _('Telephone number'),
 | |
| 			'url' => _('Other web sites'),
 | |
| 			'wWWHomePage' => _('Web site'),
 | |
| 			'deactivated' => _('Account is deactivated'),
 | |
| 			'noExpire' => _('Password does not expire'),
 | |
| 			'requireCard' => _('Require smartcard'),
 | |
| 			'profilePath' => _('Profile path'),
 | |
| 			'scriptPath' => _('Logon script'),
 | |
| 			'pwdMustChange' => _('Password change at next login'),
 | |
| 			'groups' => _('Groups'),
 | |
| 			'password' => _('Password'),
 | |
| 			'homeDrive' => _('Home drive'),
 | |
| 			'homeDirectory' => _('Home directory'),
 | |
| 		);
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
 | |
| 			$return['PDF_fields']['sAMAccountName'] = _('User name (pre W2K)');
 | |
| 		}
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 			$return['PDF_fields']['msSFU30Name'] = _('NIS name');
 | |
| 		}
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 			$return['PDF_fields']['msSFU30NisDomain'] = _('NIS domain');
 | |
| 		}
 | |
| 		// self service search attributes
 | |
| 		$return['selfServiceSearchAttributes'] = array('sAMAccountName');
 | |
| 		// self service field settings
 | |
| 		$return['selfServiceFieldSettings'] = array(
 | |
| 			'physicalDeliveryOfficeName' => _('Office name'),
 | |
| 			'telephoneNumber' => _('Telephone number'),
 | |
| 			'wWWHomePage' => _('Web site'),
 | |
| 			'streetAddress' => _('Street'),
 | |
| 			'st' => _('State'),
 | |
| 			'l' => _('Location'),
 | |
| 			'postOfficeBox' => _('Post office box'),
 | |
| 			'postalCode' => _('Postal code'),
 | |
| 			'unicodePwd' => _('Password')
 | |
| 		);
 | |
| 		// possible self service read-only fields
 | |
| 		$return['selfServiceReadOnlyFields'] = array('physicalDeliveryOfficeName', 'telephoneNumber',
 | |
| 			'wWWHomePage', 'streetAddress', 'st', 'l', 'postOfficeBox', 'postalCode');
 | |
| 		// configuration options
 | |
| 		$configContainer = new htmlTable();
 | |
| 		$configContainerHead = new htmlTable();
 | |
| 		$configContainerHead->addElement(new htmlTableExtendedInputTextarea('windowsUser_domains', '', 30, 3, _('Domains'), 'domains'));
 | |
| 		$configContainer->addElement($configContainerHead, true);
 | |
| 		$configContainer->addVerticalSpace('10px');
 | |
| 		$configHiddenGroup = new htmlGroup();
 | |
| 		$configHiddenGroup->addElement(new htmlOutputText(_('Hidden options')));
 | |
| 		$configHiddenGroup->addElement(new htmlHelpLink('hiddenOptions'));
 | |
| 		$configContainer->addElement($configHiddenGroup, true);
 | |
| 		$configContainerOptions = new htmlTable();
 | |
| 		$configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidesAMAccountName', true, _('User name (pre W2K)'), null, false));
 | |
| 		$configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidemsSFU30Name', true, _('NIS name'), null, false));
 | |
| 		$configContainerOptions->addElement(new htmlTableExtendedInputCheckbox('windowsUser_hidemsSFU30NisDomain', true, _('NIS domain'), null, false));
 | |
| 		$configContainer->addElement($configContainerOptions, true);
 | |
| 		$return['config_options']['all'] = $configContainer;
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* Initializes the module after it became part of an accountContainer
 | |
| 	*
 | |
| 	* @param string $base the name of the accountContainer object ($_SESSION[$base])
 | |
| 	*/
 | |
| 	function init($base) {
 | |
| 		// call parent init
 | |
| 		parent::init($base);
 | |
| 		$this->groupList = array();
 | |
| 		$this->groupList_orig = array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* This function fills the $messages variable with output messages from this module.
 | |
| 	*/
 | |
| 	public function load_Messages() {
 | |
| 		$this->messages['userPrincipalName'][0] = array('ERROR', _('User name'), _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
 | |
| 		$this->messages['userPrincipalName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_userPrincipalName', _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
 | |
| 		$this->messages['cn'][0] = array('ERROR', _('Common name'), _('Please enter a valid common name!'));
 | |
| 		$this->messages['cn'][1] = array('ERROR', _('Account %s:') . ' windowsUser_cn', _('Please enter a valid common name!'));
 | |
| 		$this->messages['sAMAccountName'][0] = array('ERROR', _('User name (pre W2K)'), _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
 | |
| 		$this->messages['sAMAccountName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_sAMAccountName', _('User name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
 | |
| 		$this->messages['displayName'][0] = array('ERROR', _('Display name'), _('Please enter a valid display name!'));
 | |
| 		$this->messages['displayName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_displayName', _('Please enter a valid display name!'));
 | |
| 		$this->messages['givenName'][0] = array('ERROR', _('First name'), _('First name contains invalid characters!'));
 | |
| 		$this->messages['givenName'][1] = array('ERROR', _('Account %s:') . ' windowsUser_givenName', _('First name contains invalid characters!'));
 | |
| 		$this->messages['sn'][0] = array('ERROR', _('Last name'), _('Last name contains invalid characters or is empty!'));
 | |
| 		$this->messages['sn'][1] = array('ERROR', _('Account %s:') . ' windowsUser_sn', _('Last name contains invalid characters or is empty!'));
 | |
| 		$this->messages['telephoneNumber'][0] = array('ERROR', _('Telephone number'), _('Please enter a valid telephone number!'));
 | |
| 		$this->messages['telephoneNumber'][1] = array('ERROR', _('Account %s:') . ' windowsUser_telephone', _('Please enter a valid telephone number!'));
 | |
| 		$this->messages['otherTelephone'][0] = array('ERROR', _('Other telephone numbers'), _('Please enter a valid telephone number!'));
 | |
| 		$this->messages['otherTelephone'][1] = array('ERROR', _('Account %s:') . ' windowsUser_otherTelephone', _('Please enter a valid telephone number!'));
 | |
| 		$this->messages['postalCode'][0] = array('ERROR', _('Postal code'), _('Please enter a valid postal code!'));
 | |
| 		$this->messages['postalCode'][1] = array('ERROR', _('Account %s:') . ' windowsUser_postalCode', _('Please enter a valid postal code!'));
 | |
| 		$this->messages['mail'][0] = array('ERROR', _('Email address'), _('Please enter a valid email address!'));
 | |
| 		$this->messages['mail'][1] = array('ERROR', _('Account %s:') . ' windowsUser_mail', _('Please enter a valid email address!'));
 | |
| 		$this->messages['otherMailbox'][0] = array('ERROR', _('Email alias'), _('Email alias is invalid!'));
 | |
| 		$this->messages['otherMailbox'][1] = array('ERROR', _('Account %s:') . ' windowsUser_otherMailbox', _('Email alias is invalid!'));
 | |
| 		$this->messages['profilePath'][0] = array('ERROR', _('Profile path'), _('Profile path is invalid!'));
 | |
| 		$this->messages['profilePath'][1] = array('ERROR', _('Account %s:') . ' windowsUser_profilePath', _('Profile path is invalid!'));
 | |
| 		$this->messages['scriptPath'][0] = array('ERROR', _('Logon script'), _('Logon script is invalid!'));
 | |
| 		$this->messages['scriptPath'][1] = array('ERROR', _('Account %s:') . ' windowsUser_scriptPath', _('Logon script is invalid!'));
 | |
| 		$this->messages['unicodePwd'][0] = array('ERROR', _('Password'), _('Please enter the same password in both password fields.'));
 | |
| 		$this->messages['unicodePwd'][1] = array('ERROR', _('Password'), _('Password contains invalid characters. Valid characters are:') . ' a-z, A-Z, 0-9 and #*,.;:_-+!%&/|?{[()]}=@$ §°!');
 | |
| 		$this->messages['homeDrive'][0] = array('ERROR', _('Account %s:') . ' windowsUser_homeDrive', _('Please enter a valid drive letter.'));
 | |
| 		$this->messages['homeDirectory'][0] = array('ERROR', _('Home directory'), _('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'][1] = array('ERROR', _('Account %s:') . ' windowsUser_msSFU30Name', _('NIS name contains invalid characters. Valid characters are: a-z, A-Z, 0-9 and .-_ !'));
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * This function loads all needed LDAP attributes.
 | |
| 	 *
 | |
| 	 * @param array $attr list of attributes
 | |
| 	 */
 | |
| 	function load_attributes($attr) {
 | |
| 		parent::load_attributes($attr);
 | |
| 		// get group memberships
 | |
| 		$groupList = searchLDAPByAttribute('member', $this->getAccountContainer()->dn_orig, 'group', array('dn'), array('group'));
 | |
| 		$this->groupList_orig = array();
 | |
| 		for ($i = 0; $i < sizeof($groupList); $i++) {
 | |
| 			$this->groupList_orig[] = $groupList[$i]['dn'];
 | |
| 		}
 | |
| 		$this->groupList_orig = array_values(array_unique($this->groupList_orig));
 | |
| 		$this->groupList = $this->groupList_orig;
 | |
| 	}
 | |
| 
 | |
| 	
 | |
| 	
 | |
| 	/**
 | |
| 	* Returns a list of modifications which have to be made to the LDAP account.
 | |
| 	*
 | |
| 	* @return array list of modifications
 | |
| 	* <br>This function returns an array with 3 entries:
 | |
| 	* <br>array( DN1 ('add' => array($attr), 'remove' => array($attr), 'modify' => array($attr)), DN2 .... )
 | |
| 	* <br>DN is the DN to change. It may be possible to change several DNs (e.g. create a new user and add him to some groups via attribute memberUid)
 | |
| 	* <br>"add" are attributes which have to be added to LDAP entry
 | |
| 	* <br>"remove" are attributes which have to be removed from LDAP entry
 | |
| 	* <br>"modify" are attributes which have to been modified in LDAP entry
 | |
| 	* <br>"info" are values with informational value (e.g. to be used later by pre/postModify actions)
 | |
| 	*/
 | |
| 	public function save_attributes() {
 | |
| 		$return = parent::save_attributes();
 | |
| 		// add information about clear text password and password status change
 | |
| 		$return[$this->getAccountContainer()->dn_orig]['info']['userPasswordClearText'][0] = $this->clearTextPassword;
 | |
| 		return $return;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns the HTML meta data for the main account page.
 | |
| 	 * 
 | |
| 	 * @return htmlElement HTML meta data
 | |
| 	 */
 | |
| 	public function display_html_attributes() {
 | |
| 		$containerLeft = new htmlTable();
 | |
| 		$containerLeft->alignment = htmlElement::ALIGN_TOP;
 | |
| 		if ($this->getAccountContainer()->isNewAccount && !isset($this->attributes['userAccountControl'][0])) {
 | |
| 			$this->attributes['userAccountControl'][0] = windowsUser::DEFAULT_ACCOUNT_CONTROL;
 | |
| 		}
 | |
| 		$containerLeft->addElement(new htmlSubTitle(_('General')), true);
 | |
| 		// user name
 | |
| 		$userPrincipalName = '';
 | |
| 		$userPrincipalNameDomain = '';
 | |
| 		$domains = $this->getDomains();
 | |
| 		$domains[] = '';
 | |
| 		if (!empty($this->attributes['userPrincipalName'][0])) {
 | |
| 			$parts = explode('@', $this->attributes['userPrincipalName'][0]);
 | |
| 			$userPrincipalName = $parts[0];
 | |
| 			if (!empty($parts[1])) {
 | |
| 				$userPrincipalNameDomain = $parts[1];
 | |
| 				if (!in_array($userPrincipalNameDomain, $domains)) {
 | |
| 					$domains[] = $userPrincipalNameDomain;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		$userPrincipalNameLabel = new htmlOutputText(_('User name'));
 | |
| 		$userPrincipalNameLabel->setMarkAsRequired(true);
 | |
| 		$containerLeft->addElement($userPrincipalNameLabel);
 | |
| 		$userPrincipalNameGroup = new htmlGroup();
 | |
| 		$userPrincipalNameGroup->addElement(new htmlInputField('userPrincipalName', $userPrincipalName, '15'));
 | |
| 		$userPrincipalNameGroup->addElement(new htmlSelect('userPrincipalNameDomain', $domains, array($userPrincipalNameDomain)));
 | |
| 		$containerLeft->addElement($userPrincipalNameGroup);
 | |
| 		$containerLeft->addElement(new htmlHelpLink('userPrincipalName'), true);
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
 | |
| 			$this->addSimpleInputTextField($containerLeft, 'sAMAccountName', _('User name (pre W2K)'));
 | |
| 		}
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'givenName', _('First name'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'sn', _('Last name'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'cn', _('Common name'), true);
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'displayName', _('Display name'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'initials', _('Initials'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'description', _('Description'));
 | |
| 
 | |
| 		$containerLeft->addElement(new htmlSubTitle(_('Address')), true);
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'streetAddress', _('Street'), false, 20, true);
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'postOfficeBox', _('Post office box'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'postalCode', _('Postal code'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'l', _('Location'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'st', _('State'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'physicalDeliveryOfficeName', _('Office name'));
 | |
| 
 | |
| 		$containerLeft->addElement(new htmlSubTitle(_('Contact data')), true);
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'mail', _('Email address'));
 | |
| 		$this->addMultiValueInputTextField($containerLeft, 'otherMailbox', _('Email alias'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'telephoneNumber', _('Telephone number'));
 | |
| 		$this->addMultiValueInputTextField($containerLeft, 'otherTelephone', _('Other telephone numbers'));
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'wWWHomePage', _('Web site'));
 | |
| 		$this->addMultiValueInputTextField($containerLeft, 'url', _('Other web sites'));
 | |
| 		
 | |
| 		$containerLeft->addElement(new htmlSubTitle(_('Options')), true);
 | |
| 		// locked out
 | |
| 		$containerLeft->addElement(new htmlOutputText(_("Account is locked")));
 | |
| 		$lockedOut = windowsUser::isLockedOut($this->attributes);
 | |
| 		$lockedOutCheckbox = new htmlInputCheckbox('lockedOut', $lockedOut);
 | |
| 		$lockedOutCheckbox->setIsEnabled(false);
 | |
| 		$lockedOutGroup = new htmlGroup();
 | |
| 		$lockedOutGroup->addElement($lockedOutCheckbox);
 | |
| 		if ($lockedOut) {
 | |
| 			$lockedOutGroup->addElement(new htmlButton('unlock', _('Unlock')));
 | |
| 		}
 | |
| 		$containerLeft->addElement($lockedOutGroup);
 | |
| 		$containerLeft->addElement(new htmlHelpLink('locked'), true);
 | |
| 		// password change required
 | |
| 		$pwdMustChange = false;
 | |
| 		if (isset($this->attributes['pwdLastSet'][0]) && ($this->attributes['pwdLastSet'][0] === '0')) {
 | |
| 			$pwdMustChange = true;
 | |
| 		}
 | |
| 		$containerLeft->addElement(new htmlTableExtendedInputCheckbox('forcePasswordChangeOption', $pwdMustChange, _("User must change password"), 'pwdMustChange'), true);
 | |
| 		// deactivated
 | |
| 		$deactivated = windowsUser::isDeactivated($this->attributes);
 | |
| 		$containerLeft->addElement(new htmlTableExtendedInputCheckbox('deactivated', $deactivated, _("Account is deactivated"), 'deactivated'), true);
 | |
| 		// password does not expire
 | |
| 		$noExpire = windowsUser::isNeverExpiring($this->attributes);
 | |
| 		$containerLeft->addElement(new htmlTableExtendedInputCheckbox('noExpire', $noExpire, _("Password does not expire"), 'noExpire'), true);
 | |
| 		// require smartcard
 | |
| 		$requireCard = windowsUser::isSmartCardRequired($this->attributes);
 | |
| 		$containerLeft->addElement(new htmlTableExtendedInputCheckbox('requireCard', $requireCard, _("Require smartcard"), 'requireCard'), true);
 | |
| 		
 | |
| 		$containerLeft->addElement(new htmlSubTitle(_('User profile')), true);
 | |
| 		// profile path
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'profilePath', _('Profile path'));
 | |
| 		// logon script
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'scriptPath', _('Logon script'));
 | |
| 		// home drive
 | |
| 		$drives = array('-');
 | |
| 		for ($i=90; $i>67; $i--) $drives[] = chr($i) . ':';
 | |
| 		if (!empty($this->attributes['homeDrive'][0])) {
 | |
| 			$selected = array(strtoupper($this->attributes['homeDrive'][0]));
 | |
| 		}
 | |
| 		else {
 | |
| 			$selected = array('-');
 | |
| 		}
 | |
| 		$containerLeft->addElement(new htmlTableExtendedSelect('homeDrive', $drives, $selected, _('Home drive'), 'homeDrive'), true);
 | |
| 		// home directory
 | |
| 		$this->addSimpleInputTextField($containerLeft, 'homeDirectory', _('Home directory'), true);
 | |
| 		
 | |
| 		// NIS attributes
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true) || !$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 			$containerLeft->addElement(new htmlSubTitle(_('NIS')), true);
 | |
| 			if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 				$this->addSimpleInputTextField($containerLeft, 'msSFU30Name', _('NIS name'));
 | |
| 			}
 | |
| 			if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 				$this->addSimpleInputTextField($containerLeft, 'msSFU30NisDomain', _('NIS domain'));
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		$containerLeft->addElement(new htmlEqualWidth(array('streetAddress', 'cn')), true);
 | |
| 		
 | |
| 		$containerRight = new htmlTable();
 | |
| 		$containerRight->alignment = htmlElement::ALIGN_TOP;
 | |
| 		$containerRight->addElement(new htmlSubTitle(_('Groups')), true);
 | |
| 		$containerRight->addElement(new htmlAccountPageButton(get_class($this), 'group', 'edit', _('Edit groups')), true);
 | |
| 		$containerRight->addElement(new htmlSpacer(null, '10px'), true);
 | |
| 		$groupsList = new htmlGroup();
 | |
| 		$groupCNs = array();
 | |
| 		for ($i = 0; $i < sizeof($this->groupList); $i++) {
 | |
| 			$groupCNs[] = extractRDNValue($this->groupList[$i]);
 | |
| 		}
 | |
| 		natcasesort($groupCNs);
 | |
| 		foreach ($groupCNs as $cn) {
 | |
| 			$groupsList->addElement(new htmlOutputText($cn));
 | |
| 			$groupsList->addElement(new htmlOutputText('<br>', false));
 | |
| 		}
 | |
| 		$containerRight->addElement($groupsList);
 | |
| 		
 | |
| 		$container = new htmlTable();
 | |
| 		$container->addElement($containerLeft);
 | |
| 		$container->addElement(new htmlSpacer('40px', null));
 | |
| 		$container->addElement($containerRight);
 | |
| 		return $container;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Processes user input of the primary module page.
 | |
| 	* It checks if all input values are correct and updates the associated LDAP attributes.
 | |
| 	*
 | |
| 	* @return array list of info/error messages
 | |
| 	*/
 | |
| 	public function process_attributes() {
 | |
| 		$return = array();
 | |
| 		$replacements = array('$user' => 'userPrincipalName', '$lastname' => 'sn', '$firstname' => 'givenName');
 | |
| 		// user name
 | |
| 		$userPrincipalName = $_POST['userPrincipalName'];
 | |
| 		if (!get_preg($userPrincipalName, 'username')) {
 | |
| 			$return[] = $this->messages['userPrincipalName'][0];
 | |
| 		}
 | |
| 		if (!empty($_POST['userPrincipalNameDomain'])) {
 | |
| 			$userPrincipalName .= '@' . $_POST['userPrincipalNameDomain'];
 | |
| 		}
 | |
| 		$this->attributes['userPrincipalName'][0] = $userPrincipalName;
 | |
| 		// cn
 | |
| 		$this->attributes['cn'][0] = $_POST['cn'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['cn'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['cn'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (empty($this->attributes['cn'][0])) {
 | |
| 			$cn = '';
 | |
| 			if (!empty($_POST['givenName'])) {
 | |
| 				$cn = $_POST['givenName'];
 | |
| 			}
 | |
| 			if (!empty($_POST['sn'])) {
 | |
| 				$cn .= ' ' . $_POST['sn'];
 | |
| 			}
 | |
| 			$this->attributes['cn'][0] = trim($cn);
 | |
| 		}
 | |
| 		if (!get_preg($this->attributes['cn'][0], 'cn')) {
 | |
| 			$return[] = $this->messages['cn'][0];
 | |
| 		}
 | |
| 		// sAMAccountName
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
 | |
| 			if ($this->getAccountContainer()->isNewAccount && !isset($this->attributes['sAMAccountName']) && empty($_POST['sAMAccountName'])) {
 | |
| 				$this->attributes['sAMAccountName'][0] = $_POST['userPrincipalName'];
 | |
| 			}
 | |
| 			else {
 | |
| 				$this->attributes['sAMAccountName'][0] = $_POST['sAMAccountName'];
 | |
| 			}
 | |
| 			if (!empty($this->attributes['sAMAccountName'][0]) && !get_preg($this->attributes['sAMAccountName'][0], 'username')) {
 | |
| 				$return[] = $this->messages['sAMAccountName'][0];
 | |
| 			}
 | |
| 		}
 | |
| 		// description
 | |
| 		$this->attributes['description'][0] = $_POST['description'];
 | |
| 		// display name
 | |
| 		$this->attributes['displayName'][0] = $_POST['displayName'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['displayName'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['displayName'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (!empty($this->attributes['displayName'][0]) && !get_preg($this->attributes['displayName'][0], 'realname')) {
 | |
| 			$return[] = $this->messages['displayName'][0];
 | |
| 		}
 | |
| 		if (empty($this->attributes['displayName'][0]) && !empty($this->attributes['cn'][0])) {
 | |
| 			$this->attributes['displayName'][0] = $this->attributes['cn'][0];
 | |
| 		}
 | |
| 		// first name
 | |
| 		$this->attributes['givenName'][0] = $_POST['givenName'];
 | |
| 		if (!empty($this->attributes['givenName'][0]) && !get_preg($_POST['givenName'], 'realname')) {
 | |
| 			$return[] = $this->messages['givenName'][0];
 | |
| 		}
 | |
| 		// initials
 | |
| 		$this->attributes['initials'][0] = $_POST['initials'];
 | |
| 		// location
 | |
| 		$this->attributes['l'][0] = $_POST['l'];
 | |
| 		// email
 | |
| 		$this->attributes['mail'][0] = $_POST['mail'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['mail'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['mail'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (!empty($this->attributes['mail'][0]) && !get_preg($this->attributes['mail'][0], 'email')) {
 | |
| 			$return[] = $this->messages['mail'][0];
 | |
| 		}
 | |
| 		// email aliases
 | |
| 		$this->processMultiValueInputTextField('otherMailbox', $return, 'email');
 | |
| 		if (!empty($this->attributes['otherMailbox'])) {
 | |
| 			foreach ($this->attributes['otherMailbox'] as &$otherMailbox) {
 | |
| 				foreach ($replacements as $wildcard => $postKey) {
 | |
| 					if (!empty($_POST[$postKey])) {
 | |
| 						$otherMailbox = str_replace($wildcard, $_POST[$postKey], $otherMailbox);
 | |
| 					}
 | |
| 				}
 | |
| 			}			
 | |
| 		}
 | |
| 		// other telephones
 | |
| 		$this->processMultiValueInputTextField('otherTelephone', $return, 'telephone');
 | |
| 		// office name
 | |
| 		$this->attributes['physicalDeliveryOfficeName'][0] = $_POST['physicalDeliveryOfficeName'];
 | |
| 		// postal code
 | |
| 		$this->attributes['postalCode'][0] = $_POST['postalCode'];
 | |
| 		if (!get_preg($_POST['postalCode'], 'postalCode')) {
 | |
| 			$return[] = $this->messages['postalCode'][0];
 | |
| 		}
 | |
| 		// post office box
 | |
| 		$this->attributes['postOfficeBox'][0] = $_POST['postOfficeBox'];
 | |
| 		// last name
 | |
| 		$this->attributes['sn'][0] = $_POST['sn'];
 | |
| 		if (!empty($this->attributes['sn'][0]) && !get_preg($_POST['sn'], 'realname')) {
 | |
| 			$return[] = $this->messages['sn'][0];
 | |
| 		}
 | |
| 		// state
 | |
| 		$this->attributes['st'][0] = $_POST['st'];
 | |
| 		// street
 | |
| 		$this->attributes['streetAddress'][0] = $_POST['streetAddress'];
 | |
| 		// telephone
 | |
| 		$this->attributes['telephoneNumber'][0] = $_POST['telephoneNumber'];
 | |
| 		if (!get_preg($_POST['telephoneNumber'], 'telephone')) {
 | |
| 			$return[] = $this->messages['telephoneNumber'][0];
 | |
| 		}
 | |
| 		// other web sites
 | |
| 		$this->processMultiValueInputTextField('url', $return);
 | |
| 		// web site
 | |
| 		$this->attributes['wWWHomePage'][0] = $_POST['wWWHomePage'];
 | |
| 		// password must be changed
 | |
| 		if (isset($_POST['forcePasswordChangeOption']) && ($_POST['forcePasswordChangeOption'] == 'on')) {
 | |
| 			$this->attributes['pwdLastSet'][0] = '0';
 | |
| 		}
 | |
| 		else {
 | |
| 			if (isset($this->orig['pwdLastSet'][0]) && ($this->orig['pwdLastSet'][0] !== '0')) {
 | |
| 				$this->attributes['pwdLastSet'][0] = $this->orig['pwdLastSet'][0];
 | |
| 			}
 | |
| 			else {
 | |
| 				$this->attributes['pwdLastSet'][0] = '-1';
 | |
| 			}
 | |
| 		}
 | |
| 		// save pwdLastSet for postModifyActions
 | |
| 		$this->pwdLastSet = null;
 | |
| 		if (isset($this->attributes['pwdLastSet'][0])) {
 | |
| 			if (!isset($this->orig['pwdLastSet'][0]) || ($this->orig['pwdLastSet'][0] != $this->attributes['pwdLastSet'][0])) {
 | |
| 				$this->pwdLastSet = $this->attributes['pwdLastSet'][0];
 | |
| 			}
 | |
| 		}
 | |
| 		// deactivated
 | |
| 		$deactivated = isset($_POST['deactivated']) && ($_POST['deactivated'] == 'on');
 | |
| 		windowsUser::setIsDeactivated($deactivated);
 | |
| 		// no expire
 | |
| 		$noExpire = isset($_POST['noExpire']) && ($_POST['noExpire'] == 'on');
 | |
| 		windowsUser::setIsNeverExpiring($this->attributes, $noExpire);
 | |
| 		// smartcard required
 | |
| 		$requireCard = isset($_POST['requireCard']) && ($_POST['requireCard'] == 'on');
 | |
| 		windowsUser::setIsSmartCardRequired($this->attributes, $requireCard);
 | |
| 		// profile path
 | |
| 		$this->attributes['profilePath'][0] = $_POST['profilePath'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['profilePath'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['profilePath'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (!($this->attributes['profilePath'][0] == '') && !get_preg($this->attributes['profilePath'][0], 'UNC')) {
 | |
| 			$return[] = $this->messages['profilePath'][0];
 | |
| 		}
 | |
| 		// logon script
 | |
| 		$this->attributes['scriptPath'][0] = $_POST['scriptPath'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['scriptPath'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['scriptPath'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (($this->attributes['scriptPath'][0] != '') && (!get_preg($this->attributes['scriptPath'][0], 'logonscript'))) {
 | |
| 			$return[] = $this->messages['scriptPath'][0];
 | |
| 		}
 | |
| 		// home drive
 | |
| 		if ($_POST['homeDrive'] == "-") {
 | |
| 			$this->attributes['homeDrive'][0] = '';
 | |
| 		}
 | |
| 		else {
 | |
| 			$this->attributes['homeDrive'][0] = $_POST['homeDrive'];
 | |
| 		}
 | |
| 		// home directory
 | |
| 		$this->attributes['homeDirectory'][0] = $_POST['homeDirectory'];
 | |
| 		foreach ($replacements as $wildcard => $postKey) {
 | |
| 			if (!empty($_POST[$postKey])) {
 | |
| 				$this->attributes['homeDirectory'][0] = str_replace($wildcard, $_POST[$postKey], $this->attributes['homeDirectory'][0]);
 | |
| 			}
 | |
| 		}
 | |
| 		if (!empty($this->attributes['homeDrive'][0]) && !get_preg($this->attributes['homeDirectory'][0], 'UNC')) {
 | |
| 			$return[] = $this->messages['homeDirectory'][0];
 | |
| 		}
 | |
| 		// NIS name
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 			if ($this->getAccountContainer()->isNewAccount && !isset($this->attributes['msSFU30Name']) && empty($_POST['msSFU30Name'])) {
 | |
| 				$this->attributes['msSFU30Name'][0] = $_POST['userPrincipalName'];
 | |
| 			}
 | |
| 			else {
 | |
| 				$this->attributes['msSFU30Name'][0] = $_POST['msSFU30Name'];
 | |
| 			}
 | |
| 			if (!empty($this->attributes['msSFU30Name'][0]) && !get_preg($this->attributes['msSFU30Name'][0], 'username')) {
 | |
| 				$return[] = $this->messages['msSFU30Name'][0];
 | |
| 			}
 | |
| 		}
 | |
| 		// NIS domain
 | |
| 		if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 			$this->attributes['msSFU30NisDomain'][0] = $_POST['msSFU30NisDomain'];
 | |
| 		}
 | |
| 		
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* Displays the group selection.
 | |
| 	*
 | |
| 	* @return htmlElement meta HTML code
 | |
| 	*/
 | |
| 	function display_html_group() {
 | |
| 		$return = new htmlTable();
 | |
| 		$groups = $this->findGroups();
 | |
| 		// sort by DN
 | |
| 		usort($groups, 'compareDN');
 | |
| 			
 | |
| 		$groupContainer = new htmlTable();
 | |
| 		$groupContainer->alignment = htmlElement::ALIGN_TOP;
 | |
| 		$groupContainer->addElement(new htmlSubTitle(_("Groups of names")), true);
 | |
| 		$groupContainer->addElement(new htmlOutputText(_("Selected groups")));
 | |
| 		$groupContainer->addElement(new htmlOutputText(''));
 | |
| 		$groupContainer->addElement(new htmlOutputText(_("Available groups")));
 | |
| 		$groupContainer->addNewLine();
 | |
| 		
 | |
| 		$selectedGroups = array();
 | |
| 		// sort by DN
 | |
| 		usort($this->groupList, 'compareDN');
 | |
| 		for ($i = 0; $i < sizeof($this->groupList); $i++) {
 | |
| 			if (in_array($this->groupList[$i], $groups)) {
 | |
| 				$selectedGroups[getAbstractDN($this->groupList[$i])] = $this->groupList[$i];
 | |
| 			}
 | |
| 		}
 | |
| 		$availableGroups = array();
 | |
| 		foreach ($groups as $dn) {
 | |
| 			if (!in_array($dn, $this->groupList)) {
 | |
| 				$availableGroups[getAbstractDN($dn)] = $dn;
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		$remGroupSelect = new htmlSelect('removegroups', $selectedGroups, null, 15);
 | |
| 		$remGroupSelect->setMultiSelect(true);
 | |
| 		$remGroupSelect->setTransformSingleSelect(false);
 | |
| 		$remGroupSelect->setHasDescriptiveElements(true);
 | |
| 		$remGroupSelect->setRightToLeftTextDirection(true);
 | |
| 		$remGroupSelect->setSortElements(false);
 | |
| 		$groupContainer->addElement($remGroupSelect);
 | |
| 		$buttonGroupContainer = new htmlTable();
 | |
| 		$buttonGroupContainer->addElement(new htmlButton('addgroups_button', 'back.gif', true), true);
 | |
| 		$buttonGroupContainer->addElement(new htmlButton('removegroups_button', 'forward.gif', true), true);
 | |
| 		$buttonGroupContainer->addElement(new htmlHelpLink('addgroup'));
 | |
| 		$groupContainer->addElement($buttonGroupContainer);
 | |
| 		$addGroupSelect = new htmlSelect('addgroups', $availableGroups, null, 15);
 | |
| 		$addGroupSelect->setMultiSelect(true);
 | |
| 		$addGroupSelect->setHasDescriptiveElements(true);
 | |
| 		$addGroupSelect->setTransformSingleSelect(false);
 | |
| 		$addGroupSelect->setRightToLeftTextDirection(true);
 | |
| 		$addGroupSelect->setSortElements(false);
 | |
| 		$groupContainer->addElement($addGroupSelect);
 | |
| 		$groupContainer->addNewLine();
 | |
| 		$return->addElement($groupContainer);
 | |
| 		$return->addNewLine();
 | |
| 
 | |
| 		$backGroup = new htmlGroup();
 | |
| 		$backGroup->colspan = 10;
 | |
| 		$backGroup->addElement(new htmlSpacer(null, '10px'), true);
 | |
| 		$backButton = new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back'));
 | |
| 		$backGroup->addElement($backButton);
 | |
| 		$return->addElement($backGroup);
 | |
| 		return $return;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	* Processes user input of the group selection page.
 | |
| 	* It checks if all input values are correct and updates the associated LDAP attributes.
 | |
| 	*
 | |
| 	* @return array list of info/error messages
 | |
| 	*/
 | |
| 	function process_group() {
 | |
| 		if (isset($_POST['addgroups']) && isset($_POST['addgroups_button'])) { // Add groups to list
 | |
| 			// add new group
 | |
| 			$this->groupList = @array_merge($this->groupList, $_POST['addgroups']);
 | |
| 		}
 | |
| 		elseif (isset($_POST['removegroups']) && isset($_POST['removegroups_button'])) { // remove groups from list
 | |
| 			$this->groupList = array_delete($_POST['removegroups'], $this->groupList);
 | |
| 		}
 | |
| 		return array();
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Runs the postmodify actions.
 | |
| 	 * 
 | |
| 	 * @see baseModule::postModifyActions()
 | |
| 	 *
 | |
| 	 * @param boolean $newAccount
 | |
| 	 * @param array $attributes LDAP attributes of this entry
 | |
| 	 * @return array array which contains status messages. Each entry is an array containing the status message parameters.
 | |
| 	 */
 | |
| 	public function postModifyActions($newAccount, $attributes) {
 | |
| 		$messages = array();
 | |
| 		// set groups
 | |
| 		$groups = $this->findGroups();
 | |
| 		$toAdd = array_values(array_diff($this->groupList, $this->groupList_orig));
 | |
| 		$toRem = array_values(array_diff($this->groupList_orig, $this->groupList));
 | |
| 		$toUpdate = array_values(array_intersect($this->groupList, $this->groupList_orig));
 | |
| 		$ldapUser = $_SESSION['ldap']->decrypt_login();
 | |
| 		$ldapUser = $ldapUser[0];
 | |
| 		// add groups
 | |
| 		for ($i = 0; $i < sizeof($toAdd); $i++) {
 | |
| 			if (in_array($toAdd[$i], $groups)) {
 | |
| 				$success = @ldap_mod_add($_SESSION['ldap']->server(), $toAdd[$i], array('member' => array($this->getAccountContainer()->finalDN)));
 | |
| 				if (!$success) {
 | |
| 					logNewMessage(LOG_ERR, '[' . $ldapUser .'] Unable to add user ' . $this->getAccountContainer()->finalDN . ' to group: ' . $toAdd[$i] . ' (' . ldap_error($_SESSION['ldap']->server()) . ').');
 | |
| 					$messages[] = array('ERROR', sprintf(_('Was unable to add attributes to DN: %s.'), $toAdd[$i]), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
 | |
| 				}
 | |
| 				else {
 | |
| 					logNewMessage(LOG_NOTICE, '[' . $ldapUser .'] Added user ' . $this->getAccountContainer()->finalDN . ' to group: ' . $toAdd[$i]);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		// remove groups
 | |
| 		for ($i = 0; $i < sizeof($toRem); $i++) {
 | |
| 			if (in_array($toRem[$i], $groups)) {
 | |
| 				$success = @ldap_mod_del($_SESSION['ldap']->server(), $toRem[$i], array('member' => array($this->getAccountContainer()->dn_orig)));
 | |
| 				if (!$success) {
 | |
| 					logNewMessage(LOG_ERR, '[' . $ldapUser .'] Unable to delete user ' . $this->getAccountContainer()->finalDN . ' from group: ' . $toRem[$i] . ' (' . ldap_error($_SESSION['ldap']->server()) . ').');
 | |
| 					$messages[] = array('ERROR', sprintf(_('Was unable to remove attributes from DN: %s.'), $toRem[$i]), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
 | |
| 				}
 | |
| 				else {
 | |
| 					logNewMessage(LOG_NOTICE, '[' . $ldapUser .'] Removed user ' . $this->getAccountContainer()->finalDN . ' from group: ' . $toRem[$i]);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		// force password change if needed
 | |
| 		if ($this->pwdLastSet != null) {
 | |
| 			$attrs = array('pwdLastSet' => array($this->pwdLastSet));
 | |
| 			$success = @ldap_modify($_SESSION['ldap']->server(), $this->getAccountContainer()->finalDN, $attrs);
 | |
| 			if (!$success) {
 | |
| 				logNewMessage(LOG_ERR, '[' . $ldapUser .'] Unable to change pwdLastSet for ' . $this->getAccountContainer()->finalDN . ' (' . ldap_error($_SESSION['ldap']->server()) . ').');
 | |
| 				$messages[] = array('ERROR', sprintf(_('Was unable to modify attributes of DN: %s.'), $this->getAccountContainer()->finalDN), getDefaultLDAPErrorString($_SESSION['ldap']->server()));
 | |
| 			}
 | |
| 		}
 | |
| 		return $messages;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* In this function the LDAP account is built up.
 | |
| 	*
 | |
| 	* @param array $rawAccounts list of hash arrays (name => value) from user input
 | |
| 	* @param array $ids list of IDs for column position (e.g. "posixAccount_uid" => 5)
 | |
| 	* @param array $partialAccounts list of hash arrays (name => value) which are later added to LDAP
 | |
| 	* @param array $selectedModules list of selected account modules
 | |
| 	* @return array list of error messages if any
 | |
| 	*/
 | |
| 	public function build_uploadAccounts($rawAccounts, $ids, &$partialAccounts, $selectedModules) {
 | |
| 		$errors = array();
 | |
| 		$replacements = array();
 | |
| 		// get list of existing groups
 | |
| 		$groupList = $this->findGroups();
 | |
| 		$groupMap = array();
 | |
| 		foreach ($groupList as $dn) {
 | |
| 			$groupMap[extractRDNValue($dn)] = $dn;
 | |
| 		}
 | |
| 		$booleanOptions = array(_('yes') => true, _('no') => false);
 | |
| 		for ($i = 0; $i < sizeof($rawAccounts); $i++) {
 | |
| 			// add object class
 | |
| 			if (!in_array('user', $partialAccounts[$i]['objectClass'])) $partialAccounts[$i]['objectClass'][] = 'user';
 | |
| 			// userPrincipalName
 | |
| 			if (get_preg($rawAccounts[$i][$ids['windowsUser_userPrincipalName']], 'username')) {
 | |
| 				$partialAccounts[$i]['userPrincipalName'] = $rawAccounts[$i][$ids['windowsUser_userPrincipalName']];
 | |
| 				$parts = explode('@', $partialAccounts[$i]['userPrincipalName']);
 | |
| 				$replacements['$user'] = $parts[0];
 | |
| 			}
 | |
| 			else {
 | |
| 				$errMsg = $this->messages['userPrincipalName'][1];
 | |
| 				array_push($errMsg, array($i));
 | |
| 				$errors[] = $errMsg;
 | |
| 			}
 | |
| 			// first name
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_firstName']] != "") {
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_firstName']], 'realname')) {
 | |
| 					$partialAccounts[$i]['givenName'] = $rawAccounts[$i][$ids['windowsUser_firstName']];
 | |
| 					$replacements['$firstname'] = $partialAccounts[$i]['givenName'];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['givenName'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// last name
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_lastName']] != "") {
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_lastName']], 'realname')) {
 | |
| 					$partialAccounts[$i]['sn'] = $rawAccounts[$i][$ids['windowsUser_lastName']];
 | |
| 					$replacements['$lastname'] = $partialAccounts[$i]['sn'];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['sn'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// cn
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_cn']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_cn']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_cn']]);
 | |
| 				}
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_cn']], 'cn')) {
 | |
| 					$partialAccounts[$i]['cn'] = $rawAccounts[$i][$ids['windowsUser_cn']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['cn'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			else {
 | |
| 				$cn = '';
 | |
| 				if (!empty($rawAccounts[$i][$ids['windowsUser_firstName']])) {
 | |
| 					$cn = $rawAccounts[$i][$ids['windowsUser_firstName']];
 | |
| 				}
 | |
| 				if (!empty($rawAccounts[$i][$ids['windowsUser_lastName']])) {
 | |
| 					$cn .= ' ' . $rawAccounts[$i][$ids['windowsUser_lastName']];
 | |
| 				}
 | |
| 				$cn = trim($cn);
 | |
| 				if (!empty($cn)) {
 | |
| 					$partialAccounts[$i]['cn'] = $cn;
 | |
| 				}
 | |
| 			}
 | |
| 			// sAMAccountName
 | |
| 			if (!$this->isBooleanConfigOptionSet('windowsUser_hidesAMAccountName', true)) {
 | |
| 				if (!empty($rawAccounts[$i][$ids['windowsUser_sAMAccountName']])) {
 | |
| 					if (get_preg($rawAccounts[$i][$ids['windowsUser_sAMAccountName']], 'username')) {
 | |
| 						$partialAccounts[$i]['sAMAccountName'] = $rawAccounts[$i][$ids['windowsUser_sAMAccountName']];
 | |
| 					}
 | |
| 					else {
 | |
| 						$errMsg = $this->messages['sAMAccountName'][1];
 | |
| 						array_push($errMsg, array($i));
 | |
| 						$errors[] = $errMsg;
 | |
| 					}
 | |
| 				}
 | |
| 				else {
 | |
| 					$samUser = explode('@', $partialAccounts[$i]['userPrincipalName']);
 | |
| 					$partialAccounts[$i]['sAMAccountName'] = $samUser[0];
 | |
| 				}
 | |
| 			}
 | |
| 			// password
 | |
| 			if (($rawAccounts[$i][$ids['windowsUser_password']] != "") && (get_preg($rawAccounts[$i][$ids['windowsUser_password']], 'password'))) {
 | |
| 				$partialAccounts[$i]['unicodePwd'] = self::pwdAttributeValue($rawAccounts[$i][$ids['windowsUser_password']]);
 | |
| 				$partialAccounts[$i]['INFO.userPasswordClearText'] = $rawAccounts[$i][$ids['windowsUser_password']]; // for custom scripts etc.
 | |
| 			}
 | |
| 			elseif ($rawAccounts[$i][$ids['windowsUser_password']] != "") {
 | |
| 				$errMsg = $this->messages['userPassword'][4];
 | |
| 				$errMsg[2] = str_replace('%', '%%', $errMsg[2]); // double "%" because of later sprintf
 | |
| 				array_push($errMsg, array($i));
 | |
| 				$errors[] = $errMsg;
 | |
| 			}
 | |
| 			// display name
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_displayName']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_displayName']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_displayName']]);
 | |
| 				}
 | |
| 				$partialAccounts[$i]['displayName'] = $rawAccounts[$i][$ids['windowsUser_displayName']];
 | |
| 			}
 | |
| 			elseif (!empty($partialAccounts[$i]['cn'])) {
 | |
| 				$partialAccounts[$i]['displayName'] = $partialAccounts[$i]['cn'];
 | |
| 			}
 | |
| 			// initials
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_initials']] != "") {
 | |
| 				$partialAccounts[$i]['initials'] = $rawAccounts[$i][$ids['windowsUser_initials']];
 | |
| 			}
 | |
| 			// description
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_description']] != "") {
 | |
| 				$partialAccounts[$i]['description'] = $rawAccounts[$i][$ids['windowsUser_description']];
 | |
| 			}
 | |
| 			// street
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_streetAddress']] != "") {
 | |
| 				$partialAccounts[$i]['streetAddress'] = $rawAccounts[$i][$ids['windowsUser_streetAddress']];
 | |
| 			}
 | |
| 			// post office box
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_postOfficeBox']] != "") {
 | |
| 				$partialAccounts[$i]['postOfficeBox'] = $rawAccounts[$i][$ids['windowsUser_postOfficeBox']];
 | |
| 			}
 | |
| 			// postal code
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_postalCode']] != "") {
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_postalCode']], 'postalCode')) {
 | |
| 					$partialAccounts[$i]['postalCode'] = $rawAccounts[$i][$ids['windowsUser_postalCode']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['postalCode'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// location
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_l']] != "") {
 | |
| 				$partialAccounts[$i]['l'] = $rawAccounts[$i][$ids['windowsUser_l']];
 | |
| 			}
 | |
| 			// state
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_state']] != "") {
 | |
| 				$partialAccounts[$i]['st'] = $rawAccounts[$i][$ids['windowsUser_state']];
 | |
| 			}
 | |
| 			// office name
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_officeName']] != "") {
 | |
| 				$partialAccounts[$i]['physicalDeliveryOfficeName'] = $rawAccounts[$i][$ids['windowsUser_officeName']];
 | |
| 			}
 | |
| 			// mail
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_mail']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_mail']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_mail']]);
 | |
| 				}
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_mail']], 'email')) {
 | |
| 					$partialAccounts[$i]['mail'] = $rawAccounts[$i][$ids['windowsUser_mail']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['mail'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// mail aliases
 | |
| 			if (isset($ids['windowsUser_otherMailbox']) && ($rawAccounts[$i][$ids['windowsUser_otherMailbox']] != "")) {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_otherMailbox']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_otherMailbox']]);
 | |
| 				}
 | |
| 				$valueList = preg_split('/;[ ]*/', $rawAccounts[$i][$ids['windowsUser_otherMailbox']]);
 | |
| 				$partialAccounts[$i]['otherMailbox'] = $valueList;
 | |
| 				for ($x = 0; $x < sizeof($valueList); $x++) {
 | |
| 					if (!get_preg($valueList[$x], 'email')) {
 | |
| 						$errMsg = $this->messages['otherMailbox'][1];
 | |
| 						array_push($errMsg, array($i));
 | |
| 						$errors[] = $errMsg;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// telephone
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_telephoneNumber']] != "") {
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_telephoneNumber']], 'telephone')) {
 | |
| 					$partialAccounts[$i]['telephoneNumber'] = $rawAccounts[$i][$ids['windowsUser_telephoneNumber']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['telephoneNumber'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// other telephone
 | |
| 			if (isset($ids['windowsUser_otherTelephone']) && ($rawAccounts[$i][$ids['windowsUser_otherTelephone']] != "")) {
 | |
| 				$valueList = preg_split('/;[ ]*/', $rawAccounts[$i][$ids['windowsUser_otherTelephone']]);
 | |
| 				$partialAccounts[$i]['otherTelephone'] = $valueList;
 | |
| 				for ($x = 0; $x < sizeof($valueList); $x++) {
 | |
| 					if (!get_preg($valueList[$x], 'telephone')) {
 | |
| 						$errMsg = $this->messages['otherTelephone'][1];
 | |
| 						array_push($errMsg, array($i));
 | |
| 						$errors[] = $errMsg;
 | |
| 						break;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// website
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_webSite']] != "") {
 | |
| 				$partialAccounts[$i]['wWWHomePage'] = $rawAccounts[$i][$ids['windowsUser_webSite']];
 | |
| 			}
 | |
| 			// other websites
 | |
| 			if (isset($ids['windowsUser_otherWebSites']) && ($rawAccounts[$i][$ids['windowsUser_otherWebSites']] != "")) {
 | |
| 				$valueList = preg_split('/;[ ]*/', $rawAccounts[$i][$ids['windowsUser_otherWebSites']]);
 | |
| 				$partialAccounts[$i]['url'] = $valueList;
 | |
| 			}
 | |
| 			// user account control
 | |
| 			$userAccountControlAttr['userAccountControl'][0] = windowsUser::DEFAULT_ACCOUNT_CONTROL;
 | |
| 			// deactivated
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_deactivated']] != "") {
 | |
| 				if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_deactivated']]])) {
 | |
| 					$errors[] = array('ERROR', sprintf(_('Account %s:'), $i) . ' windowsUser_deactivated', _('Please enter either yes or no.'));
 | |
| 				}
 | |
| 				else {
 | |
| 					$this->setIsDeactivated($booleanOptions[$rawAccounts[$i][$ids['windowsUser_deactivated']]], $userAccountControlAttr);
 | |
| 				}
 | |
| 			}
 | |
| 			// password does not expire
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_noExpire']] != "") {
 | |
| 				if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_noExpire']]])) {
 | |
| 					$errors[] = array('ERROR', sprintf(_('Account %s:'), $i) . ' windowsUser_noExpire', _('Please enter either yes or no.'));
 | |
| 				}
 | |
| 				else {
 | |
| 					$this->setIsNeverExpiring($userAccountControlAttr, $booleanOptions[$rawAccounts[$i][$ids['windowsUser_noExpire']]]);
 | |
| 				}
 | |
| 			}
 | |
| 			// require smartcard
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_requireCard']] != "") {
 | |
| 				if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_requireCard']]])) {
 | |
| 					$errors[] = array('ERROR', sprintf(_('Account %s:'), $i) . ' windowsUser_requireCard', _('Please enter either yes or no.'));
 | |
| 				}
 | |
| 				else {
 | |
| 					$this->setIsSmartCardRequired($userAccountControlAttr, $booleanOptions[$rawAccounts[$i][$ids['windowsUser_requireCard']]]);
 | |
| 				}
 | |
| 			}
 | |
| 			$partialAccounts[$i]['userAccountControl'][0] = $userAccountControlAttr['userAccountControl'][0];
 | |
| 			// end user account control
 | |
| 			// password change at next login
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_pwdMustChange']] != "") {
 | |
| 				if (!isset($booleanOptions[$rawAccounts[$i][$ids['windowsUser_pwdMustChange']]])) {
 | |
| 					$errors[] = array('ERROR', sprintf(_('Account %s:'), $i) . ' windowsUser_pwdMustChange', _('Please enter either yes or no.'));
 | |
| 				}
 | |
| 				// attribute must be set in postModify
 | |
| 			}
 | |
| 			// profile path
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_profilePath']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_profilePath']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_profilePath']]);
 | |
| 				}
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_profilePath']], 'UNC')) {
 | |
| 					$partialAccounts[$i]['profilePath'] = $rawAccounts[$i][$ids['windowsUser_profilePath']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['profilePath'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// logon script
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_scriptPath']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_scriptPath']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_scriptPath']]);
 | |
| 				}
 | |
| 				if (get_preg($rawAccounts[$i][$ids['windowsUser_scriptPath']], 'logonscript')) {
 | |
| 					$partialAccounts[$i]['scriptPath'] = $rawAccounts[$i][$ids['windowsUser_scriptPath']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['scriptPath'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// home drive
 | |
| 			if (!empty($rawAccounts[$i][$ids['windowsUser_homeDrive']])) {
 | |
| 				if (preg_match("/[d-z]:/i", $rawAccounts[$i][$ids['windowsUser_homeDrive']])) {
 | |
| 					$partialAccounts[$i]['homeDrive'] = strtoupper($rawAccounts[$i][$ids['windowsUser_homeDrive']]);
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['homeDrive'][0];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// home directory
 | |
| 			if ($rawAccounts[$i][$ids['windowsUser_homeDirectory']] != "") {
 | |
| 				foreach ($replacements as $wildcard => $value) {
 | |
| 					$rawAccounts[$i][$ids['windowsUser_homeDirectory']] = str_replace($wildcard, $value, $rawAccounts[$i][$ids['windowsUser_homeDirectory']]);
 | |
| 				}
 | |
| 				if (empty($partialAccounts[$i]['homeDrive']) || get_preg($rawAccounts[$i][$ids['windowsUser_homeDirectory']], 'UNC')) {
 | |
| 					$partialAccounts[$i]['homeDirectory'] = $rawAccounts[$i][$ids['windowsUser_homeDirectory']];
 | |
| 				}
 | |
| 				else {
 | |
| 					$errMsg = $this->messages['homeDirectory'][1];
 | |
| 					array_push($errMsg, array($i));
 | |
| 					$errors[] = $errMsg;
 | |
| 				}
 | |
| 			}
 | |
| 			// groups
 | |
| 			if (isset($ids['windowsUser_groups']) && ($rawAccounts[$i][$ids['windowsUser_groups']] != "")) {
 | |
| 				$valueList = preg_split('/;[ ]*/', $rawAccounts[$i][$ids['windowsUser_groups']]);
 | |
| 				$invalidGroups = array();
 | |
| 				foreach ($valueList as $group) {
 | |
| 					if (!in_array($group, $groupList) && !isset($groupMap[$group])) {
 | |
| 						$invalidGroups[] = $group;
 | |
| 					}
 | |
| 				}
 | |
| 				if (sizeof($invalidGroups) > 0) {
 | |
| 					$errors[] = array('ERROR', sprintf(_('Account %s:'), $i) . ' windowsUser_groups',
 | |
| 						_('LAM was unable to find a group with this name!') . '<br>' . htmlspecialchars(implode('; ', $invalidGroups)));
 | |
| 				}
 | |
| 			}
 | |
| 			// NIS name
 | |
| 			if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30Name', true)) {
 | |
| 				if (!empty($rawAccounts[$i][$ids['windowsUser_msSFU30Name']])) {
 | |
| 					if (get_preg($rawAccounts[$i][$ids['windowsUser_msSFU30Name']], 'username')) {
 | |
| 						$partialAccounts[$i]['msSFU30Name'] = $rawAccounts[$i][$ids['windowsUser_msSFU30Name']];
 | |
| 					}
 | |
| 					else {
 | |
| 						$errMsg = $this->messages['msSFU30Name'][1];
 | |
| 						array_push($errMsg, array($i));
 | |
| 						$errors[] = $errMsg;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			// NIS domain
 | |
| 			if (!$this->isBooleanConfigOptionSet('windowsUser_hidemsSFU30NisDomain', true)) {
 | |
| 				if (!empty($rawAccounts[$i][$ids['windowsUser_msSFU30NisDomain']])) {
 | |
| 					$partialAccounts[$i]['msSFU30NisDomain'] = $rawAccounts[$i][$ids['windowsUser_msSFU30NisDomain']];
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return $errors;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* This function executes one post upload action.
 | |
| 	*
 | |
| 	* @param array $data array containing one account in each element
 | |
| 	* @param array $ids array(<column_name> => <column number>)
 | |
| 	* @param array $failed list of accounts which were not created successfully
 | |
| 	* @param array $temp variable to store temporary data between two post actions
 | |
| 	* @param array $accounts list of LDAP entries
 | |
| 	* @return array current status
 | |
| 	* <br> array (
 | |
| 	* <br>  'status' => 'finished' | 'inProgress'
 | |
| 	* <br>  'progress' => 0..100
 | |
| 	* <br>  'errors' => array (<array of parameters for StatusMessage>)
 | |
| 	* <br> )
 | |
| 	*/
 | |
| 	function doUploadPostActions(&$data, $ids, $failed, &$temp, &$accounts) {
 | |
| 		if (!checkIfWriteAccessIsAllowed($this->get_scope())) {
 | |
| 			die();
 | |
| 		}
 | |
| 		// on first call generate list of ldap operations
 | |
| 		if (!isset($temp['counter'])) {
 | |
| 			$groupList = $this->findGroups();
 | |
| 			$groupMap = array();
 | |
| 			foreach ($groupList as $dn) {
 | |
| 				$groupMap[extractRDNValue($dn)] = $dn;
 | |
| 			}
 | |
| 			$temp['groups'] = &$groupList;
 | |
| 			$temp['groupMap'] = &$groupMap;
 | |
| 			$temp['members'] = array();
 | |
| 			$temp['memberCount'] = 0;
 | |
| 			$temp['pwdChange'] = array();
 | |
| 			$temp['pwdChangeCount'] = 0;
 | |
| 			$groupCol = $ids['windowsUser_groups'];
 | |
| 			$passwordChangeRequiredCol = $ids['windowsUser_pwdMustChange'];
 | |
| 			for ($i = 0; $i < sizeof($data); $i++) {
 | |
| 				if (in_array($i, $failed)) continue; // ignore failed accounts
 | |
| 				if ($data[$i][$groupCol] != "") {
 | |
| 					$groups = preg_split('/;[ ]*/', $data[$i][$groupCol]);
 | |
| 					for ($g = 0; $g < sizeof($groups); $g++) {
 | |
| 						if (in_array($groups[$g], $temp['groups'])) {
 | |
| 							$temp['members'][$groups[$g]][] = $accounts[$i]['dn'];
 | |
| 						}
 | |
| 						elseif (isset($temp['groupMap'][$groups[$g]])) {
 | |
| 							$temp['members'][$temp['groupMap'][$groups[$g]]][] = $accounts[$i]['dn'];
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				if (isset($data[$i][$passwordChangeRequiredCol]) && ($data[$i][$passwordChangeRequiredCol] == _('yes'))) {
 | |
| 					$temp['pwdChange'][] = $accounts[$i]['dn'];
 | |
| 				}
 | |
| 			}
 | |
| 			$temp['memberCount'] = sizeof($temp['members']);
 | |
| 			$temp['pwdChangeCount'] = sizeof($temp['pwdChange']);
 | |
| 			$temp['counter'] = $temp['memberCount'] + $temp['pwdChangeCount'];
 | |
| 			return array(
 | |
| 				'status' => 'inProgress',
 | |
| 				'progress' => 0,
 | |
| 				'errors' => array()
 | |
| 			);
 | |
| 		}
 | |
| 		// add users to groups
 | |
| 		elseif (sizeof($temp['members']) > 0) {
 | |
| 			$keys = array_keys($temp['members']);
 | |
| 			$group = $keys[0];
 | |
| 			$member = array_pop($temp['members'][$group]);
 | |
| 			$success = @ldap_mod_add($_SESSION['ldap']->server(), $group, array('member' => $member));
 | |
| 			$errors = array();
 | |
| 			if (!$success) {
 | |
| 				$errors[] = array(
 | |
| 					"ERROR",
 | |
| 					_("LAM was unable to modify group memberships for group: %s"),
 | |
| 					getDefaultLDAPErrorString($_SESSION['ldap']->server()),
 | |
| 					array($group)
 | |
| 				);
 | |
| 			}
 | |
| 			if (sizeof($temp['members'][$group]) == 0) {
 | |
| 				unset($temp['members'][$group]);
 | |
| 			}
 | |
| 			$memberPercentage = (100 * ($temp['memberCount'] - sizeof($temp['members']))) / $temp['counter'];
 | |
| 			return array (
 | |
| 				'status' => 'inProgress',
 | |
| 				'progress' => $memberPercentage,
 | |
| 				'errors' => $errors
 | |
| 			);
 | |
| 		}
 | |
| 		// force password change
 | |
| 		elseif (sizeof($temp['pwdChange']) > 0) {
 | |
| 			$dn = array_pop($temp['pwdChange']);
 | |
| 			$success = @ldap_mod_replace($_SESSION['ldap']->server(), $dn, array('pwdLastSet' => '0'));
 | |
| 			$errors = array();
 | |
| 			if (!$success) {
 | |
| 				$errors[] = array(
 | |
| 					"ERROR",
 | |
| 					_("Was unable to modify attributes of DN: %s."),
 | |
| 					getDefaultLDAPErrorString($_SESSION['ldap']->server()),
 | |
| 					array($dn)
 | |
| 				);
 | |
| 			}
 | |
| 			$pwdPercentage = (100 * ($temp['memberCount'] + ($temp['pwdChangeCount'] - sizeof($temp['pwdChange'])))) / $temp['counter'];
 | |
| 			return array (
 | |
| 				'status' => 'inProgress',
 | |
| 				'progress' => $pwdPercentage,
 | |
| 				'errors' => $errors
 | |
| 			);
 | |
| 		}
 | |
| 		// all modifications are done
 | |
| 		else {
 | |
| 			return array (
 | |
| 				'status' => 'finished',
 | |
| 				'progress' => 100,
 | |
| 				'errors' => array()
 | |
| 			);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* Returns a list of PDF entries
 | |
| 	*/
 | |
| 	public function get_pdfEntries() {
 | |
| 		$return = array();
 | |
| 		$this->addSimplePDFField($return, 'userPrincipalName', _('User name'));
 | |
| 		$this->addSimplePDFField($return, 'cn', _('Common name'));
 | |
| 		$this->addSimplePDFField($return, 'sAMAccountName', _('User name (pre W2K)'));
 | |
| 		$this->addSimplePDFField($return, 'description', _('Description'));
 | |
| 		$this->addSimplePDFField($return, 'displayName', _('Display name'));
 | |
| 		$this->addSimplePDFField($return, 'givenName', _('First name'));
 | |
| 		$this->addSimplePDFField($return, 'initials', _('Initials'));
 | |
| 		$this->addSimplePDFField($return, 'l', _('Location'));
 | |
| 		$this->addSimplePDFField($return, 'mail', _('Email address'));
 | |
| 		$this->addSimplePDFField($return, 'otherMailbox', _('Email alias'));
 | |
| 		$this->addSimplePDFField($return, 'otherTelephone', _('Other telephone numbers'));
 | |
| 		$this->addSimplePDFField($return, 'physicalDeliveryOfficeName', _('Office name'));
 | |
| 		$this->addSimplePDFField($return, 'postalCode', _('Postal code'));
 | |
| 		$this->addSimplePDFField($return, 'postOfficeBox', _('Post office box'));
 | |
| 		$this->addSimplePDFField($return, 'sn', _('Last name'));
 | |
| 		$this->addSimplePDFField($return, 'st', _('State'));
 | |
| 		$this->addSimplePDFField($return, 'streetAddress', _('Street'));
 | |
| 		$this->addSimplePDFField($return, 'telephoneNumber', _('Telephone number'));
 | |
| 		$this->addSimplePDFField($return, 'url', _('Other web sites'));
 | |
| 		$this->addSimplePDFField($return, 'wWWHomePage', _('Web site'));
 | |
| 		$this->addSimplePDFField($return, 'msSFU30Name', _('NIS name'));
 | |
| 		$this->addSimplePDFField($return, 'msSFU30NisDomain', _('NIS domain'));
 | |
| 		$deactivated = _('no');
 | |
| 		if ($this->isDeactivated($this->attributes)) {
 | |
| 			$deactivated = _('yes');
 | |
| 		}
 | |
| 		$return[get_class($this) . '_deactivated'] = array('<block><key>' . _('Account is deactivated') . '</key><value>' . $deactivated . '</value></block>');
 | |
| 		$noExpire = _('no');
 | |
| 		if ($this->isNeverExpiring($this->attributes)) {
 | |
| 			$noExpire = _('yes');
 | |
| 		}
 | |
| 		$return[get_class($this) . '_noExpire'] = array('<block><key>' . _('Password does not expire') . '</key><value>' . $noExpire . '</value></block>');
 | |
| 		$requireCard = _('no');
 | |
| 		if ($this->isSmartCardRequired($this->attributes)) {
 | |
| 			$requireCard = _('yes');
 | |
| 		}
 | |
| 		$return[get_class($this) . '_requireCard'] = array('<block><key>' . _('Require smartcard') . '</key><value>' . $requireCard . '</value></block>');
 | |
| 		$pwdMustChange = _('no');
 | |
| 		if (isset($this->attributes['pwdLastSet'][0]) && ($this->attributes['pwdLastSet'][0] === '0')) {
 | |
| 			$pwdMustChange = _('yes');
 | |
| 		}
 | |
| 		$return[get_class($this) . '_pwdMustChange'] = array('<block><key>' . _('Password change at next login') . '</key><value>' . $pwdMustChange . '</value></block>');
 | |
| 		$this->addSimplePDFField($return, 'profilePath', _('Profile path'));
 | |
| 		$this->addSimplePDFField($return, 'scriptPath', _('Logon script'));
 | |
| 		$this->addSimplePDFField($return, 'homeDirectory', _('Home directory'));
 | |
| 		$this->addSimplePDFField($return, 'homeDrive', _('Home drive'));
 | |
| 		$groups = array();
 | |
| 		foreach ($this->groupList as $group) {
 | |
| 			$groups[] = extractRDNValue($group);
 | |
| 		}
 | |
| 		$return[get_class($this) . '_groups'] = array('<block><key>' . _('Groups') . '</key><value>' . implode(', ', $groups) . '</value></block>');
 | |
| 		// password
 | |
| 		if (isset($this->clearTextPassword)) {
 | |
| 			$return['windowsUser_password'] = array('<block><key>' . _('Password') . '</key><value>' . $this->clearTextPassword . '</value></block>');
 | |
| 		}
 | |
| 		else if (isset($this->attributes['INFO.userPasswordClearText'])) {
 | |
| 			$return['windowsUser_password'] = array('<block><key>' . _('Password') . '</key><value>' . $this->attributes['INFO.userPasswordClearText'] . '</value></block>');
 | |
| 		}
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* Returns a list of elements for the account profiles.
 | |
| 	*
 | |
| 	* @return htmlElement profile elements
 | |
| 	*/
 | |
| 	function get_profileOptions() {
 | |
| 		$return = parent::get_profileOptions();
 | |
| 		// domain
 | |
| 		$domains = $this->getDomains();
 | |
| 		$domains[] = '';
 | |
| 		$return->addElement(new htmlTableExtendedSelect('windowsUser_userPrincipalNameDomain', $domains, array(), _('Domain'), 'userPrincipalNameDomain'), true);
 | |
| 		// group memberships
 | |
| 		$groups = $this->findGroups();
 | |
| 		$groupList = array();
 | |
| 		foreach ($groups as $dn) {
 | |
| 			$groupList[extractRDNValue($dn)] = $dn;
 | |
| 		}
 | |
| 		$groupSelect = new htmlTableExtendedSelect('windowsUser_groups', $groupList, array(), _('Groups'), 'groups', 10);
 | |
| 		$groupSelect->setHasDescriptiveElements(true);
 | |
| 		$groupSelect->setMultiSelect(true);
 | |
| 		$return->addElement($groupSelect, true);
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	* Loads the values of an account profile into internal variables.
 | |
| 	*
 | |
| 	* @param array $profile hash array with profile values (identifier => value)
 | |
| 	*/
 | |
| 	function load_profile($profile) {
 | |
| 		// profile mappings in meta data
 | |
| 		parent::load_profile($profile);
 | |
| 		// load domain
 | |
| 		if (isset($profile['windowsUser_userPrincipalNameDomain'][0])) {
 | |
| 			$user = empty($this->attributes['userPrincipalName'][0]) ? '' : $this->attributes['userPrincipalName'][0];
 | |
| 			$user = explode('@', $user);
 | |
| 			$user = $user[0] . '@' . $profile['windowsUser_userPrincipalNameDomain'][0];
 | |
| 			$this->attributes['userPrincipalName'][0] = $user;
 | |
| 		}
 | |
| 		// load groups
 | |
| 		if (isset($profile['windowsUser_groups'][0])) {
 | |
| 			$this->groupList = $profile['windowsUser_groups'];
 | |
| 		}
 | |
| 		// other mailboxes
 | |
| 		if (!empty($profile['windowsUser_otherMailbox'][0])) {
 | |
| 			$this->attributes['otherMailbox'] = preg_split('/;[ ]*/', $profile['windowsUser_otherMailbox'][0]);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns the meta HTML code for each input field.
 | |
| 	 * format: array(<field1> => array(<META HTML>), ...)
 | |
| 	 * It is not possible to display help links.
 | |
| 	 *
 | |
| 	 * @param array $fields list of active fields
 | |
| 	 * @param array $attributes attributes of LDAP account
 | |
| 	 * @param boolean $passwordChangeOnly indicates that the user is only allowed to change his password and no LDAP content is readable
 | |
| 	 * @param array $readOnlyFields list of read-only fields
 | |
| 	 * @return array list of meta HTML elements (field name => htmlTableRow)
 | |
| 	 */
 | |
| 	function getSelfServiceOptions($fields, $attributes, $passwordChangeOnly, $readOnlyFields) {
 | |
| 		$return = array();
 | |
| 		if (in_array('unicodePwd', $fields)) {
 | |
| 			$pwdTable = new htmlTable();
 | |
| 			$pwdTable->colspan = 3;
 | |
| 			$pwd1 = new htmlTableExtendedInputField($this->getSelfServiceLabel('unicodePwd', _('New password')), 'windowsUser_unicodePwd');
 | |
| 			$pwd1->setIsPassword(true);
 | |
| 			$pwdTable->addElement($pwd1, true);
 | |
| 			$pwd2 = new htmlTableExtendedInputField(_('Reenter password'), 'windowsUser_unicodePwd2');
 | |
| 			$pwd2->setIsPassword(true);
 | |
| 			$pwdTable->addElement($pwd2);
 | |
| 			$return['unicodePwd'] = new htmlTableRow(array(
 | |
| 				$pwdTable
 | |
| 			));
 | |
| 		}
 | |
| 		if ($passwordChangeOnly) {
 | |
| 			return $return; // only password fields as long no LDAP content can be read
 | |
| 		}
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'physicalDeliveryOfficeName', _('Office name'), $fields, $attributes, $readOnlyFields);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'telephoneNumber', _('Telephone number'), $fields, $attributes, $readOnlyFields);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'wWWHomePage', _('Web site'), $fields, $attributes, $readOnlyFields);
 | |
| 		// TODO remove this workaround when self service allows to specify the list of active modules
 | |
| 		if (isset($attributes['street'])) {
 | |
| 			$attributes['streetAddress'] = $attributes['street'];
 | |
| 		}
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'streetAddress', _('Street'), $fields, $attributes, $readOnlyFields, false, true);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'st', _('State'), $fields, $attributes, $readOnlyFields);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'l', _('Location'), $fields, $attributes, $readOnlyFields);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'postOfficeBox', _('Post office box'), $fields, $attributes, $readOnlyFields);
 | |
| 		$this->addSimpleSelfServiceTextField($return, 'postalCode', _('Postal code'), $fields, $attributes, $readOnlyFields);
 | |
| 		return $return;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Checks if all input values are correct and returns the LDAP attributes which should be changed.
 | |
| 	 * <br>Return values:
 | |
| 	 * <br>messages: array of parameters to create status messages
 | |
| 	 * <br>add: array of attributes to add
 | |
| 	 * <br>del: array of attributes to remove
 | |
| 	 * <br>mod: array of attributes to modify
 | |
| 	 * <br>info: array of values with informational value (e.g. to be used later by pre/postModify actions)
 | |
| 	 * 
 | |
| 	 * Calling this method does not require the existence of an enclosing {@link accountContainer}.
 | |
| 	 *
 | |
| 	 * @param string $fields input fields
 | |
| 	 * @param array $attributes LDAP attributes
 | |
| 	 * @param boolean $passwordChangeOnly indicates that the user is only allowed to change his password and no LDAP content is readable
 | |
| 	 * @param array $readOnlyFields list of read-only fields
 | |
| 	 * @return array messages and attributes (array('messages' => array(), 'add' => array('mail' => array('test@test.com')), 'del' => array(), 'mod' => array(), 'info' => array()))
 | |
| 	 */
 | |
| 	function checkSelfServiceOptions($fields, $attributes, $passwordChangeOnly, $readOnlyFields) {
 | |
| 		$return = array('messages' => array(), 'add' => array(), 'del' => array(), 'mod' => array(), 'info' => array());
 | |
| 		if (in_array('unicodePwd', $fields)) {
 | |
| 			if (isset($_POST['windowsUser_unicodePwd']) && ($_POST['windowsUser_unicodePwd'] != '')) {
 | |
| 				if ($_POST['windowsUser_unicodePwd'] != $_POST['windowsUser_unicodePwd2']) {
 | |
| 					$return['messages'][] = $this->messages['unicodePwd'][0];
 | |
| 				}
 | |
| 				else {
 | |
| 					if (!get_preg($_POST['windowsUser_unicodePwd'], 'password')) {
 | |
| 						$return['messages'][] = $this->messages['unicodePwd'][1];
 | |
| 					}
 | |
| 					else {
 | |
| 						$pwdPolicyResult = checkPasswordStrength($_POST['windowsUser_unicodePwd']);
 | |
| 						if ($pwdPolicyResult === true) {
 | |
| 							$this->setSelfServicePassword($return, $attributes);
 | |
| 							$return['info']['userPasswordClearText'][0] = $_POST['windowsUser_unicodePwd'];
 | |
| 						}
 | |
| 						else {
 | |
| 							$return['messages'][] = array('ERROR', $pwdPolicyResult);
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		if ($passwordChangeOnly) {
 | |
| 			return $return; // skip processing if only a password change is done
 | |
| 		}
 | |
| 		// TODO remove this workaround when self service allows to specify the list of active modules
 | |
| 		if (isset($attributes['street'])) {
 | |
| 			$attributes['streetAddress'] = $attributes['street'];
 | |
| 		}
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'physicalDeliveryOfficeName', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'telephoneNumber', $attributes, $fields, $readOnlyFields, 'telephone');
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'wWWHomePage', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'streetAddress', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'st', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'l', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'postOfficeBox', $attributes, $fields, $readOnlyFields);
 | |
| 		$this->checkSimpleSelfServiceTextField($return, 'postalCode', $attributes, $fields, $readOnlyFields, 'postalCode');
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the user password in self service.
 | |
| 	 * Since the change requires the old password we need to run ldapmodify for this task.
 | |
| 	 * 
 | |
| 	 * Enter description here ...
 | |
| 	 * @param array $return return value for checkSelfServiceOptions() (used to add message if any)
 | |
| 	 * @param array $attributes LDAP attributes
 | |
| 	 */
 | |
| 	private function setSelfServicePassword(&$return, $attributes) {
 | |
| 		$newPasswordVal = self::pwdAttributeValue($_POST['windowsUser_unicodePwd']);
 | |
| 		$oldPassword = Ldap::decrypt($_SESSION['selfService_clientPassword'], 'SelfService');
 | |
| 		$oldPasswordVal = self::pwdAttributeValue($oldPassword);
 | |
| 		$dn = $attributes['dn'];
 | |
| 		$ldif = "dn: " . $dn . "\n";
 | |
| 		$ldif .= "changetype: modify\n";
 | |
| 		$ldif .= "delete: unicodePwd\n";
 | |
| 		$ldif .= "unicodePwd:: " . base64_encode($oldPasswordVal) . "\n";
 | |
| 		$ldif .= "-\n";
 | |
| 		$ldif .= "add: unicodePwd\n";
 | |
| 		$ldif .= "unicodePwd:: " . base64_encode($newPasswordVal) . "\n";
 | |
| 		$ldif .= "-\n";
 | |
| 		
 | |
| 		$serverURL = $_SESSION['selfServiceProfile']->serverURL;
 | |
| 		$tls = '';
 | |
| 		if ($_SESSION['selfServiceProfile']->useTLS) {
 | |
| 			$tls = ' -ZZ ';
 | |
| 		}
 | |
| 		$cmd = "/usr/bin/ldapmodify -H " . $serverURL . $tls . " -D " . escapeshellarg($dn) . " -x -w " . escapeshellarg($oldPassword);
 | |
| 		
 | |
| 		$descriptorspec = array(
 | |
| 			0 => array("pipe", "r"), // stdin
 | |
| 			1 => array("pipe", "w"), // stout
 | |
| 			2 => array("pipe", "w") // sterr
 | |
| 		);
 | |
| 		$process = proc_open($cmd, $descriptorspec, $pipes); 
 | |
| 		if (is_resource($process)) {
 | |
| 			fwrite($pipes[0], $ldif);
 | |
| 		}
 | |
| 		else {
 | |
| 			logNewMessage(LOG_ERR, 'Unable to change password of ' . $dn . '. Calling /usr/bin/ldapmodify failed.');
 | |
| 			$return['messages'][] = array('ERROR', _('Unable to change password.'));
 | |
| 			return;
 | |
| 		}
 | |
| 		fclose($pipes[0]);
 | |
| 		$outputMessages = '';
 | |
| 		while (!feof($pipes[1])) {
 | |
| 			$output = fgets($pipes[1], 1024);
 | |
| 			if ($output != '') {
 | |
| 				$outputMessages .= $output;
 | |
| 			}
 | |
| 		}
 | |
| 		while (!feof($pipes[2])) {
 | |
| 			$output = fgets($pipes[2], 1024);
 | |
| 			if ($output != '') {
 | |
| 				$outputMessages .= $output;
 | |
| 			}
 | |
| 		}
 | |
| 		fclose($pipes[1]);
 | |
| 		$returnCode = proc_close($process);
 | |
| 		if ($returnCode != 0) {
 | |
| 			$outputMessages = htmlspecialchars($outputMessages);
 | |
| 			// Active Directory message translations
 | |
| 			if ((strpos($outputMessages, 'DSID-03190F80') !== false) && (strpos($outputMessages, 'unicodePwd') !== false)) {
 | |
| 				$outputMessages = _('Your password does not meet the password strength qualifications. Please retry with another one.') . '<br><br>' . $outputMessages;
 | |
| 			}
 | |
| 			logNewMessage(LOG_ERR, 'Changing user password failed: ' . $outputMessages);
 | |
| 			$return['messages'][] = array('ERROR', _('Unable to change password.'), $outputMessages);
 | |
| 			return;
 | |
| 		}
 | |
| 		else {
 | |
| 			// update session password for next page load	
 | |
| 			$_SESSION['selfService_clientPasswordNew'] = $_POST['windowsUser_unicodePwd'];
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * This method specifies if a module manages password attributes. The module alias will
 | |
| 	 * then appear as option in the GUI. 
 | |
| 	 * <br>If the module only wants to get notified about password changes then return false.
 | |
| 	 *
 | |
| 	 * @return boolean true if this module manages password attributes
 | |
| 	 */
 | |
| 	public function managesPasswordAttributes() {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Specifies if this module supports to force that a user must change his password on next login.
 | |
| 	 * 
 | |
| 	 * @return boolean force password change supported
 | |
| 	 */
 | |
| 	public function supportsForcePasswordChange() {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * This function is called whenever the password should be changed. Account modules
 | |
| 	 * must change their password attributes only if the modules list contains their module name.
 | |
| 	 *
 | |
| 	 * @param String $password new password
 | |
| 	 * @param array $modules list of modules for which the password should be changed
 | |
| 	 * @param boolean $forcePasswordChange force the user to change his password at next login
 | |
| 	 * @return array list of error messages if any as parameter array for StatusMessage
 | |
| 	 *               e.g. return arrray(array('ERROR', 'Password change failed.'))
 | |
| 	 */
 | |
| 	public function passwordChangeRequested($password, $modules, $forcePasswordChange) {
 | |
| 		if (!in_array(get_class($this), $modules)) {
 | |
| 			return array();
 | |
| 		}
 | |
| 		$pwdBin = self::pwdAttributeValue($password);
 | |
| 		$this->orig['unicodePwd'][0] = 'unknown';
 | |
| 		$this->attributes['unicodePwd'][0] = $pwdBin;
 | |
| 		$this->attributes['pwdLastSet'][0] = '-1';
 | |
| 		if ($forcePasswordChange) {
 | |
| 			$this->attributes['pwdLastSet'][0] = '0';
 | |
| 		}
 | |
| 		$this->clearTextPassword = $password;
 | |
| 		return array();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Creates the LDAP password value.
 | |
| 	 * 
 | |
| 	 * @param String $password password
 | |
| 	 */
 | |
| 	public static function pwdAttributeValue($password) {
 | |
| 		return iconv('UTF-8', 'UTF-16LE', '"' . $password . '"');
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns if the account is currently deactivated.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes 
 | |
| 	 * @return boolean is deactivated
 | |
| 	 */
 | |
| 	public static function isDeactivated($attrs) {
 | |
| 		$myAttrs = array_change_key_case($attrs, CASE_LOWER);
 | |
| 		if (!isset($myAttrs['useraccountcontrol'][0])) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		return intval($myAttrs['useraccountcontrol'][0]) & windowsUser::AC_ACCOUNT_DISABLED;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets if the account is currently deactivated.
 | |
| 	 * 
 | |
| 	 * @param boolean $deactivated is deactivated
 | |
| 	 * @param array $attrs LDAP attributes to modify (default $this->attributes)
 | |
| 	 */
 | |
| 	public function setIsDeactivated($deactivated, &$attrs = null) {
 | |
| 		if ($attrs == null) {
 | |
| 			$attrs = &$this->attributes;
 | |
| 		}
 | |
| 		foreach ($attrs as $key => $value) {
 | |
| 			if (strtolower($key) == 'useraccountcontrol') {
 | |
| 				if ($deactivated) {
 | |
| 					$attrs[$key][0] = intval($attrs[$key][0]) | windowsUser::AC_ACCOUNT_DISABLED;
 | |
| 				}
 | |
| 				else {
 | |
| 					if (intval($attrs[$key][0]) & windowsUser::AC_ACCOUNT_DISABLED) {
 | |
| 						$attrs[$key][0] = intval($attrs[$key][0]) - windowsUser::AC_ACCOUNT_DISABLED;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns if the account is currently locked out.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes 
 | |
| 	 * @return boolean is locked out
 | |
| 	 */
 | |
| 	private static function isLockedOut($attrs) {
 | |
| 		$myAttrs = array_change_key_case($attrs, CASE_LOWER);
 | |
| 		if (!isset($attrs['useraccountcontrol'][0])) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		return intval($attrs['useraccountcontrol'][0]) & windowsUser::AC_LOCKED_OUT;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Unlocks the account.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes to modify
 | |
| 	 */
 | |
| 	public static function unlock(&$attrs) {
 | |
| 		foreach ($attrs as $key => $value) {
 | |
| 			if (strtolower($key) == 'useraccountcontrol') {
 | |
| 				if (intval($attrs[$key][0]) & windowsUser::AC_LOCKED_OUT) {
 | |
| 					$attrs[$key][0] = intval($attrs[$key][0]) - windowsUser::AC_LOCKED_OUT;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns if the account requires a smartcard to login.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes 
 | |
| 	 * @return boolean requires a smartcard
 | |
| 	 */
 | |
| 	public static function isSmartCardRequired($attrs) {
 | |
| 		$myAttrs = array_change_key_case($attrs, CASE_LOWER);
 | |
| 		if (!isset($myAttrs['useraccountcontrol'][0])) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		return intval($myAttrs['useraccountcontrol'][0]) & windowsUser::AC_SMARTCARD_REQUIRED;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets if the account requires a smartcard to login.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes to modify
 | |
| 	 * @param boolean $requireCard requires a smartcard
 | |
| 	 */
 | |
| 	public static function setIsSmartCardRequired(&$attrs, $requireCard) {
 | |
| 		foreach ($attrs as $key => $value) {
 | |
| 			if (strtolower($key) == 'useraccountcontrol') {
 | |
| 				if ($requireCard) {
 | |
| 					$attrs[$key][0] = intval($attrs[$key][0]) | windowsUser::AC_SMARTCARD_REQUIRED;
 | |
| 				}
 | |
| 				else {
 | |
| 					if (intval($attrs[$key][0]) & windowsUser::AC_SMARTCARD_REQUIRED) {
 | |
| 						$attrs[$key][0] = intval($attrs[$key][0]) - windowsUser::AC_SMARTCARD_REQUIRED;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Returns if the account never expires.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes 
 | |
| 	 * @return boolean never expires
 | |
| 	 */
 | |
| 	public static function isNeverExpiring($attrs) {
 | |
| 		$myAttrs = array_change_key_case($attrs, CASE_LOWER);
 | |
| 		if (!isset($myAttrs['useraccountcontrol'][0])) {
 | |
| 			return false;
 | |
| 		}
 | |
| 		return intval($myAttrs['useraccountcontrol'][0]) & windowsUser::AC_PWD_NEVER_EXPIRES;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Sets if the account never expires.
 | |
| 	 * 
 | |
| 	 * @param array $attrs LDAP attributes to modify
 | |
| 	 * @param boolean $neverExpires never expires
 | |
| 	 */
 | |
| 	public static function setIsNeverExpiring(&$attrs, $neverExpires) {
 | |
| 		foreach ($attrs as $key => $value) {
 | |
| 			if (strtolower($key) == 'useraccountcontrol') {
 | |
| 				if ($neverExpires) {
 | |
| 					$attrs[$key][0] = intval($attrs[$key][0]) | windowsUser::AC_PWD_NEVER_EXPIRES;
 | |
| 				}
 | |
| 				else {
 | |
| 					if (intval($attrs[$key][0]) & windowsUser::AC_PWD_NEVER_EXPIRES) {
 | |
| 						$attrs[$key][0] = intval($attrs[$key][0]) - windowsUser::AC_PWD_NEVER_EXPIRES;
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Finds all existing groups.
 | |
| 	 *
 | |
| 	 * @return array group DNs
 | |
| 	 */
 | |
| 	private function findGroups() {
 | |
| 		if ($this->groupCache != null) {
 | |
| 			return $this->groupCache;
 | |
| 		}
 | |
| 		$return = array();
 | |
| 		$types = array('group');
 | |
| 		$results = searchLDAPByFilter('(objectClass=group)', array('dn'), $types);
 | |
| 		$count = sizeof($results);
 | |
| 		for ($i = 0; $i < $count; $i++) {
 | |
| 			if (isset($results[$i]['dn'])) {
 | |
| 				$return[] = $results[$i]['dn'];
 | |
| 			}
 | |
| 		}
 | |
| 		$this->groupCache = $return;
 | |
| 		return $return;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the list of possible domains from the config setting.
 | |
| 	 * 
 | |
| 	 * @return array domain list
 | |
| 	 */
 | |
| 	private function getDomains() {
 | |
| 		$domains = array();
 | |
| 		if (!empty($this->moduleSettings['windowsUser_domains'])) {
 | |
| 			foreach ($this->moduleSettings['windowsUser_domains'] as $domain) {
 | |
| 				$domain = trim(str_replace('@', '', $domain));
 | |
| 				if (!empty($domain)) {
 | |
| 					$domains[] = $domain;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return array_values(array_unique($domains));
 | |
| 	}
 | |
| 	
 | |
| }
 | |
| 	
 | |
| ?>
 |