'Server Information', 'adauthint_user_opts' => 'User Information', 'adauthint_auth_opts' => 'Authorization Information', 'adauthint_security_opts' => 'Security Information', ); /** * Has the user been authenticated already? * @var bool * @access private */ protected $_authenticated = false; /** * adLDAP Object * @var adLDAP * @access private */ protected $_adldap = NULL; /** * Logging/Debug Level */ protected $_loglevel = ADAI_LOG_NONE; /** * Debug Log * @var string */ protected $_debug = ''; /** * Whether or not to mask passwords in the log * @var bool */ protected $_mask_passwords_in_log = true; /** * Build our new ADAuthInt_Plugin object in PHP4 * * Simply calls and returns the PHP5 __construct() function * @uses ADAuthInt_Plugin::__construct() * @deprecated */ function ADAuthInt_Plugin() { return $this->__construct(); } /* ADAuthInt_Plugin() function */ /** * Build our new ADAuthInt_Plugin object * @uses load_plugin_textdomain() * @uses is_plugin_active_for_network() * @uses ADAuthInt_Plugin::_load_options() */ function __construct() { global $wp_version, $wpdb; if( !defined( 'ADAI_MU_PLUGIN' ) ) define( 'ADAI_MU_PLUGIN', stristr( 'mu-plugins/', __FILE__ ) ); if( !defined( 'ADAI_IS_WPMU' ) ) define( 'ADAI_IS_WPMU', is_multisite() ); add_filter('plugin_action_links_' . ADAUTHINT_PLUGIN_BASENAME, array($this, 'add_settings_link')); add_filter('network_admin_plugin_action_links_' . ADAUTHINT_PLUGIN_BASENAME, array($this, 'add_settings_link')); add_action('init', array($this, 'init_plugin')); add_action( 'network_admin_menu', array( $this, 'setup_admin' ) ); add_action('admin_menu', array($this, 'setup_admin') ); add_action('admin_init', array($this, 'init_admin')); if( is_admin() && $_REQUEST['page'] == ADAUTHINT_OPTIONS_PAGE ) { wp_register_script( /*$handle = */'adauthint-scripts', /*$src = */plugins_url( '/scripts/active-directory-authentication-integration.js', ADAUTHINT_PLUGIN_BASENAME ), /*$deps = */array( 'jquery' ), /*$ver = */ADAI_PLUGIN_VERSION, /*$in_footer = */true ); wp_enqueue_script( 'adauthint-scripts' ); } $this->_load_options(); $tablename = $this->get_table_name(); if( $wpdb->get_var( "SHOW TABLES LIKE '" . $tablename . "'" ) != $tablename ) { $sql = 'CREATE TABLE ' . $tablename . ' ( id bigint(20) NOT NULL AUTO_INCREMENT, site_id int(4), user_login varchar(60), failed_login_time bigint(11), UNIQUE KEY id (id) );'; require_once( ABSPATH . 'wp-includes/pluggable.php' ); require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); dbDelta( $sql ); } add_action( 'admin_notices', array( $this, '_flush_log_to_notice' ) ); if( !function_exists( 'ldap_connect' ) ) { add_action( 'admin_notices', array( $this, '_ldap_not_supported' ) ); return; } // WP 2.8 and above? if (version_compare($wp_version, '2.8', '>=')) { add_filter('authenticate', array(&$this, 'authenticate'), 10, 3); } else { add_action('wp_authenticate', array(&$this, 'authenticate'), 10, 2); } add_action( 'lost_password', array( &$this, 'disable_function' ) ); add_action( 'retrieve_password', array( &$this, 'disable_function' ) ); add_action( 'password_reset', array( &$this, 'disable_function' ) ); if( !$this->allow_local_password ) { // disable password fields add_filter('show_password_fields', array(&$this, 'disable_password_fields')); // generate a random passwords for manually added users add_action('check_passwords', array(&$this, 'generate_password'), 10, 3); } if( !class_exists( 'adLDAP' ) ) require_once( 'inc/adLDAP.php' ); } /* __construct() function */ /** * Print an Admin Notice about lack of LDAP Support */ function _ldap_not_supported() { echo '

' . __( 'LDAP Not Supported', ADAUTHINT_TEXT_DOMAIN ) . '

' . __( 'Your PHP configuration does not appear to support LDAP connections; therefore, the Active Directory Authentication Integration plug-in will not work at all. It is recommended that you deactivate the plug-in until you are able to update your PHP configuration to support LDAP.', ADAUTHINT_TEXT_DOMAIN ) . '

'; } /* _ldap_not_supported() function */ /** * Print the current log to an admin notice */ function _flush_log_to_notice() { if( $this->_loglevel && !empty( $this->_debug ) ) { echo '

' . __( 'ADAuthInt Log Information', ADAUTHINT_TEXT_DOMAIN ) . '

'; echo '
'; $this->_log_flush(); echo '
'; echo '
'; } } /* _flush_log_to_notice() function */ /** * Set the log level * @param int the level to which to set the log */ function setLogLevel($level=ADAI_LOG_NONE) { if( !is_numeric( $level ) ) return; $this->_loglevel = $level; return true; } /** * Initiate the plug-in * * Loads the WordPress text domain for this plugin * @uses load_plugin_textdomain * @uses ADAUTHINT_TEXT_DOMAIN * @uses ADAUTHINT_PATH */ function init_plugin() { load_plugin_textdomain( ADAUTHINT_TEXT_DOMAIN, false, ADAUTHINT_PATH . '/lang/' ); } /** * Load (and instantiate, if necessary) all of the options for this plug-in * @param array $values_to_use the array of values to use for the options * @param bool $force_update whether or not to force an update to the stored options * @uses ADAuthInt_Plugin::options_info * @uses ADAuthInt_Plugin::options * @uses maybe_unserialize() * @uses get_site_option() * @uses get_option() * @uses ADAuthInt_Plugin::build_options_objs() */ function _load_options( $values_to_use=NULL, $force_update=false ) { $this->options_info = $this->get_options_info(); foreach( $this->options_info as $opt=>$optinfo ) { $tmpopt = $optinfo; array_walk( $tmpopt, 'extract_val_from_optinfo' ); if( is_array( $values_to_use ) && array_key_exists( $opt, $values_to_use ) ) $this->options[$opt] = $values_to_use[$opt]; else $this->options[$opt] = maybe_unserialize( ( ( ADAI_IS_NETWORK_ACTIVE ) ? get_site_option( $opt ) : get_option( $opt ) ) ); if( $this->options[$opt] === false || empty( $this->options[$opt] ) ) { $this->options[$opt] = $this->_add_options_to_database( $tmpopt, $opt ); } elseif( $force_update ) { $this->options[$opt] = $this->_add_options_to_database( $this->options[$opt], $opt ); } } $this->build_options_objs(); } /* _load_options() function */ /** * Add this plugin's options to the database * * If the options for this plugin are not found in the database, or * the options array is empty, we need to either add the new options * or update them appropriately. * @param array $tmpopt The array of default options to be added * @param string $opt The name of the option to be updated * @return array The array of updated options retrieved from the database * @uses ADAuthInt_Plugin::_log() * @uses ADAuthInt_Plugin::options * @uses add_site_option() * @uses update_site_option() * @uses add_option() * @uses update_option() * @uses maybe_unserialize() * @uses ADAI_IS_NETWORK_ACTIVE */ protected function _add_options_to_database( $tmpopt = array(), $opt = NULL ) { if( empty( $opt ) ) /* If our option name is empty, return our original array */ return $tmpopt; if( !count( $tmpopt ) ) /* If our default options are empty, return the database options */ return maybe_unserialize( ( ADAI_IS_NETWORK_ACTIVE ) ? get_site_option( $opt ) : get_option( $opt ) ); if( ADAI_IS_NETWORK_ACTIVE ) { if( $this->options[$opt] === false ) { add_site_option( $opt, $tmpopt ); $this->_log( ADAI_LOG_INFO, 'The network options did not exist for ' . $opt . ', so they were added to the database.' ); } else { update_site_option( $opt, $tmpopt ); $this->_log( ADAI_LOG_INFO, 'The network options existed for ' . $opt . ', but they were empty, so they were updated in the database.' ); } /* If the database options are boolean false (don't exist) or just empty */ return maybe_unserialize( get_site_option( $opt ) ); } else { if( $this->options[$opt] === false ) { add_option( $opt, $tmpopt ); $this->_log( ADAI_LOG_INFO, 'The options did not exist for ' . $opt . ', so they were added to the database.' ); } else { update_option( $opt, $tmpopt ); $this->_log( ADAI_LOG_INFO, 'The options existed for ' . $opt . ', but they were empty, so they were updated in the database.' ); } /* If the database options are boolean false (don't exist) or just empty */ return maybe_unserialize( get_option( $opt ) ); } /* If ADAI_IS_NETWORK_ACTIVE or not */ } /* _add_options_to_database() function */ /** * Builds the ADAuthInt_Plugin::options_info array */ function get_options_info() { require( ADAUTHINT_ABS_DIR . '/inc/active-directory-authentication-integration.default-options.php' ); if( is_array( $default_options_info ) ) return $default_options_info; else return array(); } /* get_options_info() function */ /** * Instantiate our ADAuthInt_Option objects * @uses ADAuthInt_Plugin::options_info * @uses ADAuthInt_Plugin::options_objs * @uses ADAuthInt_Option::__construct() */ function build_options_objs() { foreach( $this->options_info as $optgroupname=>$optgroup ) { if( !array_key_exists( $optgroupname, $this->options_objs ) ) $this->options_objs[ $optgroupname ] = array(); foreach( $optgroup as $optname=>$optinfo ) { if( property_exists( $this, $optname ) ) { if( array_key_exists( $optname, $this->options[$optgroupname] ) ) { $this->_log( ADAI_LOG_DEBUG, 'The ' . $optname . ' key exists in our options array.' ); if( $optinfo['opt_type'] == 'password' ) { $this->_log( ADAI_LOG_DEBUG, 'Preparing to decode the ' . $optinfo['opt_name'] . ' field from ' . $this->options[$optgroupname][$optname] ); $this->options[$optgroupname][$optname] = base64_decode( $this->options[$optgroupname][$optname] ); } $this->$optname = ( $this->options[$optgroupname][$optname] === 'false' ) ? false : $this->options[$optgroupname][$optname]; $optinfo['opt_val'] = $this->$optname; } else { $this->_log( ADAI_LOG_DEBUG, 'The ' . $optname . ' key does not exist in our options array.' ); $this->$optname = $optinfo['opt_val']; } } $this->options_info[$optgroupname][$optname]['opt_val'] = $optinfo['opt_val']; $options_info = array_merge( array('opt_name' => $optname, 'opt_val' => $optinfo['opt_val'], 'opt_section' => $optgroupname ), $this->options_info[$optgroupname][$optname] ); $this->options_objs[$optgroupname][$optname] = new ADAuthInt_Option( $options_info ); } } return; } /* build_options_objs() function */ /** * Display our options page in the WordPress admin area * @uses $this->options * @uses settings_fields() * @uses do_settings_sections() */ function display_admin_page() { if( ( ADAI_IS_NETWORK_ACTIVE && !current_user_can( 'delete_users' ) ) || ( !ADAI_IS_NETWORK_ACTIVE && !current_user_can( 'manage_options' ) ) ) { ?>

update_wpms_options(); } if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); echo "Options Info:\n"; var_dump( $this->options_info ); echo "\n\nOptions:\n"; var_dump( $this->options ); echo "\n\nOptions Objects:\n"; var_dump( $this->options_objs ); $this->_log( ADAI_LOG_DEBUG , ob_get_contents() ); ob_end_clean(); } ?>

_log_flush(); return true; } /* display_admin_page() function */ /** * Update options for a whole network * * Only invoked when the plugin is network-active. If * the plugin is only active on one blog/site, or the * multi-site functions of WordPress are not set up, * this function is not called. */ function update_wpms_options() { if( ADAI_IS_NETWORK_ACTIVE ) { /* If the WP Multi Network plug-in is installed and active, * then we should propagate the settings to all other networks */ if( ADAI_IS_MULTINETWORK && $this->update_all_networks ) { global $wpdb; $networks = $wpdb->get_results( $wpdb->prepare( 'SELECT DISTINCT id FROM ' . $wpdb->site ) ); if( is_array( $networks ) ) { /* We retrieved an array of site IDs */ if( !method_exists( $this, 'switch_to_site' ) ) continue; foreach( $networks as $network ) { global $adai_current_network, $adai_original_network, $site_id; $adai_current_network = $network->id; $adai_original_network = $site_id; $this->_log( ADAI_LOG_INFO, 'Preparing to update sitewide options for ' . $network->id ); $this->switch_to_site( $adai_current_network ); if( current_user_can( 'delete_users' ) ) { $this->update_site_options( $adai_current_network, $adai_original_network ); } else { $this->_log( ADAI_LOG_ERROR, 'The current user does not appear to be a super admin for the network with an ID of ' . $adai_current_network . ', therefore, the site options for that network were not updated.' ); } $this->restore_current_site(); } } elseif( current_user_can( 'delete_users' ) ) { /* We only found one network */ $this->_log( ADAI_LOG_INFO, 'WPMN plugin was found, but only one network seems to exist, so only options for the current network are updated.' ); $this->update_site_options(); } else { $this->_log( ADAI_LOG_ERROR, 'Multiple networks were not found, so an attempt was made to update the current network. However, the current user does not appear to have the appropriate permissions to perform this action. Therefore, no options were updated.' ); } } else { /* The WPMN plugin is not installed or active */ $this->_log( ADAI_LOG_INFO, 'The WPMN plugin was not found, so only options for current network are updated' ); if( current_user_can( 'delete_users' ) ) $this->update_site_options(); else $this->_log( ADAI_LOG_ERROR, 'The current user does not appear to have the appropriate permissions to update these options.' ); } } } /* update_wpms_options() function */ function update_site_options( $current_network=NULL, $original_network=NULL ) { foreach( array_keys( $this->options_info ) as $optgroup ) { if( $current_network == $original_network || ( array_key_exists( 'update_all_networks', $_POST[ $optgroup ] ) && $_POST[$optgroup]['update_all_networks'] == 'true' ) ) { $this->_log( ADAI_LOG_INFO, 'The network options for ' . $optgroup . ' were updated' . ( ( !empty( $current_network ) ) ? ' on the network with an ID of ' . $current_network : '' ) . '.' ); update_site_option( $optgroup, $options ); } } } /** * Initiate our admin page * @uses ADAuthInt_Plugin::options * @uses register_setting() * @uses add_settings_section() * @uses add_settings_field() */ function init_admin(){ if( !count( $this->options_objs ) ) $this->_load_options(); foreach( $this->options_info as $optgroup=>$options ) { if( is_array( $options ) ) { register_setting( ADAUTHINT_OPTIONS_PAGE, $optgroup, array( $this, 'validate_options_' . $optgroup ) ); add_settings_section( /*$id = */$optgroup . '_group', /*$title = */__( $this->subtitles[$optgroup], ADAUTHINT_TEXT_DOMAIN ), /*$callback = */array( $this, 'build_options_' . $optgroup ), /*$page = */ADAUTHINT_OPTIONS_PAGE ); foreach( array_keys( $options ) as $k ) { add_settings_field( /*$id =*/ $k, /*$title =*/ __( $this->options_objs[$optgroup][$k]->opt_label, ADAUTHINT_TEXT_DOMAIN ), /*$callback =*/ array( &$this->options_objs[$optgroup][$k], 'build_field' ), /*$page =*/ ADAUTHINT_OPTIONS_PAGE, /*$section =*/ $optgroup . '_group' ); } } } } /* init_admin() function */ /** * Build the Server Options group * @uses ADAuthInt_Plugin::build_options_group() */ function build_options_adauthint_server_opts() { $this->build_options_group( $this->options_info['adauthint_server_opts'], 'adauthint_server_opts' ); return; } /* build_options_adauthint_server_opts function */ /** * Build the User Options group * @uses ADAuthInt_Plugin::build_options_group() */ function build_options_adauthint_user_opts() { $this->build_options_group( $this->options_info['adauthint_user_opts'], 'adauthint_user_opts' ); return; } /* build_options_adauthint_user_opts function */ /** * Build the Authority Options group * @uses ADAuthInt_Plugin::build_options_group() */ function build_options_adauthint_auth_opts() { $this->build_options_group( $this->options_info['adauthint_auth_opts'], 'adauthint_auth_opts' ); return; } /* build_options_adauthint_auth_opts function */ /** * Build the Security Options group * @uses ADAuthInt_Plugin::build_options_group() */ function build_options_adauthint_security_opts() { $this->build_options_group( $this->options_info['adauthint_security_opts'], 'adauthint_security_opts' ); return; } /* build_options_adauthint_security_opts function */ /** * General options building function * * This function is used to build each of the options groups for this plug-in * @param array $group The appropriate portion of the ADAuthInt_Plugin::options_info array for this group of options * @param string $sect The name of the options group to build */ function build_options_group( $group=array(), $sect ) { if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $this->options_objs ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } $section_notes = array( 'adauthint_server_opts' => 'Information about the active directory server.', 'adauthint_user_opts' => 'Information about how to handle individual user accounts', 'adauthint_security_opts' => 'Various security options to help prevent brute-force attacks', 'adauthint_auth_opts' => 'Authorization options, allowing you to set up specific user groups based on Active Directory groups, etc.', ); echo '
' . $section_notes[$sect]; if( ADAI_IS_MULTINETWORK ) echo '

'; echo '
'; return; } /* build_options_group function */ /** * Validate the Server Options * @uses ADAuthInt_Plugin::validate_options_group() */ function validate_options_adauthint_server_opts( $input ) { $input = $this->validate_options_group( $this->options_info['adauthint_server_opts'], 'adauthint_server_opts', $input, 'validate_options_adauthint_server_opts' ); if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $input ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } return $input; } /* validate_options_adauthint_server_opts function */ /** * Validate the User Options * @uses ADAuthInt_Plugin::validate_options_group() */ function validate_options_adauthint_user_opts( $input ) { $input = $this->validate_options_group( $this->options_info['adauthint_user_opts'], 'adauthint_user_opts', $input, 'validate_options_adauthint_user_opts' ); if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $input ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } return $input; } /* validate_options_adauthint_user_opts */ /** * Validate the Authority Options * @uses ADAuthInt_Plugin::validate_options_group() */ function validate_options_adauthint_auth_opts( $input ) { $input = $this->validate_options_group( $this->options_info['adauthint_auth_opts'], 'adauthint_auth_opts', $input, 'validate_options_adauthint_auth_opts' ); if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $input ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } return $input; } /* validate_options_adauthint_auth_opts */ /** * Validate the Security Options * @uses ADAuthInt_Plugin::validate_options_group() */ function validate_options_adauthint_security_opts( $input ) { $input = $this->validate_options_group( $this->options_info['adauthint_security_opts'], 'adauthint_security_opts', $input, 'validate_options_adauthint_security_opts' ); if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $input ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } return $input; } /* validate_options_adauthint_security_opts */ /** * General Validation Function * * This function is used to validate all options used by this function * @param array $group the appropriate part of the options_info array * @param string $sect the name of the group of options to be validated * @param array $input the array of submitted form values */ function validate_options_group( $group=array(), $sect, $input, $referring_function=NULL ) { $this->_log( ADAI_LOG_DEBUG, 'Preparing to save ' . $sect . ' site options as called by the $referring_function function.' ); $options = ( ADAI_IS_NETWORK_ACTIVE ) ? get_site_option( $sect ) : get_option( $sect ); $options = maybe_unserialize( $options ); if( empty( $input ) ) $input = $_POST[$sect]; if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $input ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } foreach( $this->options_info[$sect] as $optname=>$optval ) { if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); var_dump( $options ); print('
'); var_dump( $optname ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } if( !array_key_exists( $optname, $input ) ) $input[$optname] = false; $options[$optname] = $this->options_objs[$sect][$optname]->validate_field( $input[$optname] ); $this->options_info[$sect][$optname]['opt_val'] = $this->options_objs[$sect][$optname]->opt_value; $this->$optname = $this->options_objs[$sect][$optname]->opt_value; $this->options[$sect][$optname] = $this->options_objs[$sect][$optname]->opt_value; } if( $this->_loglevel >= ADAI_LOG_DEBUG ) { ob_start(); print( "\n" ); var_dump( $options ); print( '

' ); $this->_log( ADAI_LOG_DEBUG, ob_get_contents() ); ob_end_clean(); } return $options; } /* validate_options_group function */ /** * Adds 'Settings' link to main WordPress Plugins page */ function add_settings_link( $links ){ global $wp_version; $options_page = ( ( ADAI_IS_NETWORK_ACTIVE ) ? ( ( version_compare( $wp_version, '3.0.9', '>' ) ) ? 'settings' : 'ms-admin' ) : 'options-general' ); $settings_link = '' . __( 'Settings', ADAUTHINT_TEXT_DOMAIN ) . ''; $delete_settings_link = '' . __( 'Delete Settings', ADAUTHINT_TEXT_DOMAIN ) . ''; array_unshift( $links, $settings_link ); array_push( $links, $delete_settings_link ); return $links; } /* add_settings_link function */ /** * Setup admin settings page */ function setup_admin(){ global $wp_version; if( ADAI_IS_NETWORK_ACTIVE ) { /* This plug-in is network activated */ $options_page = ( version_compare( $wp_version, '3.0.9', '>' ) ) ? 'settings.php' : 'ms-admin.php'; /* Add the new options page to the Super Admin menu */ add_submenu_page( /*$parent_slug = */$options_page, /*$page_title = */'AD Authentication Integration Settings', /*$menu_title = */'AD Authentication Integration', /*$capability = */'delete_users', /*$menu_slug = */ADAUTHINT_OPTIONS_PAGE, /*$function = */array($this, 'display_admin_page') ); } elseif( function_exists( 'add_options_page' ) ) { /* This plug-in is only active on 1 blog */ /* Add the new options page to the Settings menu */ add_options_page( /*$page_title = */'AD Authentication Integration Settings', /*$menu_title = */'AD Authentication Integration', /*$capability = */'delete_users', /* Should restrict settings to admins for regular installs and super admins for multi-site installs */ /*$menu_slug = */ADAUTHINT_OPTIONS_PAGE, /*$function = */array($this, 'display_admin_page') ); } } /* setup_admin function */ function _set_masked_passwords_for_log( $mask ) { $this->_mask_passwords_in_log = ( false === $mask ) ? false : true; } } /* ADAuthInt_Plugin class */ } ?>