WordPress.org

Ready to get started?Download WordPress

Forums

Active Directory Integration
Multiple roles through AD groups (10 posts)

  1. anttiai
    Member
    Posted 4 months ago #

    Hello,

    I've integrated my AD authentication successfully to wordpress via your awesome plugin. Also assigning wordpress roles via AD-groups is working.

    I'm using wordpress as extranet solution, and I'm trying to create slightly different content for different usergroups. Also one user may be member of multiple groups wich is currently giving my headache. I've created those roles with Role Scoper and I've added them into Active Directory. Problem is that when user logs in, he will only gain one role through AD. Is it possible to assign multiple roles for user with your plugin as it is possible to do with Role Scoper, and your plugin can assign at least one role.

    http://wordpress.org/plugins/active-directory-integration/

  2. Shonu
    Member
    Posted 1 month ago #

    I need this feature as well. This is a killer criteria and I am already digging into the code to see where the "flaw" is. I know that WP originally foresees only 1 role per user (...), BUT the core code does allow multiple users (I believe as of multi sites feature) and it should not cost more than 3 lines to add this.

    Shonu

  3. Shonu
    Member
    Posted 1 month ago #

    Things to consider:

    1. roles as array thoughout usage
    2. User profile showing roles (only changable when NOT ad user and ADMIN user)
    3. non-admins shall be able to see the roles thei have, but not change them

    Using the plugin

    Multiple Roles per User
    together with this plugin may the the most appropriate solution as not everyone needs multiple roles. But it could of course be a feature switch.

    Multiple Roles per User

    offers the roles checkboxes on the profile. Perhaps both authors can collaborate?

    I have some updates for ad-integration.php that enable to write multiple roles from AD to user object. Whether security will still work, that has to be proven

  4. anttiai
    Member
    Posted 2 weeks ago #

    Hi,

    did you get this working? I couldn't quite catch up with your solution :)

  5. Shonu
    Member
    Posted 2 weeks ago #

    Our project is not kicking off, yet, but I can dump a draft of mentioned file, which I think did allow me to have multiple roles. Eventually, I might take over both plugins and make it solid, but it is complex, when you have no Active Directory at home ,-)
    I hope, my W7 Pro can act as a domain controller, somehow.

    Remind me these days again

  6. Shonu
    Member
    Posted 2 weeks ago #

    Try this and let me know about problems.

    <?php
    
    /*
    Plugin Name: Active Directory Integration
    Version: 1.1.5
    Plugin URI: http://www.steindorff.de/wp-ad-integration
    Description: Allows WordPress to authenticate, authorize, create and update users through Active Directory [Unofficial patch by Carsten Schaefer (infomail@crs-web.de): 1. Multiple roles support]
    Author: Christoph Steindorff
    Author URI: http://www.steindorff.de/
    
    The work is derived from version 1.0.5 of the plugin Active Directory Authentication:
    OriginalPlugin URI: http://soc.qc.edu/jonathan/wordpress-ad-auth
    OriginalDescription: Allows WordPress to authenticate users through Active Directory
    OriginalAuthor: Jonathan Marc Bearak
    OriginalAuthor URI: http://soc.qc.edu/jonathan
    */
    
    /*
    	This library is free software; you can redistribute it and/or
    	modify it under the terms of the GNU Lesser General Public
    	License as published by the Free Software Foundation; either
    	version 2.1 of the License, or (at your option) any later version.
    
    	This library 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
    	Lesser General Public License for more details.
    */
    
    if (!class_exists('ADIntegrationPlugin')) {
    
    define('ADI_DEBUG_LOG', 1);
    
    define('USE_MULTI_ROLES', TRUE);
    // LOG LEVEL
    define('ADI_LOG_DEBUG', 6);
    define('ADI_LOG_INFO',  5);
    define('ADI_LOG_NOTICE',4);
    define('ADI_LOG_WARN',  3);
    define('ADI_LOG_ERROR', 2);
    define('ADI_LOG_FATAL', 1);
    define('ADI_LOG_NONE',  0);
    
    define('ADI_DUPLICATE_EMAIL_ADDRESS_PREVENT', 'prevent');
    define('ADI_DUPLICATE_EMAIL_ADDRESS_ALLOW', 'allow');
    define('ADI_DUPLICATE_EMAIL_ADDRESS_CREATE', 'create');
    
    class ADIntegrationPlugin {
    
    	// version of needed DB table structure
    	const DB_VERSION = '0.9';
    	const ADI_VERSION = '1.1.4';
    
    	// name of our own table
    	const TABLE_NAME = 'adintegration';
    
    	// is the user authenticated?
    	public $_authenticated = false;
    
    	protected $_minium_WPMU_version = '3.0';
    	protected $_minium_WP_version = '3.0';
    
    	// log level
    	protected $_loglevel = ADI_LOG_NONE;
    
    	protected $_logfile = '';
    
    	// adLDAP-object
    	protected $_adldap;
    
    	// Should a new user be created automatically if not already in the WordPress database?
    	protected $_auto_create_user = false;
    
    	// Should the users be updated in the WordPress database everytime they logon? (Works only if automatic user creation is set.
    	protected $_auto_update_user = false;
    
    	// Account Suffix (will be appended to all usernames created in WordPress, as well as used in the Active Directory authentication process
    	protected $_account_suffix = '';
    
    	// Should the account suffix be appended to the usernames created in WordPress?
    	protected $_append_suffix_to_new_users = false;
    
    	// Domain Controllers (separate with semicolons)
    	protected $_domain_controllers = '';
    
    	// LDAP/AD BASE DN
    	protected $_base_dn = '';
    
    	// Role Equivalent Groups (wp-role1=ad-group1;wp-role2=ad-group2;...)
    	protected $_role_equivalent_groups = '';
    
    	// Default Email Domain (eg. 'domain.tld')
    	protected $_default_email_domain = '';
    
    	// Port on which AD listens (default 389)
    	protected $_port = 389;
    
    	// Secure the connection between the Drupal and the LDAP servers using TLS.
    	protected $_use_tls = false;
    
    	// network timeout (LDAP_OPT_NETWORK_TIMEOUT) in seconds
    	protected $_network_timeout = 5;
    
    	// Check Login authorization by group membership
    	protected $_authorize_by_group = false;
    
    	// Group name for authorization.
    	protected $_authorization_group = '';
    
    	// Maximum number of failed login attempts before the account is blocked
    	protected $_max_login_attempts = 3;
    
    	// Number of seconds an account is blocked after the maximum number of failed login attempts is reached.
    	protected $_block_time = 30;
    
    	// Send email to user if his account is blocked.
    	protected $_user_notification = false;
    
    	// Send email to admin if a user account is blocked.
    	protected $_admin_notification = false;
    
    	// Administrator's e-mail address(es) where notifications should be sent to.
    	protected $_admin_email = '';
    
    	// Set user's display_name to an AD attribute or to username if left blank
    	// Possible values: description, displayname, mail, sn, cn, givenname, samaccountname, givenname sn
    	protected $_display_name = '';
    
    	// Enable/Disable password changes
    	protected $_enable_password_change = false;
    
    	// How to deal with duplicate email addresses
    	protected $_duplicate_email_prevention = ADI_DUPLICATE_EMAIL_ADDRESS_PREVENT;
    
    	// Update users description if $_auto_update_user is true
    	protected $_auto_update_description = false;
    
    	// default attributes to be read from AD (Windows 2000/20003)
    	protected $_default_user_attributes = array (
    	    'cn', // Common Name
    	    'givenname', // First name
    	    'sn', // Last name
    		'displayname',  // Display name
    		'description', // Description
    		'mail', // E-mail
    		'samaccountname', // User logon name
    		'userprincipalname', // userPrincipalName
    		'useraccountcontrol' // userAccountControl
    	);
    
    	// List of additional user attributes that can be defined by the admin
    	// The attributes are seperated by a new line and have the format:
    	//   <Attribute name>:<type>
    	// where type can be one of the following: string, integer, bool, image, time, timestamp
    	//   thumbnailphoto:image
    	//   whencreated:time
    	protected $_additional_user_attributes = '';
    
    	// Merged array of _user_attributes and _additional_user_attributes
    	protected $_all_user_attributes = array();
    
    	// Add all user attributes from AD to WP table usermeta
    	protected $_write_usermeta = true;
    
    	// Prefix for user meta Data from AD
    	protected $_usermeta_prefix = 'adi_';
    
    	// Overwrite local values even if values in Active Directory are empty.
    	protected $_usermeta_empty_overwrite = false;
    
    	// Enable Sync Back
    	protected $_syncback = false;
    
    	// Use global Sync Back User
    	protected $_syncback_use_global_user = false;
    
    	// Account name of global sync back user
    	protected $_syncback_global_user = '';
    
    	// Password of global sync back user
    	protected $_syncback_global_pwd = '';
    
    	// Show AD attributes in user profile
    	protected $_show_attributes = false;
    
    	// List of AD attributes in the order they should appear on users profile page
    	// Attributes are separated by semicolon or linefeed / newline and have to format:
    	//   <Attribute name>:<desription>
    	// <description> is used on the profile page
    	protected $_attributes_to_show = '';
    
    	// Use the real password when a user is created
    	protected $_no_random_password = false;
    
    	// Update password on every successfull login
    	protected $_auto_update_password = false;
    
    	// Enable lost password recovery
    	protected $_enable_lost_password_recovery = false;
    
    	// enable Bulk Import
    	protected $_bulkimport_enabled = false;
    
    	// AUTHCODE for Bulk Import. Bulk Import will only work, if this AUTHCODE is send as as get-parameter to bulkimport.php
    	protected $_bulkimport_authcode = '';
    
    	// generate a new AUTHCODE for Bulk Import
    	protected $_bulkimport_new_authcode = false;
    
    	// Import members of these security groups (separated by semicolons)
    	protected $_bulkimport_security_groups = '';
    
    	// name of Bulk Import User in Active Directory
    	protected $_bulkimport_user = '';
    
    	// password for Bulk Import User (will be stored encrypted)
    	protected $_bulkimport_pwd = '';
    
    	// use user disabling
    	protected $_disable_users = false;
    
    	// use local (WordPress) password as fallback if authentication against AD fails
    	protected $_fallback_to_local_password = false;
    
    	// show disabled and ADI user status on user list
    	protected $_show_user_status = true;
    
    	// Prevent email change by ADI Users (not for admins)
    	protected $_prevent_email_change = false;
    
    	// protected $_sso_enabled = false; // TODO: for auto login/SSO feature, has to be added to _load_options(), admin.php etc.
    
    	// All options and its types
    	// Has to be static for static call of method uninstall()
    	protected static $_all_options = array(
    
    			array('name' => 'AD_Integration_version', 'type' => 'string'),
    
    			// Server
    			array('name' => 'AD_Integration_domain_controllers', 'type' => 'string'),
    			array('name' => 'AD_Integration_port', 'type' => 'int'),
    			array('name' => 'AD_Integration_use_tls', 'type' => 'bool'),
    			array('name' => 'AD_Integration_network_timeout', 'type' => 'integer'),
    			array('name' => 'AD_Integration_base_dn', 'type' => 'string'),
    
    			// User
    			array('name' => 'AD_Integration_account_suffix', 'type' => 'string'),
    			array('name' => 'AD_Integration_append_suffix_to_new_users', 'type' => 'bool'),
    			array('name' => 'AD_Integration_auto_create_user', 'type' => 'bool'),
    			array('name' => 'AD_Integration_auto_update_user', 'type' => 'bool'),
    			array('name' => 'AD_Integration_auto_update_description', 'type' => 'bool'),
    			array('name' => 'AD_Integration_default_email_domain', 'type' => 'string'),
    			array('name' => 'AD_Integration_duplicate_email_prevention', 'type' => 'string'),
    			array('name' => 'AD_Integration_prevent_email_change', 'type' => 'bool'),
    			array('name' => 'AD_Integration_display_name', 'type' => 'string'),
    			array('name' => 'AD_Integration_show_user_status', 'type' => 'bool'),
    			array('name' => 'AD_Integration_enable_password_change', 'type' => 'bool'),
    			array('name' => 'AD_Integration_no_random_password', 'type' => 'bool'),
    			array('name' => 'AD_Integration_auto_update_password', 'type' => 'bool'),
    
    			// Authorization
    			array('name' => 'AD_Integration_authorize_by_group', 'type' => 'bool'),
    			array('name' => 'AD_Integration_authorization_group', 'type' => 'string'),
    			array('name' => 'AD_Integration_role_equivalent_groups', 'type' => 'string'),
    			//add_settings_field('plugin_textarea_string', 'Large Textbox!', 'setting_textarea_fn', __FILE__, 'main_section');
    
    			// Security
    			array('name' => 'AD_Integration_fallback_to_local_password', 'type' => 'bool'),
    			array('name' => 'AD_Integration_enable_lost_password_recovery', 'type' => 'bool'),
    			array('name' => 'AD_Integration_max_login_attempts', 'type' => 'int'),
    			array('name' => 'AD_Integration_block_time', 'type' => 'int'),
    			array('name' => 'AD_Integration_user_notification', 'type' => 'bool'),
    			array('name' => 'AD_Integration_admin_notification', 'type' => 'bool'),
    			array('name' => 'AD_Integration_admin_email', 'type' => 'string'),
    
    			// User Meta
    			array('name' => 'AD_Integration_additional_user_attributes', 'type' => 'string'),
    			array('name' => 'AD_Integration_usermeta_empty_overwrite', 'type' => 'bool'),
    			array('name' => 'AD_Integration_show_attributes', 'type' => 'bool'),
    			array('name' => 'AD_Integration_attributes_to_show', 'type' => 'bool'),
    			array('name' => 'AD_Integration_syncback', 'type' => 'bool'),
    			array('name' => 'AD_Integration_syncback_use_global_user', 'type' => 'bool'),
    			array('name' => 'AD_Integration_syncback_global_user', 'type' => 'string'),
    			array('name' => 'AD_Integration_syncback_global_pwd', 'type' => 'string'),
    
    			// Bulk Import
    			array('name' => 'AD_Integration_bulkimport_enabled', 'type' => 'bool'),
    			array('name' => 'AD_Integration_bulkimport_authcode', 'type' => 'string'),
    			array('name' => 'AD_Integration_bulkimport_new_authcode', 'type' => 'bool'),
    			array('name' => 'AD_Integration_bulkimport_security_groups', 'type' => 'string'),
    			array('name' => 'AD_Integration_bulkimport_user', 'type' => 'string'),
    			array('name' => 'AD_Integration_bulkimport_pwd', 'type' => 'string'),
    			array('name' => 'AD_Integration_disable_users', 'type' => 'bool')
    		);
    
    	public $errors = false;
    
    	/**
    	 * Constructor
    	 */
    	public function __construct() {
    		global $wp_version, $wpmu_version, $wpdb, $wpmuBaseTablePrefix;
    
    		if (!defined('IS_WPMU')) {
    			define('IS_WPMU', ($wpmu_version != ''));
    		}
    
    		// define folder constant
    		if (!defined('ADINTEGRATION_FOLDER')) {
    			define('ADINTEGRATION_FOLDER', basename(dirname(__FILE__)));
    		}
    
    		$this->setLogFile(dirname(__FILE__).'/adi.log');
    
    		$this->errors = new WP_Error();
    
    		// Load Options
    		$this->_load_options();
    
    		// Generate authcode if necessary
    		if (strlen($this->_bulkimport_authcode) < 20) {
    			$this->_generate_authcode();
    		}
    
    		if (isset($_GET['activate']) and $_GET['activate'] == 'true') {
    			add_action('init', array(&$this, 'initialize_options'));
    		}
    
    		add_action('admin_init', array(&$this, 'register_adi_settings'));
    
    		add_action('admin_menu', array(&$this, 'add_options_page'));
    		add_filter('contextual_help', array(&$this, 'contextual_help'), 10, 2);
    
    		// DO WE HAVE LDAP SUPPORT?
    		if (function_exists('ldap_connect')) {
    
    			add_filter('authenticate', array(&$this, 'authenticate'), 10, 3);
    
    			if (!$this->_enable_lost_password_recovery) {
    				add_action('lost_password', array(&$this, 'disable_function'));
    				add_action('retrieve_password', array(&$this, 'disable_function'));
    				add_action('password_reset', array(&$this, 'disable_function'));
    			}
    
    		    add_action('admin_print_styles', array(&$this, 'load_styles'));
    		    add_action('admin_print_scripts', array(&$this, 'load_scripts'));
    
    		    // Add new column to the user list
    		    if ($this->_show_user_status) {
    				add_filter( 'manage_users_columns', array( &$this, 'manage_users_columns' ) );
    				add_filter( 'manage_users_custom_column', array( &$this, 'manage_users_custom_column' ), 10, 3 );
    			}
    
    			// actions for user disabling
    			add_action('personal_options_update', array(&$this, 'profile_update_disable_user'));
    			add_action('edit_user_profile_update', array(&$this, 'profile_update_disable_user'));
    			add_action('edit_user_profile', array(&$this, 'show_user_profile_disable_user'));
    			add_action('show_user_profile', array(&$this, 'show_user_profile_disable_user'));
    
    		    // Sync Back?
    		    if ($this->_syncback === true) {
    				add_action('personal_options_update', array(&$this, 'profile_update'));
    				add_action('edit_user_profile_update', array(&$this, 'profile_update'));
    		    }
    
    			// TODO: auto_login feature must be tested
    			/*
    			if ($this->_auto_login) {
    				add_action('init', array(&$this, 'auto_login'));
    			}
    			*/
    
    			add_filter('check_password', array(&$this, 'override_password_check'), 10, 4);
    
    			// Is local password change disallowed?
    			if (!$this->_enable_password_change) {
    
    				// disable password fields
    				add_filter('show_password_fields', array(&$this, 'disable_password_fields'));
    
    				// generate a random password for manually added users
    				add_action('check_passwords', array(&$this, 'generate_password'), 10, 3);
    			}
    
    			if (!class_exists('adLDAP')) {
    				require 'ad_ldap/adLDAP.php';
    			}
    		} else {
    			$this->_log(ADI_LOG_WARN,'openLDAP not installed or activated in PHP.');
    		}
    
    		// Adding AD attributes to profile page
    		if ($this->_show_attributes) {
    			add_action( 'edit_user_profile', array(&$this, 'show_AD_attributes'));
    			add_action( 'show_user_profile', array(&$this, 'show_AD_attributes'));
    		}
    
    		$this->_all_user_attributes = $this->_get_user_attributes();
    
    		// Prevent email change
    		if ($this->_prevent_email_change) {
    			add_action( 'edit_user_profile', array(&$this, 'user_profile_prevent_email_change')); // cosmetic
    			add_action( 'show_user_profile', array(&$this, 'user_profile_prevent_email_change')); // cosmetic
    			add_action( 'user_profile_update_errors', array(&$this, 'prevent_email_change'), 10, 3 ); // true prevention
    		}
    	}
    
    	public function load_styles() {
    		wp_register_style('adintegration', plugins_url('css/adintegration.css', __FILE__ )  ,false, '1.7.1', 'screen');
    		wp_enqueue_style('adintegration');
    	}
    
    	public function load_scripts() {
    		wp_enqueue_script('jquery-ui-tabs');   // this is a wp default script
    		wp_enqueue_script('jquery-ui-dialog'); // this is a wp default script
    	}
    
    	/*************************************************************
    	 * Plugin hooks
    	 *************************************************************/
    
    	/**
    	 * Add options for this plugin to the database.
    	 */
    	public function initialize_options() {
    
    		if (IS_WPMU) {
    			if (is_super_admin()) {
    				add_site_option('AD_Integration_account_suffix', '');
    				add_site_option('AD_Integration_auto_create_user', false);
    				add_site_option('AD_Integration_auto_update_user', false);
    				add_site_option('AD_Integration_append_suffix_to_new_users', false);
    				add_site_option('AD_Integration_domain_controllers', '');
    				add_site_option('AD_Integration_base_dn', '');
    				add_site_option('AD_Integration_role_equivalent_groups', '');
    				add_site_option('AD_Integration_default_email_domain', '');
    				add_site_option('AD_Integration_port', '389');
    				add_site_option('AD_Integration_use_tls', false);
    				add_site_option('AD_Integration_network_timeout', 5);
    
    				// User
    				add_site_option('AD_Integration_authorize_by_group', false);
    				add_site_option('AD_Integration_authorization_group', '');
    				add_site_option('AD_Integration_display_name', '');
    				add_site_option('AD_Integration_enable_password_change', false);
    				add_site_option('AD_Integration_duplicate_email_prevention', ADI_DUPLICATE_EMAIL_ADDRESS_PREVENT);
    				add_site_option('AD_Integration_prevent_email_change', false);
    				add_site_option('AD_Integration_auto_update_description', false);
    				add_site_option('AD_Integration_show_user_status', false);
    
    				add_site_option('AD_Integration_show_attributes', false);
    				add_site_option('AD_Integration_attributes_to_show', '');
    				add_site_option('AD_Integration_additionl_user_attributes', '');
    				add_site_option('AD_Integration_usermeta_empty_overwrite', false);
    				add_site_option('AD_Integration_no_random_password', false);
    				add_site_option('AD_Integration_auto_update_password', false);
    
    				add_site_option('AD_Integration_max_login_attempts', '3');
    				add_site_option('AD_Integration_block_time', '30');
    				add_site_option('AD_Integration_user_notification', false);
    				add_site_option('AD_Integration_admin_notification', false);
    				add_site_option('AD_Integration_admin_email', '');
    				add_site_option('AD_Integration_disable_users', false);
    				add_site_option('AD_Integration_fallback_to_local_password', false);
    				add_site_option('AD_Integration_enable_lost_password_recovery', false);
    
    				add_site_option('AD_Integration_syncback', false);
    				add_site_option('AD_Integration_syncback_use_global_user', false);
    				add_site_option('AD_Integration_syncback_global_user', '');
    				add_site_option('AD_Integration_syncback_global_pwd', '');
    
    				add_site_option('AD_Integration_bulkimport_enabled', false);
    				add_site_option('AD_Integration_bulkimport_authcode', '');
    				add_site_option('AD_Integration_bulkimport_new_authcode', false);
    				add_site_option('AD_Integration_bulkimport_security_groups', '');
    				add_site_option('AD_Integration_bulkimport_user', '');
    				add_site_option('AD_Integration_bulkimport_pwd', '');
    			}
    		} else {
    			if (current_user_can('manage_options')) {
    				add_option('AD_Integration_account_suffix', '');
    				add_option('AD_Integration_auto_create_user', false);
    				add_option('AD_Integration_auto_update_user', false);
    				add_option('AD_Integration_append_suffix_to_new_users', false);
    				add_option('AD_Integration_domain_controllers', '');
    				add_option('AD_Integration_base_dn', '');
    				add_option('AD_Integration_role_equivalent_groups', '');
    				add_option('AD_Integration_default_email_domain', '');
    				add_option('AD_Integration_port', '389');
    				add_option('AD_Integration_use_tls', false);
    				add_option('AD_Integration_network_timeout', 5);
    
    				add_option('AD_Integration_authorize_by_group', false);
    				add_option('AD_Integration_authorization_group', '');
    				add_option('AD_Integration_display_name', '');
    				add_option('AD_Integration_enable_password_change', false);
    				add_option('AD_Integration_duplicate_email_prevention', ADI_DUPLICATE_EMAIL_ADDRESS_PREVENT);
    				add_option('AD_Integration_prevent_email_change', false);
    				add_option('AD_Integration_auto_update_description', false);
    				add_option('AD_Integration_show_user_status', false);
    
    				add_option('AD_Integration_show_attributes', false);
    				add_option('AD_Integration_attributes_to_show', '');
    				add_option('AD_Integration_additional_user_attributes', '');
    				add_option('AD_Integration_usermeta_empty_overwrite', false);
    
    				add_option('AD_Integration_no_random_password', false);
    				add_option('AD_Integration_auto_update_password', false);
    
    				add_option('AD_Integration_max_login_attempts', '3');
    				add_option('AD_Integration_block_time', '30');
    				add_option('AD_Integration_user_notification', false);
    				add_option('AD_Integration_admin_notification', false);
    				add_option('AD_Integration_admin_email', '');
    				add_option('AD_Integration_disable_users', false);
    				add_option('AD_Integration_fallback_to_local_password', false);
    				add_option('AD_Integration_enable_lost_password_recovery', false);
    
    				add_option('AD_Integration_syncback', false);
    				add_option('AD_Integration_syncback_use_global_user', false);
    				add_option('AD_Integration_syncback_global_user', '');
    				add_option('AD_Integration_syncback_global_pwd', '');
    
    				add_option('AD_Integration_bulkimport_enabled', false);
    				add_option('AD_Integration_bulkimport_authcode', '');
    				add_option('AD_Integration_bulkimport_new_authcode', false);
    				add_option('AD_Integration_bulkimport_security_groups', '');
    				add_option('AD_Integration_bulkimport_user', '');
    				add_option('AD_Integration_bulkimport_pwd', '');
    			}
    		}
    
    	}
    
    	public function register_adi_settings()
    	{
    
    		// Server
    		register_setting('ADI-server-settings',	'AD_Integration_domain_controllers');
    		register_setting('ADI-server-settings', 'AD_Integration_port', array(&$this, 'sanitize_port'));
    		register_setting('ADI-server-settings', 'AD_Integration_use_tls', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-server-settings', 'AD_Integration_base_dn');
    		register_setting('ADI-server-settings', 'AD_Integration_network_timeout', array(&$this, 'sanitize_network_timeout'));
    
    		// User
    		register_setting('ADI-user-settings', 'AD_Integration_auto_create_user', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_auto_update_user', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_auto_update_description', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_default_email_domain', array(&$this, 'sanitize_default_email_domain'));
    		register_setting('ADI-user-settings', 'AD_Integration_account_suffix', array(&$this, 'sanitize_account_suffix'));
    		register_setting('ADI-user-settings', 'AD_Integration_append_suffix_to_new_users', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_display_name');
    		register_setting('ADI-user-settings', 'AD_Integration_enable_password_change', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_duplicate_email_prevention');
    		register_setting('ADI-user-settings', 'AD_Integration_prevent_email_change', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_no_random_password', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_auto_update_password', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-user-settings', 'AD_Integration_show_user_status', array(&$this, 'sanitize_bool'));
    
    		// Authorization
    		register_setting('ADI-auth-settings', 'AD_Integration_authorize_by_group', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-auth-settings', 'AD_Integration_authorization_group');
    		register_setting('ADI-auth-settings', 'AD_Integration_role_equivalent_groups', array(&$this, 'sanitize_role_equivalent_groups'));
    
    		// Security
    		register_setting('ADI-security-settings', 'AD_Integration_fallback_to_local_password', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-security-settings', 'AD_Integration_enable_lost_password_recovery', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-security-settings', 'AD_Integration_max_login_attempts', array(&$this, 'sanitize_max_login_attempts'));
    		register_setting('ADI-security-settings', 'AD_Integration_block_time', array(&$this, 'sanitize_block_time'));
    		register_setting('ADI-security-settings', 'AD_Integration_user_notification', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-security-settings', 'AD_Integration_admin_notification', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-security-settings', 'AD_Integration_admin_email', array(&$this, 'sanitize_admin_email'));
    
    		// User Meta
    		register_setting('ADI-usermeta-settings', 'AD_Integration_show_attributes', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_attributes_to_show', array(&$this, 'sanitize_attributes_to_show'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_additional_user_attributes', array(&$this, 'sanitize_additional_user_attributes'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_usermeta_empty_overwrite', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_syncback', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_syncback_use_global_user', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_syncback_global_user', array(&$this, 'sanitize_syncback_global_user'));
    		register_setting('ADI-usermeta-settings', 'AD_Integration_syncback_global_pwd', array(&$this, 'sanitize_syncback_global_user_pwd'));
    
    		// Bulk Import
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_bulkimport_enabled', array(&$this, 'sanitize_bool'));
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_bulkimport_new_authcode', array(&$this, 'sanitize_new_authcode'));
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_bulkimport_security_groups');
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_bulkimport_user', array(&$this, 'sanitize_bulkimport_user'));
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_bulkimport_pwd', array(&$this, 'sanitize_bulkimport_user_pwd'));
    		register_setting('ADI-bulkimport-settings', 'AD_Integration_disable_users', array(&$this, 'sanitize_bool'));
    	}
    
    	/**
    	 * Add an options pane for this plugin.
    	 */
    	public function add_options_page() {
    
    		if (IS_WPMU && is_super_admin()) {
    			// WordPress MU
    			if (function_exists('add_submenu_page')) {
    				add_submenu_page('wpmu-admin.php', __('Active Directory Integration'), __('Active Directory Integration'), 'manage_options', 'active-directory-integration', array(&$this, 'display_options_page'));
    			}
    		}
    
    		if (!IS_WPMU) {
    			// WordPress Standard
    			if (function_exists('add_options_page')) {
    				//add_options_page('Active Directory Integration', 'Active Directory Integration', 'manage_options', __FILE__, array(&$this, 'display_options_page'));
    				add_options_page('Active Directory Integration', 'Active Directory Integration', 'manage_options', 'active-directory-integration', array(&$this, 'display_options_page'));
    			}
    		}
    	}
    
    	/**
    	 * If the REMOTE_USER evironment is set, use it as the username.
    	 * This assumes that you have externally authenticated the user.
    	 */
    	public function authenticate($user = NULL, $username = '', $password = '') {
    
    		global $wp_version, $wpmu_version;
    
    		$this->_log(ADI_LOG_INFO,'method authenticate() called');
    
    		if (IS_WPMU) {
    			$version = $wpmu_version;
    		} else {
    			$version = $wp_version;
    		}
    
    		// log debug informations
    		$this->_log(ADI_LOG_INFO,"------------------------------------------\n".
    								 'PHP version: '.phpversion()."\n".
    								 'WP  version: '.$version."\n".
    								 'ADI version: '.ADIntegrationPlugin::ADI_VERSION."\n".
    								 'OS Info    : '.php_uname()."\n".
    								 'Web Server : '.php_sapi_name()."\n".
    								 'adLDAP ver.: '.adLDAP::VERSION."\n".
    								 '------------------------------------------');
    
    		// IMPORTANT!
    		$this->_authenticated = false;
    		$user_id  = NULL;
    		$username = strtolower($username);
    		$password = stripslashes($password);
    
    		// Don't use Active Directory for admin user (ID 1)
    		// $user = get_userdatabylogin($username); // deprecated
    		$user = get_user_by('login', $username);
    
    		if (is_object($user) && ($user->ID == 1)) {
    			$this->_log(ADI_LOG_NOTICE,'User with ID 1 will never be authenticated by Active Directory Integration.');
    			return false;
    		}
    
    		// extract account suffix from username if not set
    		// (after loading of options)
    		// Extended for issue #0043
    		if (strpos($username,'@') !== false) {
    			$this->_log(ADI_LOG_NOTICE,'@domain found.');
    			$parts = explode('@',trim($username));
    			$puser = $parts[0];
    			$pdomain = '@'.$parts[1];
    			if (trim($this->_account_suffix) == '') {
    				// without Account Suffix
    				$username = $puser;
    				$this->_account_suffix = $pdomain;
    				$this->_append_suffix_to_new_users = true;
    				$this->_log(ADI_LOG_NOTICE,'No account suffix set. Using user domain "' . $pdomain . '" as account suffix.');
    			} else {
    				// with Account Suffix
    				// let's see if users domain is in the list of all account suffixes
    				$account_suffix_found = false;
    				$account_suffixes = explode(";", $this->_account_suffix);
    				foreach($account_suffixes AS $account_suffix) {
    					if (trim($account_suffix) == $pdomain) {
    						// user domain same as _account_suffix (leave _append_suffix_to_new_users untouched)
    						$username = $puser;
    						$account_suffix_found = true;
    						$this->_log(ADI_LOG_NOTICE,'user domain "' . $pdomain . '" in list of account suffixes.');
    						break;
    					}
    				}
    				if ($account_suffix_found === false) {
    					//
    					$this->_append_suffix_to_new_users = false;
    					$this->_account_suffix = '';
    					$this->_log(ADI_LOG_NOTICE,'user domain "' . $pdomain . '" NOT in list of account suffixes.');
    				}
    			}
    		}
    
    		$this->_log(ADI_LOG_NOTICE,'username: '.$username);
    		$this->_log(ADI_LOG_NOTICE,'password: **not shown**');
    
    		// Log informations
    		$this->_log(ADI_LOG_INFO,"Options for adLDAP connection:\n".
    					  "- account_suffix: $this->_account_suffix\n".
    					  "- base_dn: $this->_base_dn\n".
    					  "- domain_controllers: $this->_domain_controllers\n".
    					  "- ad_port: $this->_port\n".
    					  "- use_tls: ".(int) $this->_use_tls."\n".
    					  "- network timeout: ". $this->_network_timeout);
    
    		// Connect to Active Directory
    		try {
    			$this->_adldap = @new adLDAP(array(
    						"base_dn" => $this->_base_dn,
    						"domain_controllers" => explode(';', $this->_domain_controllers),
    						"ad_port" => $this->_port,               		// AD port
    						"use_tls" => $this->_use_tls,             		// secure?
    						"network_timeout" => $this->_network_timeout	// network timeout*/
    						));
    		} catch (Exception $e) {
        		$this->_log(ADI_LOG_ERROR,'adLDAP exception: ' . $e->getMessage());
        		return false;
    		}
    
    		$this->_log(ADI_LOG_NOTICE,'adLDAP object created.');
    
    		// Check for maximum login attempts
    		$this->_log(ADI_LOG_INFO,'max_login_attempts: '.$this->_max_login_attempts);
    		if ($this->_max_login_attempts > 0) {
    			$failed_logins = $this->_get_failed_logins_within_block_time($username);
    			$this->_log(ADI_LOG_INFO,'users failed logins: '.$failed_logins);
    			if ($failed_logins >= $this->_max_login_attempts) {
    				$this->_authenticated = false;
    
    				$this->_log(ADI_LOG_ERROR,'Authentication failed again');
    				$this->_log(ADI_LOG_ERROR,"Account '$username' blocked for $this->_block_time seconds");
    
    				// e-mail notfications if user is blocked
    				if ($this->_user_notification) {
    					$this->_notify_user($username);
    					$this->_log(ADI_LOG_NOTICE,"Notification send to user.");
    				}
    				if ($this->_admin_notification) {
    					$this->_notify_admin($username);
    					$this->_log(ADI_LOG_NOTICE,"Notification send to admin(s).");
    				}
    
    				// Show the blocking page to the user (only if we are not in debug/log mode)
    				if ($this->_loglevel == ADI_LOG_NONE) {
    					$this->_display_blocking_page($username);
    				}
    				die(); // important !
    			}
    		}
    
    		// This is where the action is.
    		$account_suffixes = explode(";",$this->_account_suffix);
    		foreach($account_suffixes AS $account_suffix) {
    			$account_suffix = trim($account_suffix);
    			$this->_log(ADI_LOG_NOTICE,'trying account suffix "'.$account_suffix.'"');
    			$this->_adldap->set_account_suffix($account_suffix);
    			if ( $this->_adldap->authenticate($username, $password) === true ) // Authenticate
    			{
    				$this->_log(ADI_LOG_NOTICE,'Authentication successfull for "' . $username . $account_suffix.'"');
    				$this->_authenticated = true;
    				break;
    			}
    		}
    
    		if ( $this->_authenticated == false )
    		{
    			$this->_log(ADI_LOG_ERROR,'Authentication failed');
    			$this->_authenticated = false;
    			$this->_store_failed_login($username);
    			return false;
    		}
    
    		// Cleanup old database entries
    		$this->_cleanup_failed_logins($username);
    
    		// Check the authorization
    		if ($this->_authorize_by_group) {
    			if ($this->_check_authorization_by_group($username)) {
    				$this->_authenticated = true;
    			} else {
    				$this->_authenticated = false;
    				return false;
    			}
    		}
    
    		$ad_username = $username;
    
    		// should the account suffix be used for the new username?
    		if ($this->_append_suffix_to_new_users) {
    			$username .= $account_suffix;
    		}
    
    		// getting user data (again!)
    		// $user = get_userdatabylogin($username); // deprecated
    		$user = get_user_by('login', $username);
    
    		// role
    		$user_roles = $this->_get_user_role_equiv($ad_username); // important: use $ad_username not $username
    
    		// userinfo from AD
    		$this->_log(ADI_LOG_DEBUG, 'ATTRIBUTES TO LOAD: '.print_r($this->_all_user_attributes, true));
    		$userinfo = $this->_adldap->user_info($ad_username, $this->_all_user_attributes);
    		$userinfo = $userinfo[0];
    		$this->_log(ADI_LOG_DEBUG,"USERINFO[0]: \n".print_r($userinfo,true));
    
    		// get display name
    		$display_name = $this->_get_display_name_from_AD($username, $userinfo);
    
    		// Create new users automatically, if configured
    		if (!$user OR ($user->user_login != $username)) {
    			$hasRole = FALSE;
    			if(USE_MULTI_ROLES){
    				$hasRole = sizeof($user_roles) > 1;
    			}else{
    				$user_roles 	= trim($user_roles);
    				$hasRole 	= $user_roles != '';
    			}
    
    			if ($this->_auto_create_user || $hasRole ) {
    				// create user
    				$user_id = $this->_create_user($ad_username, $userinfo, $display_name, $user_roles, $password);
    			} else {
    				// Bail out to avoid showing the login form
    				$this->_log(ADI_LOG_ERROR,'This user exists in Active Directory, but has not been granted access to this installation of WordPress.');
    				return new WP_Error('invalid_username', __('<strong>ERROR</strong>: This user exists in Active Directory, but has not been granted access to this installation of WordPress.'));
    			}
    
    		} else {
    
    			//  Update known users if configured
    			if ($this->_auto_create_user AND $this->_auto_update_user) {
    				// Update users role
    				$user_id = $this->_update_user($ad_username, $userinfo, $display_name, $user_roles, $password);
    			}
    		}
    
    		// load user object
    		if (!$user_id) {
    			if (version_compare($wp_version, '3.1', '<')) {
    				require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'registration.php');
    			}
    			$user_id = username_exists($username);
    			$this->_log(ADI_LOG_NOTICE,'user_id: '.$user_id);
    		}
    		$user = new WP_User($user_id);
    
    		// user disabled?
    		if (get_user_meta($user_id, 'adi_user_disabled', true)) {
    			$this->_log(ADI_LOG_WARN,'User with ID ' . $user_id .' is disabled.');
    			$this->_authenticated = false;
    			return false;
    		}
    
    		$this->_log(ADI_LOG_NOTICE,'FINISHED');
    		return $user;
    	}
    
    	/*
    	 * Use local (WordPress) password check if needed and allowed
    	 */
    	public function override_password_check($check, $password, $hash, $user_id) {
    
    		// Always use local password handling for user_id 1 (admin)
    		if ($user_id == 1) {
    			$this->_log(ADI_LOG_DEBUG,'UserID 1: using local (WordPress) password check.');
    			return $check;
    		}
    
    		// return true for users authenticated by ADI (should never happen, but who knows?)
    		if ( $this->_authenticated == true )
    		{
    			$this->_log(ADI_LOG_DEBUG,'User successfully authenticated by ADI: override local (WordPress) password check.');
    			return true;
    		}
    
    		// return false if user is disabled
    		if (get_user_meta($user_id,'adi_user_disabled', true)) {
    			$reason = get_user_meta($user_id,'adi_user_disabled_reason', true);
    			$this->_log(ADI_LOG_DEBUG,'User is disabled. Reason: '.$reason);
    			return false;
    		}
    
    		// Only check for local password if this is not an AD user and if fallback to local password is active
    		$usercheck =  get_user_meta($user_id,'adi_samaccountname', true);
    		if ($usercheck != '') {
    			if ($this->_fallback_to_local_password) {
    				$this->_log(ADI_LOG_DEBUG,'User from AD. Falling back to local (WordPress) password check.');
    				return $check;
    			} else {
    				$this->_log(ADI_LOG_DEBUG,'User from AD and fallback to local (WordPress) password deactivated. Authentication failed.');
    				return false;
    			}
    		}
    
    		// use local password check in all other cases
    		$this->_log(ADI_LOG_DEBUG,'Using local (WordPress) password check.');
    		return $check;
    	}
    
    	/**
    	 * Auto Login / Single Sign On
    	 * Code by Alex Nolan
    	 */
    	public function auto_login() {
    		// TODO: This has to be tested - carefully
    		// looks pretty insecure
    		/*
    		if (!is_user_logged_in() && isset($_SERVER['LOGON_USER'])) {
    			$user_login = substr($_SERVER['LOGON_USER'], strrpos($_SERVER['LOGON_USER'],'\\')+1, strlen($_SERVER['LOGON_USER'])-strrpos($_SERVER['LOGON_USER'],'\\'));
    			$user = get_userdatabylogin($user_login); // TODO: deprecated
    			$user_id = $user->ID;
    			wp_set_current_user($user_id, $user_login);
    			wp_set_auth_cookie($user_id);
    			do_action('wp_login', $user_login);
    		}
    		*/
        }
    
    	/*
    	 * Generate a password for the user. This plugin does not
    	 * require the user to enter this value, but we want to set it
    	 * to something nonobvious.
    	 */
    	public function generate_password($username, $password1, $password2) {
    		$password1 = $password2 = $this->_get_password();
    	}
    
    	/*
    	 * Used to disable certain display elements, e.g. password
    	 * fields on profile screen.
    	 */
    	public function disable_password_fields($show_password_fields) {
    		return false;
    	}
    
    	/*
    	 * Used to disable certain login functions, e.g. retrieving a
    	 * user's password.
    	 */
    	public function disable_function() {
    		die('Disabled');
    	}
    
    	/**
    	 * Shows the contexual help on the options/admin screen.
    	 *
    	 * @param $help
    	 * @param $screen
    	 * @return string help message
    	 */
    	public function contextual_help ($help, $screen) {
    		if ($screen == 'settings_page_' . ADINTEGRATION_FOLDER . '/ad-integration'
    		                 || $screen == 'wpmu-admin_page_' . ADINTEGRATION_FOLDER . '/ad-integration') {
    			$help .= '<h5>' . __('Active Directory Integration Help','ad-integration') . '</h5><div class="metabox-prefs">';
    			$help .= '<a href="http://blog.ecw.de/wp-ad-integration" target="_blank">'.__ ('Overview','ad-integration').'</a><br/>';
    			$help .= '<a href="http://wordpress.org/extend/plugins/active-directory-integration/faq/" target="_blank">'.__ ('FAQ', 'ad-integration').'</a><br/>';
    			$help .= '<a href="http://wordpress.org/extend/plugins/active-directory-integration/changelog/" target="_blank">'.__ ('Changelog', 'ad-integration').'</a><br/>';
    			$help .= '<a href="http://wordpress.org/tags/active-directory-integration" target="_blank">'.__ ('Support-Forum', 'ad-integration').'</a><br/>';
    			$help .= '<a href="http://bt.ecw.de/" target="_blank">'.__ ('Bug Tracker', 'ad-integration').'</a><br/>';
    			$help .= '</div>';
    		}
    		return $help;
    	}
    
    	/**
    	 * Generate an error message for the users if Sync Back failed.
    	 */
    	public function generate_error(&$errors, $update, &$user) {
    		$errors = $this->errors;
    	}
    
    	public function setLogLevel($level = 0) {
    		$this->_loglevel = (int)$level;
    	}
    
    	public function setLogFile($filename) {
    		$this->_logfile = $filename;
    	}
    
    	public function disableDebug() {
    		echo '<pre>';
    		$this->debug = false;
    		echo '</pre>';
    	}
    
    	/**
    	 * HOOKS: Actions and Filters
    	 */
    
    	/**
    	 * Show the disable user checkbox if needed
    	 * Action(s): edit_user_profile, show_user_profile
    	 *
    	 * @param object $user
    	 */
    	public function show_user_profile_disable_user($user) {
    
    		global $user_ID;
    
    		// User disabled only visible for admins and not for user with ID 1 (admin) and not for ourselves
    		if (current_user_can('level_10') && ($user->ID != 1) && ($user->ID != $user_ID)) {
    
    			// Load up the localization file if we're using WordPress in a different language
    			// Place it in this plugin's folder and name it "ad-integration-[value in wp-config].mo"
    			load_plugin_textdomain( 'ad-integration', false, dirname( plugin_basename( __FILE__ ) ) );
    
    			$user_disabled = get_user_meta($user->ID, 'adi_user_disabled', true);
    			?>
    			<input type="hidden" name="adi_user_disabling" value="1" />
    			<table class="form-table">
    				<tr>
    					<th><label><?php _e('User Disabled','ad-integration');?></label></th>
    					<td>
    						<input type="checkbox" name="adi_user_disabled" id="adi_user_disabled"<?php if ($user_disabled) echo ' checked="checked"' ?> value="1" />
    						<?php _e('If selected, the user can not log in and his e-mail address will be changed for security reasons. The e-mail address is restored if the user is reenabled.','ad-integration'); ?>
    						<?php
    						if ($user_disabled) {
    							?>
    							<p class="description"><?php _e('Information on last disabling: ', 'ad-integration');
    							echo get_user_meta($user->ID, 'adi_user_disabled_reason', true);?></p>
    							<?php
    						}?>
    						<p class="description"><?php _e('Attention: This flag is automatically set (or unset) by Bulk Import and its state may change on next run of Bulk Import.','ad-integration'); ?></p>
    					</td>
    				</tr>
    			</table>
    		<?php
    		}
    	}
    
    	/**
    	 * Update disable status as set on profile page
    	 * Action(s): personal_options_update, edit_user_profile_update
    	 *
    	 * @param object $user_id
    	 */
    	public function profile_update_disable_user($user_id)
    	{
    		global $user_login;
    
    		// Disable User
    		if (isset($_POST['adi_user_disabling'])) {
    			if (isset($_POST['adi_user_disabled'])) {
    				// Disable if user was not disabled only
    				if (get_user_meta($user_id, 'adi_user_disabled', true) == false) {
    					$this->_disable_user($user_id, sprintf(__('User manually disabled by "%s".', 'ad-integration'), $user_login));
    				}
    			} else {
    				// Reenable if user was disabled only
    				if (get_user_meta($user_id, 'adi_user_disabled', true) == true) {
    					$this->_enable_user($user_id);
    				}
    			}
    		}
    	}
    
    	/*
    	 * Display the options for this plugin.
    	 */
    	public function display_options_page() {
    		include dirname( __FILE__ ) .'/admin.php';
    	}
    
    	/**
    	 * Show defined AD attributes on profile page
    	 */
    	public function show_AD_attributes($user) {
    
    		global $user_ID;
    
    		// Load up the localization file if we're using WordPress in a different language
    		// Place it in this plugin's folder and name it "ad-integration-[value in wp-config].mo"
    		load_plugin_textdomain( 'ad-integration', false, dirname( plugin_basename( __FILE__ ) ) );
    
    		// Additional Attributes
    		if ($this->_show_attributes) {
    
    			$all_attributes = $this->_get_attributes_array();
    
    			$list = str_replace(";", "\n", $this->_attributes_to_show);
    			$list = explode("\n", $list);
    
    			$attributes = array();
    			foreach($list AS $line) {
    				$parts = explode(':',$line);
    				if (isset($parts[0])) {
    					if (trim($parts[0] != '')) {
    						$attributes[] = trim($parts[0]);
    					}
    				}
    			}
    
    			if (count($attributes) > 0) {
    				wp_nonce_field('ADI_UserProfileUpdate','ADI_UserProfileUpdate_NONCE');
    				echo '<h3>' . __('Additional Informations', 'ad-integration').'</h3>';
    
    				$adi_samaccountname = get_user_meta($user->ID, 'adi_samaccountname', true);
    				?>
    				<input type="hidden" name="adi_samaccountname" value="<?php echo $adi_samaccountname; ?>" />
    				<table class="form-table">
    				<?php
    				foreach ($attributes AS $attribute) {
    					$no_attribute = false;
    					if (isset($all_attributes[$attribute]['metakey'])) {
    						$metakey = $all_attributes[$attribute]['metakey'];
    						$value = get_user_meta($user->ID, $metakey, true);
    					} else {
    						$value = '';
    						$no_attribute = true;
    					}
    
    					if (isset($all_attributes[$attribute]['description'])) {
    						$description = trim($all_attributes[$attribute]['description']);
    					} else {
    						// if value is empty and we've found no description then this is no attribute
    						if ($value == '') {
    							$no_attribute = true;
    						}
    					}
    
    					?>
    					<tr>
    					  <?php if ($no_attribute) { // use as sub-headline ?>
    					  	<th colspan="2">
    					  	  <?php echo $description; ?>
    					  	</th>
    					  <?php } else {?>
    					    <th><label for="<?php echo $metakey ?>"><?php echo $description; ?></label></th>
    					    <td><?php
    					    // editable only if this is our own personal profile page if Global Sync Back user is not set.
    					    if (($this->_syncback == true)
    					    		&& isset($all_attributes[$attribute]['sync'])
    					        	&& ($all_attributes[$attribute]['sync'] == true)
    					        	&& (($user->ID == $user_ID) || ($this->_syncback_use_global_user === true))) {
    					        // use textarea if we have a list
    					        if (isset($all_attributes[$attribute]['type']) && ($all_attributes[$attribute]['type'] == 'list')) {
    					        	echo '<textarea name="'.$metakey.'" id="'.$metakey.'" cols="30" rows="3">'.esc_html($value).'</textarea>';
    					        } else {
    						    	echo '<input type="text" name="'.$metakey.'" id="'.$metakey.'" value="'.esc_html($value).'" class="regular-text code">';
    					        }
    					    } else {
    					    	echo nl2br(esc_html($value));
    					  	}
    					  ?></td>
    					  <?php } ?>
    					</tr>
    				<?php
    				}
    
    				// show this only if Global Sync Back user is not set AND your are your own personal profile page AND we have an AD-user
    				if (($this->_syncback_use_global_user === false)
    					 && ($user->ID == $user_ID)
    					 && ($this->_syncback == true)
    					 && ($adi_samaccountname != '')) {
    					?>
    					<tr>
    						<th><label for="adi_syncback_password" class="adi_syncback_password"><?php _e('Your password','ad-integration');?></label></th>
    						<td>
    							<input type="password" name="adi_synback_password" id="adi_syncback_password" class="regulat-text code" />
    							<?php _e('If you want to save the changes on "Additional Informations" back to the Active Directory you must enter your password.')?>
    						</td>
    					</tr>
    					<?php
    				}
    
    				?>
    				</table>
    				<?php
    			}
    		}
    	}
    
    	/**
    	 * Update user meta from profile page
    	 * Here we can write user meta informations back to AD. User disable status is set in profile_update_disable_user().
    	 *
    	 * @param integer $user_id
    	 */
    	public function profile_update($user_id)
    	{
    		global $wp_version, $user_login;
    
    		// Add an action, so we can show errors on profile page
    		add_action('user_profile_update_errors', array(&$this,'generate_error'), 10, 3);
    
    		$this->_log(ADI_LOG_DEBUG,'SyncBack: Start of profile update');
    
    		$attributes_to_sync = array();
    
    		// check if synback is on and we have a user from AD and not local user
    		if ($this->_syncback === true)
    		{
    
    			// Go through attributes and update user meta if necessary.
    			$attributes = $this->_get_attributes_array();
    			foreach($attributes AS $key => $attribute) {
    				if ($attribute['sync'] == true) {
    					if (isset($_POST[$attribute['metakey']])) {
    
    						if ($attribute['type'] == 'list') {
    							// List
    							$list = explode("\n",str_replace("\r",'',$_POST[$attribute['metakey']]));
    							$i=0;
    							foreach ($list AS $line) {
    								if (trim($line) != '') {
    									$attributes_to_sync[$key][$i] = $line;
    									$i++;
    								}
    							}
    							if ($i == 0) {
    								$attributes_to_sync[$key][0] = ' '; // Use a SPACE !!!
    							}
    						} else {
    							// single value
    							if ($_POST[$attribute['metakey']] == '') {
    								$attributes_to_sync[$key][0] = ' '; // Use a SPACE !!!!
    							} else {
    								$attributes_to_sync[$key][0] = $_POST[$attribute['metakey']];
    							}
    						}
    						update_user_meta($user_id, $attribute['metakey'], $_POST[$attribute['metakey']]);
    					}
    				}
    			}
    
    			// Only SyncBack if we have an AD-user and not a local user
    			if (isset($_POST['adi_samaccountname']) && ($_POST['adi_samaccountname'] != '')) {
    
    				// Get User Data
    				$userinfo = get_userdata($_POST['user_id']);
    				$username = $userinfo->user_login;
    
    				// use personal_account_suffix
    				$personal_account_suffix = trim(get_user_meta($user_id,'ad_integration_account_suffix', true));
    				if ($personal_account_suffix != '') {
    					$account_suffix = $personal_account_suffix;
    				} else {
    					// extract account suffix from username if not set
    					// (after loading of options)
    					if (trim($this->_account_suffix) == '') {
    						if (strpos($username,'@') !== false) {
    							$parts = explode('@',$username);
    							$username = $parts[0];
    							$this->_account_suffix = '@'.$parts[1];
    							$this->_append_suffix_to_new_users = true; // TODO not really, hm?
    						}
    					} else {
    						// choose first possible account suffix (this should never happen)
    						$suffixes = explode(';',$this->_account_suffix);
    						$account_suffix = $suffixes[0];
    						$this->_log(ADI_LOG_WARN,'No personal account suffix found. Now using first account suffix "'.$account_suffix.'".');
    					}
    				}
    
    				// establish adLDAP connection
    				// Connect to Active Directory
    				if ($this->_syncback_use_global_user === true) {
    					$ad_username = $this->_syncback_global_user;
    					$ad_password = $this->_decrypt($this->_syncback_global_pwd);
    				} else {
    					if (isset($_POST['adi_synback_password']) && ($_POST['adi_synback_password'] != '')) {
    						$ad_username = $username.$account_suffix;
    						$ad_password = stripslashes($_POST['adi_synback_password']);
    					} else {
    						// No Global Sync User and no password given, so stop here.
    						$this->errors->add('syncback_no_password',__('No password given, so additional attributes are not written back to Active Directory','ad-integration'));
    						return false;
    					}
    				}
    
    				// Log informations
    				$this->_log(ADI_LOG_INFO,"SyncBack: Options for adLDAP connection:\n".
    							  "- base_dn: $this->_base_dn\n".
    							  "- domain_controllers: $this->_domain_controllers\n".
    							  "- ad_username: $ad_username\n".
    							  "- ad_password: **not shown**\n".
    							  "- ad_port: $this->_port\n".
    							  "- use_tls: ".(int) $this->_use_tls."\n".
    							  "- network timeout: ". $this->_network_timeout);
    
    				try {
    					$ad =  @new adLDAP(array(
    											"base_dn" => $this->_base_dn,
    											"domain_controllers" => explode(';', $this->_domain_controllers),
    											"ad_username" => $ad_username,      // AD Bind User
    											"ad_password" => $ad_password,      // password
    											"ad_port" => $this->_port,          // AD port
    											"use_tls" => $this->_use_tls,             		// secure?
    											"network_timeout" => $this->_network_timeout	// network timeout
    											));
    				} catch (Exception $e) {
    		    		$this->_log(ADI_LOG_ERROR,'adLDAP exception: ' . $e->getMessage());
    		    		$this->errors->add('syncback_wrong_password',__('Error on writing additional attributes back to Active Directory. Wrong password?','ad-integration'),'');
    					return false;
    				}
    				$this->_log(ADI_LOG_DEBUG,'Connected to AD');
    
    				//  Now we can modify the user
    				$this->_log(ADI_LOG_DEBUG,'attributes to sync: '.print_r($attributes_to_sync, true));
    				$this->_log(ADI_LOG_DEBUG,'modifying user: '.$username);
    				$modified = @$ad->user_modify_without_schema($username, $attributes_to_sync);
    				if (!$modified) {
    					$this->_log(ADI_LOG_WARN,'SyncBack: modifying user failed');
    					$this->_log(ADI_LOG_DEBUG,$ad->get_last_errno().': '.$ad->get_last_error());
    		    		$this->errors->add('syncback_modify_failed',__('Error on writing additional attributes back to Active Directory. Please contact your administrator.','ad-integration') . "<br/>[Error " . $ad->get_last_errno().'] '.$ad->get_last_error(),'');
    		    		return false;
    				} else {
    					$this->_log(ADI_LOG_NOTICE,'SyncBack: User successfully modified.');
    					return true;
    				}
    			} else {
    				return true;
    			}
    		}
    	}
    
    	/**
    	 * Disable email field in user profile if needed (actions edit_user_profile and show_user_profile)
    	 * This is not safe and only for cosmetic reasons, but we also have the method prevent_email_change() (see below).
    	 *
    	 * @param object $user
    	 */
    	public function user_profile_prevent_email_change($user)
    	{
    		// disable email field if needed (dirty hack)
    		if ($this->_prevent_email_change && $this->_is_adi_user($user->ID) && (!current_user_can('level_10'))) {
    			?>
    			<script type="text/javascript">
    				var email = document.getElementById('email');
    				if (email) {
    					email.setAttribute('disabled','disabled');
    				}
    			</script>
    			<?php
    		}
    	}
    
    	/**
    	 * Prevent ADI users from changing their email (action user_profile_update_errors)
    	 *
    	 * @param object $errors
    	 * @param bool $update
    	 * @param object $user
    	 */
    	public function prevent_email_change(&$errors, $update, &$user)
    	{
    		if ($this->_prevent_email_change && ($this->_is_adi_user($user->ID)) && (!current_user_can('level_10'))) {
    		    $old = get_user_by('id', $user->ID);
    
    		    if( $user->user_email != $old->user_email ) {
    		    	// reset to old email
    				$this->_log(ADI_LOG_DEBUG, 'Prevent email change on profile update for user "'.$user->user_login.'" ('.$user->ID.').');
    		        $user->user_email = $old->user_email;
    		    }
    		}
    	}
    
    	/**
    	 *  Add new column to the user list page
    	 *
    	 *  @param array $columns
    	 */
    	public function manage_users_columns($columns) {
    		global $wp_version;
    		$columns['adi_user'] = __('ADI User', 'ad-integration');
    		$columns['adi_user_disabled'] = __('Disabled', 'ad-integration');
    		return $columns;
    	}
    
    	/**
    	 *  Add column content for each user on user list
    	 *
    	 * @param mixed $value Value to show
    	 * @param string $column_name Name of column in user table
    	 * @param integer $user_id ID of user (the row)
    	 */
    	public function manage_users_custom_column( $value, $column_name, $user_id ) {
    
    		// Column "Disabled"
    		if ( $column_name == 'adi_user' ) {
    			$sam = get_user_meta($user_id, 'adi_samaccountname', true);
    			if ($sam != '') {
    				$value = '<div class="user_adi">&nbsp;</div>';
    			} else {
    				$value = '';
    			}
    		}
    
    		// Column "Reason"
    		if ( $column_name == 'adi_user_disabled' ) {
    			if (get_user_meta($user_
  7. Shonu
    Member
    Posted 2 weeks ago #

    Path (sorry):
    \wp-content\plugins\active-directory-integration\ad-integration.php

  8. Shonu
    Member
    Posted 1 week ago #

    Arg, the code got cut. Anyways, the code should go into the ADI plugin forum anyhow

  9. anttiai
    Member
    Posted 1 week ago #

    I'm sorry, I hate to be whiny and useless but I couldn't locate the complete code anywhere.

  10. Shonu
    Member
    Posted 1 week ago #

    Try over-installing it by downloading and then uploading this version to your WP:
    1.1.5

Reply

You must log in to post.

About this Plugin

About this Topic