Advertisement
gilzow

wpDirAuth multisite per-site enabled

May 29th, 2014
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 98.57 KB | None | 0 0
  1. <?php
  2. /**
  3.  * wpDirAuth: WordPress Directory Authentication (LDAP/LDAPS).
  4.  *
  5.  * Works with most LDAP enabled directory services, such as OpenLDAP,
  6.  * Apache Directory, Microsoft Active Directory, Novell eDirectory,
  7.  * Sun Java System Directory Server, etc.
  8.  *
  9.  * Please note that wpDirAuth will start in safe mode if it detects that
  10.  * another plugin is in conflict, by detecting if the wp_authenticate and
  11.  * wp_setcookie functions have already been overwritten. It cannot,
  12.  * on the other hand, detect plugins that might want to overwrite these
  13.  * functions after wpDirAuth has been loaded.
  14.  *
  15.  * Originally forked from a patched version of wpLDAP.
  16.  *
  17.  * @package wpDirAuth
  18.  * @version 1.7.6a
  19.  * @see http://wpdirauth.gilzow.com/
  20.  * @license GPL <http://www.gnu.org/licenses/gpl.html>
  21.  *
  22.  * Copyrights are listed in chronological order, by contributions.
  23.  *
  24.  * wpDirAuth: WordPress Directory Authentication, original author
  25.  * Copyright (c) 2007 Stephane Daury - http://stephane.daury.org/
  26.  *
  27.  * wpDirAuth and wpLDAP Patch Contributions
  28.  * Copyright (c) 2007 PKR Internet, LLC - http://www.pkrinternet.com/
  29.  *
  30.  * wpDirAuth Patch Contributions
  31.  * Copyright (c) 2007 Todd Beverly
  32.  *
  33.  * wpLDAP: WordPress LDAP Authentication
  34.  * Copyright (c) 2007 Ashay Suresh Manjure - http://ashay.org/
  35.  *
  36.  * wpDirAuth Patch Contribution and current maintainer
  37.  * Copyright (c) 2010, 2011, 2012 Paul Gilzow - http://gilzow.com/
  38.  *
  39.  * wpDirAuth is free software: you can redistribute it and/or modify it
  40.  * under the terms of the GNU General Public License as published by the
  41.  * Free Software Foundation.
  42.  *
  43.  * wpDirAuth is distributed in the hope that it will be useful,
  44.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  45.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  46.  * GNU General Public License for more details.
  47.  *
  48.  * You should have received a copy of the GNU General Public License
  49.  * along with this program.  If not, see http://www.gnu.org/licenses/.
  50.  *
  51.  * @todo Always stay on top of security and user input validation while
  52.  * staying backwards compatible enough until PHP4 support is dropped in
  53.  * WP (serious patches welcomed, please see code). Note that we do
  54.  * heavily rely on WP's admin ACL scheme, by necessity.
  55.  */
  56.  
  57. /*
  58. PLUGIN META INFO FOR WORDPRESS LISTINGS
  59. Plugin Name: wpDirAuth
  60. Plugin URI:  http://wpdirauth.gilzow.com/
  61. Description: WordPress Directory Authentication (LDAP/LDAPS).
  62.              Works with most LDAP enabled directory services, such as OpenLDAP,
  63.              Apache Directory, Microsoft Active Directory, Novell eDirectory,
  64.              Sun Java System Directory Server, etc.
  65.              Originally revived and upgraded from a patched version of wpLDAP.
  66. Version: 1.7.6
  67. Author: Paul Gilzow
  68. Author URI: http://gilzow.com/
  69. */
  70.  
  71. /**
  72.  * wpDirAuth version.
  73.  */
  74. define('WPDIRAUTH_VERSION', '1.7.6a');
  75.  
  76. /**
  77.  * wpDirAuth signature.
  78.  */
  79. define('WPDIRAUTH_SIGNATURE', '<a href="http://wordpress.org/extend/plugins/wpdirauth/">wpDirAuth</a> '.WPDIRAUTH_VERSION);
  80.  
  81. /**
  82.  * Default LDAP field to search against when locating the user's profile.
  83.  */
  84. define('WPDIRAUTH_DEFAULT_FILTER', 'samAccountName');
  85.  
  86. /**
  87.  * Default login screen message.
  88.  */
  89. define('WPDIRAUTH_DEFAULT_LOGINSCREENMSG', '%s members can login directly using their institutional password.');
  90.  
  91. /**
  92.  * Default password change message.
  93.  */
  94. define('WPDIRAUTH_DEFAULT_CHANGEPASSMSG', 'To change a %s password, please refer to the official institutional password policy.');
  95.  
  96. /**
  97.  * Allowed HTML (messages)
  98.  */
  99. define('WPDIRAUTH_ALLOWED_TAGS', '<a><strong><em><p><ul><ol><li>');
  100.  
  101. define('WPDIRAUTH_ERROR_TITLE',__('<strong>Directory Authentication Error</strong>: '));
  102.  
  103. define('WPDIRAUTH_LDAP_RETURN_KEYS',serialize(array('sn', 'givenname', 'mail')));
  104.  
  105. define('WPDIRAUTH_EMAIL_NEWUSER_NOTIFY','You have been added to the site %s as %s %s. You may login to the site using your institution\'s %s (%s) and password at the following address: %s');
  106.  
  107. /**
  108.  *My fail-safe method for determining if we are running in multisite mode
  109.  * @deprecated
  110.  * @see lines 135 - 150
  111.  */
  112. //define('WPDIRAUTH_MULTISITE',(defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE && function_exists('switch_to_blog')) ? TRUE : FALSE);
  113.  
  114. /**
  115.  *List of option keys we store in wp_sitemeta/wp_options
  116.  */
  117. define('WPDIRAUTH_OPTIONS', serialize(array(
  118.     'dirAuthEnable',
  119.     'dirAuthRequiresSsl',
  120.     'dirAuthTOS',
  121.     'dirAuthUseGroups',
  122.     'dirAuthEnableSsl',
  123.     'dirAuthControllers',
  124.     'dirAuthBaseDn',
  125.     'dirAuthPreBindUser',
  126.     'dirAuthAccountSuffix',
  127.     'dirAuthFilter',
  128.     'dirAuthInstitution',
  129.     'dirAuthGroups',
  130.     'dirAuthMarketingSSOID',
  131.     'dirAuthLoginScreenMsg',
  132.     'dirAuthChangePassMsg'
  133. )));
  134.  
  135. /**
  136.  * We need to determine if we are running in multisite mode, and if we have been network-enabled...
  137.  */
  138. //first we need to make sure we have access to the function
  139. if(! function_exists('is_plugin_active_for_network')){
  140.     require_once( ABSPATH . '/wp-admind/includes/plugin.php');
  141. }
  142.  
  143. /**
  144.  * @todo don't hardcode plugin directory/name
  145.  */
  146. if(defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE && function_exists('switch_to_blog') && is_plugin_active_for_network('wpdirauth/wpDirAuth.php')){
  147.     define('WPDIRAUTH_MULTISITE',true);
  148. } else {
  149.     define('WPDIRAUTH_MULTISITE',false);
  150. }
  151.  
  152. if (function_exists('wp_authenticate') || function_exists('wp_setcookie') || !function_exists('ldap_connect')) {
  153.     /**
  154.      * SAFE MODE
  155.      */
  156.  
  157.     /**
  158.      * SAFE MODE: wpDirAuth plugin configuration panel.
  159.      * Processes and outputs the wpDirAuth configuration form, with a conflict message.
  160.      *
  161.      * @return void
  162.      */
  163.     function wpDirAuth_safeConflictMessage()
  164.     {
  165.         $wpDARef = WPDIRAUTH_SIGNATURE;
  166.  
  167.         if (!function_exists('ldap_connect')) {
  168.             $message = <<<________EOS
  169.             <h3>Sorry, but your PHP install does not seem to have access to the LDAP features.</h3>
  170.             <p>
  171.                 <br />wpDirAuth is now running in safe mode.'
  172.            </p>
  173.            <p>
  174.                Quote from the <a href="http://php.net/ldap#ldap.installation">PHP manual LDAP section</a>:
  175.                <blockquote>
  176.                     LDAP support in PHP is not enabled by default. You will need to use the
  177.                     --with-ldap[=DIR] configuration option when compiling PHP to enable LDAP
  178.                     support. DIR is the LDAP base install directory. To enable SASL support,
  179.                     be sure --with-ldap-sasl[=DIR] is used, and that sasl.h exists on the system.
  180.                </blockquote>
  181.            </p>
  182. ________EOS;
  183.        }
  184.        else {
  185.            $message = <<<________EOS
  186.            <h3>Sorry, but another plugin seems to be conflicting with wpDirAuth.</h3>
  187.            <p>
  188.                <br />wpDirAuth is now running in safe mode as to not impair the other plugin's operations.'
  189.            </p>
  190.            <p>
  191.                The wp_authenticate and wp_setcookie WordPress
  192.                <a href="http://codex.wordpress.org/Pluggable_Functions">pluggable functions</a>
  193.                have already been redefined, and wpDirAuth cannot provide directory authentication
  194.                without having access to these functions.
  195.            </p>
  196.            <p>
  197.                Please disable any WP plugins that deal with authentication in order to use wpDirAuth.
  198.                Unfortunately, we cannot provide you with more info as to which plugin is in conflict.
  199.            </p>
  200. ________EOS;
  201.        }
  202.  
  203.        echo <<<________EOS
  204.        <div class="wrap">
  205.            <h2>Directory Authentication Options: Plugin Conflict</h2>
  206.            $message
  207.            <p>$wpDARef</p>
  208.        </div>
  209. ________EOS;
  210.    }
  211.  
  212.  
  213.    /**
  214.     * SAFE MODE: Adds the `Directory Auth.` menu entry in the Wordpress Admin section.
  215.     * Also activates the wpDirAuth config panel, with a conflict message, as a callback function.
  216.     *
  217.     * @uses wpDirAuth_safeConflictMessage
  218.     */
  219.    function wpDirAuth_safeAddMenu()
  220.    {
  221.        if (function_exists('add_options_page')) {
  222.            add_options_page(
  223.                'Directory Authentication Options: Plugin Conflict',
  224.                '!! Directory Auth. !!',
  225.                9,
  226.                basename(__FILE__),
  227.                'wpDirAuth_safeConflictMessage'
  228.            );
  229.        }
  230.    }
  231.  
  232.  
  233.    /**
  234.     * SAFE MODE: Add custom WordPress actions.
  235.     *
  236.     * @uses wpDirAuth_safeAddMenu
  237.     */
  238.    if (function_exists('add_action')) {
  239.        add_action('admin_menu', 'wpDirAuth_safeAddMenu');
  240.    }
  241. }
  242. else {
  243.    /**
  244.     * STANDARD MODE
  245.     */
  246.  
  247.    /**
  248.     * Cookie marker.
  249.     * Generates a random string to be used as salt for the password
  250.     * hash cookie checks in wp_setcookie and wp_authenticate
  251.     *
  252.     * @return string 55 chars-long salty goodness (md5 + uniqid)
  253.     */
  254.    function wpDirAuth_makeCookieMarker()
  255.    {
  256.        $cookieMarker = md5(
  257.                $_SERVER['SERVER_SIGNATURE']
  258.                .$_SERVER['HTTP_USER_AGENT']
  259.                .$_SERVER['REMOTE_ADDR']
  260.            ).uniqid(microtime(),true);
  261.        update_site_option("dirAuthCookieMarker",$cookieMarker);
  262.        return $cookieMarker;
  263.    }
  264.  
  265.  
  266.    /**
  267.     * LDAP bind test
  268.     * Tries two different documented method of php-based ldap binding.
  269.     * Note: passing params by reference, no need for copies (unlike in
  270.     * wpDirAuth_auth where it is desirable).
  271.     *
  272.     * @param object &$connection LDAP connection
  273.     * @param string &$username LDAP username
  274.     * @param string &$password LDAP password
  275.     * @param string $baseDn
  276.     * @return boolean Binding status
  277.     *      */
  278.    function wpDirAuth_bindTest(&$connection, &$username, &$password,$baseDn)
  279.    {
  280.        $password = strtr($password, array("\'"=>"'"));
  281.        if ( ($isBound = @ldap_bind($connection, $username, $password)) === false ) {
  282.            // @see http://weblogs.valsania.it/andreav/2008/07/24/wpdirauth-14-patch/
  283.            $isBound = @ldap_bind($connection,"uid=$username,$baseDn", $password);
  284.        }
  285.        return $isBound;
  286.    }
  287.  
  288.    /**
  289.     * put your comment there...
  290.     *
  291.     * @param string $dc name of domain controller to connect to
  292.     * @param integer $enableSsl ssl config option
  293.     * @return resource
  294.     */
  295.    function wpDirAuth_establishConnection($dc,$enableSsl){
  296.        /**
  297.         * Only setup protocol value if ldaps is required to help with older AD
  298.         * @see http://groups.google.com/group/wpdirauth-support/browse_thread/thread/7b744c7ad66a4829
  299.         */
  300.        $protocol = ($enableSsl) ? 'ldaps://' : '';
  301.  
  302.        /**
  303.         * Scan for and use alternate server port, but only if ssl is disabled.
  304.         * @see Parameters constraint at http://ca.php.net/ldap_connect
  305.         */
  306.  
  307.        if (strstr($dc, ':')) list($dc, $port) = explode(':', $dc);
  308.  
  309.        switch($enableSsl){
  310.            case 1:
  311.                $connection = ldap_connect($protocol.$dc);
  312.                break;
  313.            case 2:
  314.            case 0:
  315.            default:
  316.                if(isset($port)){
  317.                    $connection = ldap_connect($dc,$port);
  318.                } else {
  319.                    $connection = ldap_connect($dc);
  320.                }
  321.                break;
  322.  
  323.        }
  324.  
  325.        /**
  326.         * Copes with W2K3/AD issue.
  327.         * @see http://bugs.php.net/bug.php?id=30670
  328.         */
  329.        if (@ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, 3)) {
  330.            @ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
  331.        }
  332.  
  333.        //they want to start TLS
  334.        if($enableSsl == 2){
  335.            if(!ldap_start_tls($connection)){
  336.                return new WP_Error('tls_failed_to_start',__('wpDirAuth error: tls failed to start'));
  337.            }
  338.        }
  339.  
  340.        return $connection;
  341.    }
  342.  
  343.    /**
  344.     * put your comment there...
  345.     *
  346.     * @param array $controllers list of domain controllers to connect to
  347.     * @return mixed array of shuffled controllers or WP_Error
  348.     */
  349.    function wpDirAuth_shuffleControllers($controllers){
  350.        if (count($controllers) > 1) {
  351.            // shuffle the domain controllers for pseudo load balancing and fault tolerance.
  352.            shuffle($controllers);
  353.        } elseif (count($controllers) == 0) {
  354.            return new WP_Error('no_controllers',__(' wpDirAuth config error: no domain controllers specified.'));
  355.        }
  356.  
  357.        return $controllers;
  358.    }
  359.  
  360.    /**
  361.     * Custom LDAP authentication module.
  362.     * The returned keys are in the same format used by WP for
  363.     * the wp_insert_user and wp_update_user functions.
  364.     *
  365.     * @param string $username LDAP username
  366.     * @param string $password LDAP password
  367.     * @return WP_Error object OR array Directory email, last_name and first_name
  368.     *
  369.     * @uses WPDIRAUTH_DEFAULT_FILTER
  370.     * @uses WPDIRAUTH_ERROR_TITLE
  371.     * @uses wpDirAuth_bindTest
  372.     * @uses wpDirAuth_retrieveUserDetails
  373.     * @uses wpDirAuth_shuffleControllers
  374.     * @uses wpDirAuth_establishConnection
  375.     */
  376.    function wpDirAuth_auth($username, $password)
  377.    {
  378.        global $error, $pwd;
  379.  
  380.        $errorTitle = WPDIRAUTH_ERROR_TITLE;
  381.  
  382.        $controllers      = explode(',', get_site_option('dirAuthControllers'));
  383.        $baseDn           = get_site_option('dirAuthBaseDn');
  384.        $preBindUser      = get_site_option('dirAuthPreBindUser');
  385.        $preBindPassword  = get_site_option('dirAuthPreBindPassword');
  386.        $accountSuffix    = get_site_option('dirAuthAccountSuffix');
  387.        $filter           = get_site_option('dirAuthFilter');
  388.        $enableSsl        = get_site_option('dirAuthEnableSsl');
  389.        $boolUseGroups    = get_site_option('dirAuthUseGroups');
  390.  
  391.        if($boolUseGroups == 1){
  392.            $strAuthGroups = get_site_option('dirAuthGroups');
  393.        }
  394.  
  395.        $returnKeys = unserialize(WPDIRAUTH_LDAP_RETURN_KEYS);
  396.  
  397.        $isBound = $isPreBound = $isLoggedIn = false;
  398.  
  399.        if ($accountSuffix) $username .= $accountSuffix;
  400.  
  401.        if (!$filter) $filter = WPDIRAUTH_DEFAULT_FILTER;
  402.  
  403.        $filterQuery = "($filter=$username)";
  404.  
  405.        $controllers = wpDirAuth_shuffleControllers($controllers);
  406.  
  407.        if(is_wp_error($controllers)){
  408.            return $controllers;
  409.        }
  410.  
  411.        // Connection pool loop - Haha, PooL LooP
  412.        foreach ($controllers as $dc) {
  413.  
  414.            $connection = wpDirAuth_establishConnection($dc,$enableSsl);
  415.  
  416.            if(is_wp_error($connection)){
  417.                return $connection;
  418.            }
  419.  
  420.            if ($preBindUser && $preBindPassword) {
  421.                /**
  422.                 * Use case 1: Servers requiring pre-binding with admin defined
  423.                 * credentials to search for the user's full DN before attempting
  424.                 * to login.
  425.                 * @see http://dev.wp-plugins.org/ticket/681
  426.                 */
  427.                if ( $isPreBound = wpDirAuth_bindTest($connection, $preBindUser, $preBindPassword,$baseDn) === true ) {
  428.                    if ( ($results = @ldap_search($connection, $baseDn, $filterQuery, $returnKeys)) !== false ) {
  429.                        if ( ($userDn = @ldap_get_dn($connection, ldap_first_entry($connection, $results))) !== false ) {
  430.                            if ( ($isBound = wpDirAuth_bindTest($connection, $userDn, $password,$baseDn)) === true ) {
  431.                                $isLoggedIn = true; // valid server, valid login, move on
  432.                                break; // valid server, valid login, move on
  433.                            }
  434.                        }
  435.                    }
  436.                }
  437.            }
  438.            elseif ( ($isBound = wpDirAuth_bindTest($connection, $username, $password,$baseDn)) === true ) {
  439.                /**
  440.                 * Use case 2: Servers that will not let you bind anonymously
  441.                 * but will let the end user bind directly.
  442.                 * @see http://groups.google.com/group/wpdirauth-support/browse_thread/thread/8fd16c05266fc832
  443.                 */
  444.                $isLoggedIn = true;
  445.                break;  // valid server, valid login, move on
  446.            }
  447.            elseif ( ($isBound = @ldap_bind($connection)) === true ) {
  448.                /**
  449.                 * Use case 3: Servers that might require a full user DN to
  450.                 * actually login and therefore let you bind anonymously first .
  451.                 * Try ldap_search + ldap_get_dn before attempting a login.
  452.                 * @see http://wordpress.org/support/topic/129814?replies=34#post-603644
  453.                 */
  454.                if ( ($results = @ldap_search($connection, $baseDn, $filterQuery, $returnKeys)) !== false ) {
  455.                    if ( ($userDn = @ldap_get_dn($connection, ldap_first_entry($connection, $results))) !== false ) {
  456.                        $isInDirectory = true; // account exists in directory
  457.                        if ( ($isBound = wpDirAuth_bindTest($connection, $userDn, $password,$baseDn)) === true ) {
  458.                            $isLoggedIn = true; // valid server, valid login, move on
  459.                            break; // valid server, valid login, move on
  460.                        }
  461.                    }
  462.                }
  463.            }
  464.        }
  465.  
  466.        if ( ($preBindUser && $preBindPassword) && ( ! $isPreBound ) ) {
  467.            return new WP_Error ('no_directory_or_prebinding', $errorTitle
  468.                . __(' wpDirAuth config error: No directory server available for authentication, OR pre-binding credentials denied.'));
  469.        }
  470.        elseif ( ( $isInDirectory ) && ( ! $isBound ) ) {
  471.            return new WP_Error ('could_not_bind_as_user', $errorTitle
  472.                . __(' Incorrect password.'));
  473.        }
  474.        elseif ( ! $isBound && ! $isPreBound ) {
  475.            return new WP_Error ('no_directory_available', $errorTitle
  476.                . __(' wpDirAuth config error: No directory server available for authentication.'));
  477.        }
  478.        elseif ( ! $isLoggedIn) {
  479.            /**
  480.             * @desc wp-hack was echo'ing out $username verbatim which allowed a XSS vulnerability. Encoded $username before echoing'
  481.             */
  482.            return new WP_Error ('could_not_authenticate', $errorTitle
  483.                . __(' Could not authenticate user. Please check your credentials.')
  484.                . " [" . htmlentities($username,ENT_QUOTES,'UTF-8') . "]");
  485.  
  486.  
  487.        }
  488.        else {
  489.            if($boolUseGroups == 1){
  490.                //the user is authenticated, but we want to make sure they are a member of the groups given
  491.                /**
  492.                 * We need to get the DN's for each Authentication Group CN that was given to us.
  493.                 */
  494.                $aryAuthGroupsDN = array();
  495.                $aryAuthGroups = explode(',',$strAuthGroups);
  496.                $aryAttribs = array('distinguishedname');
  497.                foreach($aryAuthGroups as $strAuthGroup){
  498.                    $strAuthGroup = 'cn='.$strAuthGroup;
  499.                    $rscLDAPSearch = ldap_search($connection,$baseDn,$strAuthGroup,$aryAttribs);
  500.                    $arySearchResults = ldap_get_entries($connection,$rscLDAPSearch);
  501.                    if(isset($arySearchResults[0]['dn'])){
  502.                        $aryAuthGroupsDN[] = $arySearchResults[0]['dn'];
  503.                    }
  504.                }
  505.  
  506.                if(count($aryAuthGroupsDN) == 0){
  507.                    return new WP_Error('no_auth_groups_found',$errorTitle.__('No Authentication Groups found based on given group CN'));
  508.                }
  509.  
  510.  
  511.                $strFilterQuery = '(&'.$filterQuery.'(|';
  512.                foreach($aryAuthGroupsDN as $strAuthGroupDN){
  513.                    $strFilterQuery .= '(memberOf='.$strAuthGroupDN.')';
  514.                }
  515.                $strFilterQuery .= '))';
  516.                if(($rscLDAPSearchGroupMember = ldap_search($connection,$baseDn,$strFilterQuery)) !== false){
  517.                    $arySearchResultsMember = ldap_get_entries($connection,$rscLDAPSearchGroupMember);
  518.                    if($arySearchResultsMember['count'] !== 1){
  519.                        return new WP_Error('not_member_of_auth_group',$errorTitle
  520.                            . __('User authenticated but is not a member of an Authentication Group(s)'));
  521.                    }
  522.                }
  523.  
  524.            }
  525.  
  526.  
  527.            /**
  528.             * Search for profile, if still needed.
  529.             * @see $results in preceding loop: Use case 3
  530.             */
  531.            if (!$results){
  532.                return wpDirAuth_retrieveUserDetails($connection,$baseDn,$filterQuery);
  533.            } else {
  534.                return wpDirAuth_retrieveUserDetails($connection,$baseDn,$filterQuery,$results);
  535.            }
  536.        }
  537.    }
  538.  
  539.  
  540.    /**
  541.     * Runs stripslashes, html_entity_decode, then strip_tags with
  542.     * allowed html if requested.
  543.     *
  544.     * No input sashimi for us (hopefully).
  545.     *
  546.     * @param string $value Value to `sanitize`
  547.     * @param boolean $allowed Set to true for WPDIRAUTH_ALLOWED_TAGS
  548.     * @return string Cleaner value.
  549.     *
  550.     * @uses WPDIRAUTH_ALLOWED_TAGS
  551.     */
  552.    function wpDirAuth_sanitize($value, $allowed = false)
  553.    {
  554.        $allowed = ($allowed) ? WPDIRAUTH_ALLOWED_TAGS : '';
  555.        return strip_tags(html_entity_decode(stripslashes($value)), $allowed);
  556.    }
  557.  
  558.  
  559.    /**
  560.     * wpDirAuth plugin configuration panel.
  561.     * Processes and outputs the wpDirAuth configuration form.
  562.     *
  563.     * @return void
  564.     *
  565.     * @uses WPDIRAUTH_DEFAULT_FILTER
  566.     * @uses WPDIRAUTH_DEFAULT_LOGINSCREENMSG
  567.     * @uses WPDIRAUTH_DEFAULT_CHANGEPASSMSG
  568.     * @uses WPDIRAUTH_ALLOWED_TAGS
  569.     * @uses wpDirAuth_makeCookieMarker
  570.     * @uses wpDirAuth_sanitize
  571.     */
  572.    function wpDirAuth_optionsPanel()
  573.    {
  574.        global $userdata;
  575.  
  576.        $wpDARef     = WPDIRAUTH_SIGNATURE;
  577.        $allowedHTML = htmlentities(WPDIRAUTH_ALLOWED_TAGS);
  578.  
  579.        $curUserIsDirUser = get_usermeta($userdata->ID, 'wpDirAuthFlag');
  580.  
  581.        if ($curUserIsDirUser) {
  582.            echo <<<____________EOS
  583.            <div class="wrap">
  584.                <h2>Directory Authentication Options</h2>
  585.                <p>
  586.                    Because any changes made to directory authentication
  587.                    options can adversly affect your session when logged in
  588.                    as a directory user, you must be logged in as a
  589.                    WordPress-only administrator user to update these settings.
  590.                </p>
  591.                <p>
  592.                    If such a user no longer exists in the database, please
  593.                    <a href="./users.php#add-new-user">create a new one</a>
  594.                    using the appropriate WordPress admin tool.
  595.                 </p>
  596.                 <p>$wpDARef</p>
  597.             </div>
  598. ____________EOS;
  599.             return;
  600.         }
  601.  
  602.         if ($_POST) {
  603.             $enableSsl        = 0; //default
  604.             $boolUseGroups    = 0; //default
  605.             // Booleans
  606.             $enable           = intval($_POST['dirAuthEnable'])      == 1 ? 1 : 0;
  607.             $requireSsl       = intval($_POST['dirAuthRequireSsl'])  == 1 ? 1 : 0;
  608.             $TOS              = intval($_POST['dirAuthTOS'])         == 1 ? 1 : 0;
  609.  
  610.             //integers
  611.             if(intval($_POST['dirAuthEnableSsl']) == 1 || intval($_POST['dirAuthEnableSsl']) == 2){
  612.                 $enableSsl        = intval($_POST['dirAuthEnableSsl']);
  613.             }
  614.  
  615.  
  616.             // Strings, no HTML
  617.             $controllers      = wpDirAuth_sanitize($_POST['dirAuthControllers']);
  618.             $baseDn           = wpDirAuth_sanitize($_POST['dirAuthBaseDn']);
  619.             $preBindUser      = wpDirAuth_sanitize($_POST['dirAuthPreBindUser']);
  620.             $preBindPassword  = wpDirAuth_sanitize($_POST['dirAuthPreBindPassword']);
  621.             $preBindPassCheck = wpDirAuth_sanitize($_POST['dirAuthPreBindPassCheck']);
  622.             $accountSuffix    = wpDirAuth_sanitize($_POST['dirAuthAccountSuffix']);
  623.             $filter           = wpDirAuth_sanitize($_POST['dirAuthFilter']);
  624.             $institution      = wpDirAuth_sanitize($_POST['dirAuthInstitution']);
  625.             $strAuthGroups    = wpDirAuth_sanitize($_POST['dirAuthGroups']);
  626.             $strMarketingSSOID= wpDirAuth_sanitize(($_POST['dirAuthMarketingSSOID']));
  627.  
  628.             if($strAuthGroups != ''){
  629.                 $boolUseGroups = 1;
  630.             }
  631.  
  632.             // Have to be allowed to contain some HTML
  633.             $loginScreenMsg   = wpDirAuth_sanitize($_POST['dirAuthLoginScreenMsg'], true);
  634.             $changePassMsg    = wpDirAuth_sanitize($_POST['dirAuthChangePassMsg'], true);
  635.  
  636.             update_site_option('dirAuthEnable',          $enable);
  637.             update_site_option('dirAuthEnableSsl',       $enableSsl);
  638.             update_site_option('dirAuthRequireSsl',      $requireSsl);
  639.             update_site_option('dirAuthControllers',     $controllers);
  640.             update_site_option('dirAuthBaseDn',          $baseDn);
  641.             update_site_option('dirAuthPreBindUser',     $preBindUser);
  642.             update_site_option('dirAuthAccountSuffix',   $accountSuffix);
  643.             update_site_option('dirAuthFilter',          $filter);
  644.             update_site_option('dirAuthInstitution',     $institution);
  645.             update_site_option('dirAuthLoginScreenMsg',  $loginScreenMsg);
  646.             update_site_option('dirAuthChangePassMsg',   $changePassMsg);
  647.             update_site_option('dirAuthTOS',             $TOS);
  648.             update_site_option('dirAuthUseGroups',       $boolUseGroups);
  649.             update_site_option('dirAuthGroups',          $strAuthGroups);
  650.             update_site_option('dirAuthMarketingSSOID',  $strMarketingSSOID);
  651.  
  652.  
  653.             // Only store/override the value if a new one is being sent a bind user is set.
  654.             if ( $preBindUser && $preBindPassword && ($preBindPassCheck == $preBindPassword) )
  655.                 update_site_option('dirAuthPreBindPassword', $preBindPassword);
  656.  
  657.             // Clear the stored password if the Bind DN is null
  658.             elseif ( ! $preBindUser)
  659.                 update_site_option('dirAuthPreBindPassword', '');
  660.  
  661.             if (get_site_option('dirAuthEnable') && !get_site_option('dirAuthCookieMarker'))
  662.                 wpDirAuth_makeCookieMarker();
  663.  
  664.             echo '<div id="message" class="updated fade"><p>Your new settings were saved successfully.</p></div>';
  665.  
  666.             // Be sure to clear $preBindPassword, not to be displayed onscreen or in source
  667.             unset($preBindPassword);
  668.         }
  669.         else {
  670.             // Booleans
  671.             $enable          = intval(get_site_option('dirAuthEnable'))     == 1 ? 1 : 0;
  672.             $requireSsl      = intval(get_site_option('dirAuthRequireSsl')) == 1 ? 1 : 0;
  673.             $TOS             = intval(get_site_option('dirAuthTOS'))        == 1 ? 1 : 0;
  674.             $boolUseGroups   = intval(get_site_option('dirAuthUseGroups'))  == 1 ? 1 : 0;
  675.  
  676.             //integers
  677.             $enableSsl       = intval(get_site_option('dirAuthEnableSsl',0));
  678.  
  679.             // Strings, no HTML
  680.             $controllers        = wpDirAuth_sanitize(get_site_option('dirAuthControllers'));
  681.             $baseDn             = wpDirAuth_sanitize(get_site_option('dirAuthBaseDn'));
  682.             $preBindUser        = wpDirAuth_sanitize(get_site_option('dirAuthPreBindUser'));
  683.             $accountSuffix      = wpDirAuth_sanitize(get_site_option('dirAuthAccountSuffix'));
  684.             $filter             = wpDirAuth_sanitize(get_site_option('dirAuthFilter'));
  685.             $institution        = wpDirAuth_sanitize(get_site_option('dirAuthInstitution'));
  686.             $strAuthGroups      = wpDirAuth_sanitize((get_site_option('dirAuthGroups')));
  687.             $strMarketingSSOID  = wpDirAuth_sanitize((get_site_option('dirAuthMarketingSSOID')));
  688.  
  689.             // Have to be allowed to contain some HTML
  690.             $loginScreenMsg  = wpDirAuth_sanitize(get_site_option('dirAuthLoginScreenMsg'), true);
  691.             $changePassMsg   = wpDirAuth_sanitize(get_site_option('dirAuthChangePassMsg'), true);
  692.         }
  693.  
  694.         $controllers    = htmlspecialchars($controllers);
  695.         $baseDn         = htmlspecialchars($baseDn);
  696.         $preBindUser    = htmlspecialchars($preBindUser);
  697.         $accountSuffix  = htmlspecialchars($accountSuffix);
  698.         $filter         = htmlspecialchars($filter);
  699.         $institution    = htmlspecialchars($institution);
  700.         $loginScreenMsg = htmlspecialchars($loginScreenMsg);
  701.         $changePassMsg  = htmlspecialchars($changePassMsg);
  702.         $strAuthGroups  = htmlspecialchars($strAuthGroups);
  703.  
  704.         if ($enable) {
  705.             $tEnable = "checked";
  706.         }
  707.         else {
  708.             $fEnable = "checked";
  709.         }
  710.  
  711.         $defaultFilter = WPDIRAUTH_DEFAULT_FILTER;
  712.         if (!$filter) {
  713.             $filter = $defaultFilter;
  714.         }
  715.  
  716.         if (!$institution) {
  717.             $institution = '[YOUR INSTITUTION]';
  718.         }
  719.  
  720.         if (!$loginScreenMsg) {
  721.             $loginScreenMsg = sprintf(WPDIRAUTH_DEFAULT_LOGINSCREENMSG, $institution);
  722.         }
  723.  
  724.         if (!$changePassMsg) {
  725.             $changePassMsg = sprintf(WPDIRAUTH_DEFAULT_CHANGEPASSMSG, $institution);
  726.         }
  727.  
  728.         /*
  729.         if ($enableSsl) {
  730.             $tSsl = "checked";
  731.         }
  732.         else {
  733.             $fSsl = "checked";
  734.         }
  735.         */
  736.         $strNoSSL ='';
  737.         $strSSL = '';
  738.         $strTLS = '';
  739.         $strOptionSelected = 'selected="selected"';
  740.         switch($enableSsl){
  741.             case 1:
  742.                 $strSSL = $strOptionSelected;
  743.                 break;
  744.             case 2:
  745.                 $strTLS = $strOptionSelected;
  746.                 break;
  747.             case 0:
  748.             default:
  749.                 $strNoSSL = $strOptionSelected;
  750.                 break;
  751.  
  752.         }
  753.  
  754.         if ($requireSsl) {
  755.             $tWpSsl = "checked";
  756.         }
  757.         else {
  758.             $fWpSsl = "checked";
  759.         }
  760.  
  761.         if ($TOS) {
  762.             $tTOS = "checked";
  763.         }
  764.         else {
  765.             $fTOS = "checked";
  766.         }
  767.  
  768.         $wpDAV = WPDIRAUTH_VERSION;
  769.  
  770.         echo <<<________EOS
  771.         <div class="wrap">
  772.             <h2>Directory Authentication Options</h2>
  773.             <form method="post" id="dir_auth_options">
  774.                 <p class="submit"><input type="submit" name="dirAuthOptionsSave" value="Update Options &raquo;" /></p>
  775.                 <fieldset class="options">
  776.                     <legend>WordPress Settings</legend>
  777.                     <ul>
  778.                         <li>
  779.                             <label for="dirAuthEnable"><strong>Enable Directory Authentication?</strong></label>
  780.                             <br />
  781.                             <input type="radio" name="dirAuthEnable" value="1" $tEnable /> Yes &nbsp;
  782.                             <input type="radio" name="dirAuthEnable" value="0" $fEnable /> No
  783.                             <br />
  784.                             <strong>Note 1</strong>: Users created in WordPress are not affected by your directory authentication settings.
  785.                             <br />
  786.                             <strong>Note 2</strong>: You will still be able to login with standard WP users if the LDAP server(s) go offline.
  787.                             </li>
  788.                         <li>
  789.                             <label for="dirAuthRequireSsl"><strong>Require SSL Login?</strong></label>
  790.                             <br />
  791.                             <input type="radio" name="dirAuthRequireSsl" value="1" $tWpSsl/> Yes &nbsp;
  792.                             <input type="radio" name="dirAuthRequireSsl" value="0" $fWpSsl/> No
  793.                             <br />
  794.                             <em>Force the WordPress login screen to require encryption (SSL, https:// URL)?</em>
  795.                         </li>
  796.                     </ul>
  797.                 </fieldset>
  798.                 <fieldset class="options">
  799.                     <legend>Directory Settings</legend>
  800.                     <ul>
  801.                         <li>
  802.                             <label for="dirAuthEnableSsl"><strong>Enable SSL Connectivity?</strong></label>
  803.                             <br />
  804.                             <!--
  805.                             <input type="radio" name="dirAuthEnableSsl" value="1" $tSsl/> Yes &nbsp;
  806.                             <input type="radio" name="dirAuthEnableSsl" value="0" $fSsl/> No
  807.                             -->
  808.                             <select id="dirAuthEnableSsl" name="dirAuthEnableSsl">
  809.                                 <option value="0" $strNoSSL>No SSL Connectivity</option>
  810.                                 <option value="1" $strSSL>Use SSL (ldaps)</option>
  811.                                 <option value="2" $strTLS>Use TLS</option>
  812.                             </select>
  813.                             <br />
  814.                             <em>Use encryption (TLS, SSL, ldaps:// URL) when WordPress connects to the directory server(s)?</em>
  815.                         </li>
  816.                         <li>
  817.                             <label for="dirAuthControllers"><strong>Directory Servers (Domain Controllers)</strong></label>
  818.                             <br />
  819.                             <input type="text" name="dirAuthControllers" value="$controllers" size="40"/><br />
  820.                             <em>The DNS name or IP address of the directory server(s).</em><br />
  821.                             <strong>NOTE:</strong> Separate multiple entries by a comma and/or alternate ports with a colon (eg: my.server1.org, my.server2.edu:387).
  822.                             Unfortunately, alternate ports will be ignored when using LDAP/SSL, because of <a href="http://ca3.php.net/ldap_connect">the way</a> PHP handles the protocol.
  823.  
  824.                         </li>
  825.                         <li>
  826.                             <label for="dirAuthFilter"><strong>Account Filter</strong></label>
  827.                             <br />
  828.                             <input type="text" name="dirAuthFilter" value="$filter" size="40"/>
  829.                             (Defaults to <em>$defaultFilter</em>)
  830.                             <br />
  831.                             <em>What LDAP field should we search the username against to locate the user's profile after successful login?</em>
  832.                        </li>
  833.                        <li>
  834.                            <label for="dirAuthAccountSuffix"><strong>Account Suffix</strong></label>
  835.                            <br />
  836.                            <input type="text" name="dirAuthAccountSuffix" value="$accountSuffix" size="40" /><br />
  837.                            <em>Suffix to be automatically appended to the username if desired. e.g. @domain.com</em><br />
  838.                            <strong>NOTE:</strong> Changing this value will cause your existing directory users to have new accounts created the next time they login.
  839.                        </li>
  840.                        <li>
  841.                            <label for="dirAuthBaseDn"><strong>Base DN</strong></label>
  842.                            <br />
  843.                            <input type="text" name="dirAuthBaseDn" value="$baseDn" size="40"/><br />
  844.                            <em>The base DN for carrying out LDAP searches.</em>
  845.                        </li>
  846.                        <li>
  847.                            <label for="dirAuthPreBindUser"><strong>Bind DN</strong></label>
  848.                            <br />
  849.                            <input type="text" name="dirAuthPreBindUser" value="$preBindUser" size="40"/><br />
  850.                            <em>Enter a valid user account/DN to pre-bind with if your LDAP server does not allow anonymous profile searches, or requires a user with specific privileges to search.</em>
  851.                        </li>
  852.                        <li>
  853.                            <label for="dirAuthPreBindPassword"><strong>Bind Password</strong></label>
  854.                            <br />
  855.                            <input type="password" name="dirAuthPreBindPassword" value="" size="40"/><br />
  856.                            <em>Enter a password for the above Bind DN if a value is needed.</em><br />
  857.                            <strong>Note 1</strong>: this value will be stored in clear text in your WordPress database.<br />
  858.                            <strong>Note 2</strong>: Simply clear the Bind DN value if you wish to delete the stored password altogether.
  859.                        </li>
  860.                        <li>
  861.                            <label for="dirAuthPreBindPassCheck"><strong>Confirm Password</strong></label>
  862.                            <br />
  863.                            <input type="password" name="dirAuthPreBindPassCheck" value="" size="40"/><br />
  864.                            <em>Confirm the above Bind Password if you are setting a new value.</em>
  865.                        </li>
  866.                        <li>
  867.                            <label for="dirAuthGroups"><strong>Authentication Groups</strong></label><br />
  868.                            <input type="text" name="dirAuthGroups" id="dirAuthGroups" size="40" value="$strAuthGroups" /><br />
  869.                            <em>Enter each group CN that the user must be a member of in order to authenticate.</em> <br />
  870.                            <strong>NOTE:</strong> Separate multiple CNs by a comma.
  871.                        </li>
  872.                    </ul>
  873.                </fieldset>
  874.                <fieldset class="options">
  875.                    <legend>Branding Settings</legend>
  876.                    <ul>
  877.                        <li>
  878.                            <label for="dirAuthInstitution"><strong>Institution Name</strong></label>
  879.                            <br />
  880.                            <input type="text" name="dirAuthInstitution" value="$institution" size="40" />
  881.                            <br />
  882.                            <em>Name of your institution/company. Displayed on the login screen.</em>
  883.                        </li>
  884.  
  885.                        <li>
  886.                            <label for=""><strong>Marketing name for Institutional Single-Sign-On ID</strong></label>
  887.                            <br />
  888.                            <input type="text" name="dirAuthMarketingSSOID" value="$strMarketingSSOID" id="dirAuthMarketingSSOID" size="40" />
  889.                            <br />
  890.                            <em>How your institution/company refers to the single-sign-on ID you use.</em>
  891.                        </li>
  892.                        <li>
  893.                            <label for="dirAuthLoginScreenMsg"><strong>Login Screen Message</strong></label>
  894.                            <br />
  895.                            <textarea name="dirAuthLoginScreenMsg" cols="40" rows="3">$loginScreenMsg</textarea>
  896.                            <br />
  897.                            <em>Displayed on the login screen, underneath the username/password fields.</em><br />
  898.                            <strong>Note</strong>: Some HTML allowed: $allowedHTML
  899.                        </li>
  900.                        <li>
  901.                            <label for="dirAuthChangePassMsg"><strong>Password Change Message</strong></label>
  902.                            <br />
  903.                            <textarea name="dirAuthChangePassMsg" cols="40" rows="3">$changePassMsg</textarea>
  904.                            <br />
  905.                            <em>Displayed wherever user passwords can be changed, for directory users only.</em><br />
  906.                            <strong>Note</strong>: Some HTML allowed: $allowedHTML
  907.  
  908.                        </li>
  909.                        <li>
  910.                            <label for="dirAuthTOS"><strong>Terms of Services Agreement</strong></label>
  911.                            <br />
  912.                            <input type="radio" name="dirAuthTOS" value="1" $tTOS/> Yes &nbsp;
  913.                            <input type="radio" name="dirAuthTOS" value="0" $fTOS/> No
  914.                            <br />
  915.                            <em>Ask directory users to agree to terms of services that you link to in the message above?</em><br />
  916.                            <strong>Note</strong>: Checkbox disappears once checked, date of agreement is stored and users are no longer prompted.
  917.                        </li>
  918.                        </ul>
  919.                </fieldset>
  920.                <p class="submit"><input type="submit" name="dirAuthOptionsSave" value="Update Options &raquo;" /></p>
  921.            </form>
  922.            <p>Powered by $wpDARef.</p>
  923.        </div>
  924. ________EOS;
  925.    }
  926.  
  927.  
  928.    /**
  929.     * Adds the `Directory Auth.` menu entry in the Wordpress Admin section, and the `Add Directory Authenticated User` to the Users menu
  930.     * Also activates the wpDirAuth config panel as a callback function.
  931.     *
  932.     * @uses wpDirAuth_optionsPanel
  933.     * @uses wpDirAuth_add_user_panel
  934.     */
  935.    function wpDirAuth_addMenu()
  936.    {
  937.        if (function_exists('add_options_page')) {
  938.            add_options_page(
  939.                'Directory Authentication Options',
  940.                'Directory Auth.',
  941.                9,
  942.                basename(__FILE__),
  943.                'wpDirAuth_optionsPanel'
  944.            );
  945.        }
  946.    }
  947.  
  948.  
  949.    /**
  950.     * Extending WP's login_form.
  951.      * Enforces the admin defined SSL login preferences and adds a directory
  952.      * login related message to the standard WP login screen.
  953.      *
  954.      * @uses WPDIRAUTH_DEFAULT_LOGINSCREENMSG
  955.      */
  956.     function wpDirAuth_loginFormExtra()
  957.     {
  958.         if (get_site_option('dirAuthEnable')) {
  959.  
  960.             if (isset($_SERVER['SCRIPT_URI']) && preg_match('|^http|',$_SERVER['SCRIPT_URI'])) {
  961.                 $selfURL = $_SERVER['SCRIPT_URI'];
  962.             }
  963.             else {
  964.                 /**
  965.                  * $_SERVER['SCRIPT_URI'] seems to be unavilable in some PHP
  966.                  * installs, and $_SERVER['REQUEST_URI'] and $_SERVER['PHP_SELF']
  967.                  * have been known to sometimes have the same issue.
  968.                  * Thanks to Todd Beverly for helping out with this one. :)
  969.                  * @see http://wordpress.org/support/topic/129814?replies=27#post-605423
  970.                  */
  971.                 $selfURL = sprintf(
  972.                     'http%s://%s%s',
  973.                     (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : ''),
  974.                     $_SERVER['HTTP_HOST'],
  975.                     (isset($_SERVER['REQUEST_URI'])
  976.                         ? $_SERVER['REQUEST_URI']
  977.                         : $_SERVER["SCRIPT_NAME"].'?'.$_SERVER['QUERY_STRING'])
  978.                 );
  979.             }
  980.  
  981.             //_log('contents of selfurl: '.$selfURL);
  982.  
  983.  
  984.             if (get_site_option('dirAuthRequireSsl') && (!preg_match('|^https|',$selfURL))) {
  985.                 $sslURL = str_replace('http://','https://',$selfURL);
  986.  
  987.                 $refreshJS   = '<script type="text/javascript">'."\n".'top.location.href=\''.$sslURL.'\';'."\n".'</script>" />';
  988.                 $refreshMeta = '<meta http-equiv="refresh" content="0;url='.$sslURL.'" />';
  989.                 $refreshMsg  = 'Please access the <a href="'.$sslURL.'">encrypted version</a> of this page.';
  990.  
  991.                 if (headers_sent()) {
  992.                     echo $refreshJS.$refreshMeta.'<p>'.$refreshMsg.'</p></form></div></html>';
  993.                 }
  994.                 else {
  995.                     @ob_end_clean();
  996.                     if (!@header('Location:'.$sslURL)) {
  997.                         echo '<html><head>'.$refreshJS.$refreshMeta.'</head>'
  998.                             . '<body>'.$refreshMsg.'</body></html>';
  999.                     }
  1000.                 }
  1001.  
  1002.                 exit;
  1003.             }
  1004.  
  1005.             $dirAuthInstitution = stripslashes(get_site_option('dirAuthInstitution'));
  1006.             if (!$dirAuthInstitution) $dirAuthInstitution = __('Directory');
  1007.  
  1008.             $loginScreenMsg = stripslashes(get_site_option('dirAuthLoginScreenMsg'));
  1009.             if (!$loginScreenMsg) $loginScreenMsg = __(sprintf(
  1010.                 WPDIRAUTH_DEFAULT_LOGINSCREENMSG,
  1011.                 get_site_option('dirAuthInstitution')
  1012.             ));
  1013.  
  1014.             echo '
  1015.                <style>.wpDirAuthMsg a, .wpDirAuthMsg a:visited {color: #ebcd4e;}</style>
  1016.                <p class="wpDirAuthMsg">'.$loginScreenMsg.'</p>
  1017.            ';
  1018.         }
  1019.     }
  1020.  
  1021.  
  1022.     /**
  1023.      * Extending WP's show_password_fields.
  1024.      * Displays the directory password change message in profile.php and user.php.
  1025.      *
  1026.      * @return boolean Return format as expected by WP's show_password_fields()
  1027.      *
  1028.      * @uses WPDIRAUTH_DEFAULT_CHANGEPASSMSG
  1029.      */
  1030.     function wpDirAuth_hidePassFields()
  1031.     {
  1032.         global $profileuser, $userdata;
  1033.  
  1034.         $editUserIsDirUser = get_usermeta($profileuser->ID, 'wpDirAuthFlag');
  1035.  
  1036.         if (!$editUserIsDirUser) {
  1037.             return true;
  1038.         }
  1039.         else {
  1040.             // Editing directory user profile, show password msg
  1041.             $message = stripslashes(get_site_option('dirAuthChangePassMsg'));
  1042.             if (!$message) {
  1043.                 $message = __(sprintf(
  1044.                     WPDIRAUTH_DEFAULT_CHANGEPASSMSG,
  1045.                     stripslashes(get_site_option('dirAuthInstitution'))
  1046.                 ));
  1047.             }
  1048.  
  1049.             if (get_site_option('dirAuthTOS')) {
  1050.                 // TOS option is ON
  1051.                 if (($TOSDate = get_usermeta($profileuser->ID, 'wpDirAuthTOS')) === '') {
  1052.                     if ($userdata->ID == $profileuser->ID) {
  1053.                         // Only show TOS acceptance checkbox to the owner of the profile.
  1054.                         $message .= '</p><p class="desc">'
  1055.                             .  '<input type="checkbox" name="wpDirAuthTOS" value="1" style="width:15px; height:15px;" /> '
  1056.                             .  __('Accept terms of services.')
  1057.                             .  '</p><p class="desc">';
  1058.                     }
  1059.                     else {
  1060.                         // Show generic message to other admins.
  1061.                         $message .= '</p><p class="desc">'
  1062.                             .  __('User has not yet agreed to the terms of services.')
  1063.                             .  '</p><p class="desc">';
  1064.                     }
  1065.                 }
  1066.                 else {
  1067.                     // Show TOS acceptance date
  1068.                     $message .= '</p><p class="desc">'
  1069.                         .  __('Terms of services accepted on')
  1070.                         .  ' '.$TOSDate
  1071.                         .  '</p><p class="desc">';
  1072.                 }
  1073.             }
  1074.  
  1075.             echo '<fieldset><legend>'
  1076.                 . __('Directory Password Update')
  1077.                 . '</legend><p class="desc">'
  1078.                 . $message
  1079.                 . '</p></fieldset>';
  1080.  
  1081.             return false;
  1082.         }
  1083.     }
  1084.  
  1085.  
  1086.     /**
  1087.      * Extending WP's profile_update.
  1088.      * Saves the TOS acceptance if sent.
  1089.      *
  1090.      * @param integer $userID Sent by WP profile_update action
  1091.      * @return boolean Return format as expected by WP's profile_update()
  1092.      */
  1093.     function wpDirAuth_profileUpdate($userID){
  1094.         if (intval($_POST['wpDirAuthTOS']) === 1) {
  1095.             update_usermeta($userID, 'wpDirAuthTOS', date('Y-m-d H:i:s'));
  1096.         }
  1097.         return true;
  1098.     }
  1099.  
  1100.  
  1101.     /**
  1102.      * WP's wp_authenticate overwrite.
  1103.      * Processes the directory login and creates a new user on first access.
  1104.      *
  1105.      * @param string $username Login form username.
  1106.      * @param string $password Login form password
  1107.      * @return WP_Error|WP_User WP_User object if login successful, otherwise WP_Error object.
  1108.      *
  1109.      * @uses wpDirAuth_makeCookieMarker
  1110.      * @uses wpDirAuth_auth
  1111.      *
  1112.      * @see http://codex.wordpress.org/Pluggable_Functions
  1113.      */
  1114.     function wp_authenticate($username, $password)
  1115.     {
  1116.         //echo 'authenticating';exit;
  1117.         $boolRestoreBlog = false;
  1118.         if(defined('WPDIRAUTH_MULTISITE') && WPDIRAUTH_MULTISITE){
  1119.             //echo 'I should switch blogs!';exit;
  1120.             global $blog_id;
  1121.             $intOriginalBlog = $blog_id;
  1122.             switch_to_blog(1); //switch to the parent blog
  1123.             $boolRestoreBlog = true;
  1124.         }
  1125.         /**
  1126.          * @desc wp-hack for some reason, this function is being called even when a user just goes to the login page. added the next 3 lines so that
  1127.          * if the user arrives via $_GET, then we simply tell them to login
  1128.          */
  1129.         if($_SERVER['REQUEST_METHOD'] != 'POST'){
  1130.             if($boolRestoreBlog) restore_current_blog();
  1131.             return new WP_Error('incorrect_method',__('<strong>Please Login</strong>'));
  1132.         }
  1133.  
  1134.         if (!$username) {
  1135.             if($boolRestoreBlog) restore_current_blog();
  1136.             return new WP_Error('empty_username', __('<strong>Login Error</strong>:
  1137.                        The username field is empty.'));
  1138.         }
  1139.  
  1140.         if (!$password) {
  1141.             if($boolRestoreBlog) restore_current_blog();
  1142.             return new WP_Error('empty_password', __('<strong>Login Error</strong>:
  1143.                        The password field is empty.'));
  1144.         }
  1145.  
  1146.         $enable       = get_site_option('dirAuthEnable');
  1147.         $cookieMarker = get_site_option('dirAuthCookieMarker');
  1148.  
  1149.         if (!$cookieMarker) {
  1150.             $cookieMarker = wpDirAuth_makeCookieMarker();
  1151.         }
  1152.  
  1153.         /**
  1154.          * Get the login object. We will use it for first user insertion or when the
  1155.          * directory auth option is not activated.
  1156.          */
  1157.         $login = get_userdatabylogin($username);
  1158.         $loginUserIsDirUser = ($login) ? get_usermeta($login->ID, 'wpDirAuthFlag') : 0;
  1159.  
  1160.         if (!$enable && $loginUserIsDirUser) {
  1161.             /*
  1162.              * Existing directory user, but directory access has now been disabled.
  1163.              */
  1164.             if($boolRestoreBlog) restore_current_blog();
  1165.             do_action( 'wp_login_failed', $username );
  1166.             return new WP_Error('login_disabled',__('<strong>Directory Login Error</strong>:
  1167.                        Sorry, but the site administrators have disabled
  1168.                        directory access in this WordPress install.'));
  1169.         }
  1170.         elseif ($enable) {
  1171.             /**
  1172.              * Directory auth == true
  1173.              */
  1174.  
  1175.             if (!$login) {
  1176.                 /**
  1177.                  * No existing account record found, try dir auth
  1178.                  */
  1179.                 $userData = wpDirAuth_auth($username,$password);
  1180.  
  1181.                 if ( !is_wp_error($userData) ) {
  1182.                     /**
  1183.                      * Passed directory signin, so create a new WP user
  1184.                      */
  1185.                     require_once(ABSPATH . WPINC . '/registration.php');
  1186.  
  1187.                     $userLogin = sanitize_user($username);
  1188.                     $userEmail = apply_filters('user_registration_email', $userData['email']);
  1189.  
  1190.                     if (username_exists($userLogin)) {
  1191.                         /*
  1192.                          * Username exists.
  1193.                          */
  1194.                         if($boolRestoreBlog) restore_current_blog();
  1195.                         do_action( 'wp_login_failed', $username );
  1196.                         return new WP_Error('username_exists',__('<strong>Directory Login Error</strong>:
  1197.                                    Could not create a new WP user account
  1198.                                    because the directory username <strong>' . htmlentities($userLogin,ENT_QUOTES,'UTF-8') . '</strong> is already
  1199.                                    registered on this site.'));
  1200.                     }
  1201.                     elseif (email_exists($userEmail)) {
  1202.                         /*
  1203.                          * Email exists.
  1204.                          */
  1205.                         if($boolRestoreBlog) restore_current_blog();
  1206.                         do_action( 'wp_login_failed', $username );
  1207.                         return new WP_Error('email_exists',__('<strong>Directory Login Error</strong>:
  1208.                                    Could not create a new WP account because
  1209.                                    the email <strong>' . htmlentities($userEmail,ENT_QUOTES,'UTF-8') . '</strong> is
  1210.                                    already registered with this site.'));
  1211.                     }
  1212.                     else {
  1213.                         if(defined('WPDIRAUTH_MULTISITE') && WPDIRAUTH_MULTISITE && isset($boolRestoreBlog) && $boolRestoreBlog){
  1214.                             restore_current_blog();
  1215.                         }
  1216.  
  1217.                         if ($userID = wp_create_user($userLogin, $password, $userEmail)) {
  1218.                             $userData['ID'] = $userID;
  1219.                             $tmpAr = split('@',$userData['email']);
  1220.                             $userData['nickname'] =  str_replace('.','_',$tmpAr[0]);
  1221.                             $userData['display_name'] = $userData['first_name'].' '.$userData['last_name'];
  1222.                             unset($userData['email']);
  1223.  
  1224.                             wp_update_user($userData);
  1225.                             update_usermeta($userID, 'wpDirAuthFlag', 1);
  1226.                             wpDirAuth_remove_password_nag($userID);
  1227.                             //if($boolRestoreBlog) restore_current_blog();
  1228.                             return new WP_User($userID);
  1229.                         }
  1230.                         else {
  1231.                             /*
  1232.                             * Unknown error.
  1233.                             */
  1234.                             //if($boolRestoreBlog) restore_current_blog();
  1235.                             do_action( 'wp_login_failed', $username );
  1236.                             return new WP_Error('creation_unknown_error',__('<strong>Directory Login Error</strong>:
  1237.                                            Could not create a new user account.
  1238.                                            Unknown error. [user: ' . htmlentities($userLogin,ENT_QUOTES,'UTF-8') . ', email: ' . htmlentities($userEmail,ENT_QUOTES,'UTF-8') . ']'));
  1239.                         }
  1240.                     }
  1241.                 }
  1242.                 else {
  1243.                     /*
  1244.                      * Did not pass dir auth, and no login present in WP
  1245.                      */
  1246.                     if($boolRestoreBlog) restore_current_blog();
  1247.                     do_action( 'wp_login_failed', $username );
  1248.                     return $userData;
  1249.                 }
  1250.             }
  1251.             else {
  1252.                 /*
  1253.                  * Dealing with an existing WP account
  1254.                  */
  1255.                 if (!$loginUserIsDirUser) {
  1256.                     /*
  1257.                      * WP-only user
  1258.                      */
  1259.                     if ( wp_check_password($password, $login->user_pass, $login->ID) ) {
  1260.                         /*
  1261.                          * WP user, password okay.
  1262.                          */
  1263.                         if($boolRestoreBlog) restore_current_blog();
  1264.                         return new WP_User($login->ID);
  1265.                     }
  1266.                     else {
  1267.                         /*
  1268.                          * WP user, wrong pass
  1269.                          */
  1270.                         if($boolRestoreBlog) restore_current_blog();
  1271.                         do_action( 'wp_login_failed', $username );
  1272.                         return new WP_Error('incorrect_password',__('<strong>WordPress Login Error</strong>:
  1273.                                    Incorrect password.'));
  1274.                     }
  1275.                 }
  1276.                 else {
  1277.                     /**
  1278.                      * Directory user, try ldap binding
  1279.                      */
  1280.                     $userData = wpDirAuth_auth($username,$password);
  1281.  
  1282.                     if ( !is_wp_error($userData) ) {
  1283.                         /*
  1284.                          * Directory user, password okay.
  1285.                          */
  1286.                         wpDirAuth_remove_password_nag($login->ID);
  1287.                         if($boolRestoreBlog) restore_current_blog();
  1288.                         return new WP_User($login->ID);
  1289.                     }
  1290.                     else {
  1291.                         /*
  1292.                          * Directory user, wrong pass
  1293.                          */
  1294.                         if($boolRestoreBlog) restore_current_blog();
  1295.                         do_action( 'wp_login_failed', $username );
  1296.                         return $userData;
  1297.                     }
  1298.                 }
  1299.             }
  1300.         }
  1301.         else {
  1302.             /**
  1303.              * Directory auth == false
  1304.              */
  1305.             if (!$login || ($login->user_login != $username) ) {
  1306.                 /**
  1307.                  * No existing account record found
  1308.                  */
  1309.                 if($boolRestoreBlog) restore_current_blog();
  1310.                 do_action( 'wp_login_failed', $username );
  1311.                 return new WP_Error('failed_login',__('<strong>WordPress Login Error</strong>:
  1312.                            Could not authenticate user.
  1313.                            Please check your credentials.'));
  1314.             }
  1315.             else {
  1316.                 /*
  1317.                  * Found an existing WP account.
  1318.                  */
  1319.                 if ( wp_check_password($password, $login->user_pass, $login->ID) ) {
  1320.                     /*
  1321.                      * WP user, password okay.
  1322.                      */
  1323.                     if($boolRestoreBlog) restore_current_blog();
  1324.                     return new WP_User($login->ID);
  1325.                 }
  1326.                 else {
  1327.                     /*
  1328.                      * WP user, wrong pass
  1329.                      */
  1330.                     if($boolRestoreBlog) restore_current_blog();
  1331.                     do_action( 'wp_login_failed', $username );
  1332.                     return new WP_Error('incorrect_password',__('<strong>WordPress Login Error</strong>:
  1333.                                Incorrect password.'));
  1334.                 }
  1335.             }
  1336.         }
  1337.     }
  1338.  
  1339.  
  1340.     /**
  1341.      * WordPress wp_setcookie overwrite.
  1342.      * Sets the WP session cookies.
  1343.      *
  1344.      * @param string $username Login form username.
  1345.      * @param string $password Login form password
  1346.      * @param boolean $already_md5 Has the pswd been double-hashed already?
  1347.      * @param string $home
  1348.      * @param string $siteurl
  1349.      * @param boolean $remember
  1350.      * @return void
  1351.      *
  1352.      * @uses wpDirAuth_makeCookieMarker
  1353.      *
  1354.      * @see http://codex.wordpress.org/Pluggable_Functions
  1355.      */
  1356.     function wp_setcookie($username, $password, $already_md5 = false, $home = '', $siteurl = '', $remember = false)
  1357.     {
  1358.         global $wpdb;
  1359.  
  1360.         /**
  1361.          * Try to locate the user's record and define if it is an existing directory user
  1362.          */
  1363.         $login = get_userdatabylogin($username);
  1364.         //$login = $wpdb->get_row('SELECT ID FROM $wpdb->users WHERE user_login = '$username'');
  1365.         $loginUserIsDirUser = ($login) ? get_usermeta($login->ID, 'wpDirAuthFlag') : 0;
  1366.  
  1367.         /**
  1368.          * Get wpsDirAuth options
  1369.          */
  1370.         $enable       = get_site_option('dirAuthEnable');
  1371.         $cookieMarker = get_site_option('dirAuthCookieMarker');
  1372.  
  1373.         if (!$cookieMarker) {
  1374.             $cookieMarker = wpDirAuth_makeCookieMarker();
  1375.         }
  1376.  
  1377.         /**
  1378.          * Set the password hash cookie
  1379.          */
  1380.         if (($enable) && ($loginUserIsDirUser)) {
  1381.             $password = md5($username).md5($cookieMarker);
  1382.         }
  1383.         else {
  1384.             if (!$already_md5) {
  1385.                 $password = md5( md5($password) ); // Double hash the password in the cookie.
  1386.             }
  1387.         }
  1388.  
  1389.         /**
  1390.          * Updated WP remember me option for directory users to only be
  1391.          * remembered for 1 hour so that institutional passwords are not
  1392.          * overly endangered when accessing the blog from a public terminal.
  1393.          */
  1394.         if ( $remember ){
  1395.             $duration = ($loginUserIsDirUser) ? strtotime('1 hour') : strtotime('6 months');
  1396.             $expire = time() + $duration;
  1397.         }
  1398.         else {
  1399.             $expire = 0;
  1400.         }
  1401.  
  1402.         /**
  1403.          * The rest of the logic is from the original WP wp_setcookie
  1404.          * function, from /wp-inlcudes/pluggable.php version 2.2.2
  1405.          */
  1406.         if ( empty($home) )
  1407.             $cookiepath = COOKIEPATH;
  1408.         else
  1409.             $cookiepath = preg_replace('|https?://[^/]+|i', '', $home . '/' );
  1410.  
  1411.         if ( empty($siteurl) ) {
  1412.             $sitecookiepath = SITECOOKIEPATH;
  1413.             $cookiehash = COOKIEHASH;
  1414.         } else {
  1415.             $sitecookiepath = preg_replace('|https?://[^/]+|i', '', $siteurl . '/' );
  1416.             $cookiehash = md5($siteurl);
  1417.         }
  1418.  
  1419.         setcookie(USER_COOKIE, $username, $expire, $cookiepath, COOKIE_DOMAIN);
  1420.         setcookie(PASS_COOKIE, $password, $expire, $cookiepath, COOKIE_DOMAIN);
  1421.  
  1422.         if ( $cookiepath != $sitecookiepath ) {
  1423.             setcookie(USER_COOKIE, $username, $expire, $sitecookiepath, COOKIE_DOMAIN);
  1424.             setcookie(PASS_COOKIE, $password, $expire, $sitecookiepath, COOKIE_DOMAIN);
  1425.         }
  1426.  
  1427.     }
  1428.  
  1429.     /**
  1430.      * Prints data on a variable into a comments block in the source code of a page. Used for debugging purposes only.
  1431.      *
  1432.      * @param mixed $mxdVar
  1433.      * @param string $strMsg
  1434.      */
  1435.     function wpDirAuthPrintDebug($mxdVar,$strMsg){
  1436.         echo PHP_EOL,'<!-- ',$strMsg,': ',PHP_EOL,var_export($mxdVar,true),PHP_EOL,'-->',PHP_EOL;
  1437.     }
  1438.  
  1439.     /**
  1440.      * Removes the "you're using a default password"" nag for dirauth accounts
  1441.      *
  1442.      * @param integer $userID
  1443.      * @return void
  1444.      */
  1445.     function wpDirAuth_remove_password_nag($userID){
  1446.         if(get_user_option('default_password_nag',$userID)){
  1447.             update_user_option($userID, 'default_password_nag', false, true);
  1448.         }
  1449.     }
  1450.  
  1451.     /**
  1452.      * Retrieves values given in WPDIRAUTH_LDAP_RETURN_KEYS from a valid, bound LDAP connection
  1453.      *
  1454.      * @param resource $rscConnection verified LDAP connection resource
  1455.      * @param string $strBaseDn
  1456.      * @param string $strFilterQuery
  1457.      * @param mixed $rscReult if LDAP search was already performed. default null
  1458.      * @return mixed WP_Error object if there was an error encountered, otherwise an array of user details
  1459.      *
  1460.      * @TODO right now it's actually coded such that what is returned is always the same, even if you change the keys in WPDIRAUTH_LDAP_RETURN_KEYS. Rewrite it so
  1461.      * it will dynamically retrieve the values. idea is that WPDIRAUTH_LDAP_RETURN_KEYS would become an associative array of key names to return => LDAP keys to retrieve.
  1462.      * WPDIRAUTH_LDAP_RETURN_KEYS = serialize(array(
  1463.      *       'first_name'    =>'givenname',
  1464.      *       'last_name'     =>'sn',
  1465.      *       'email'         =>'mail'
  1466.      * ));
  1467.      * of course, we'll need to somehow require at least the email key since we need that one in order to add the user.
  1468.      */
  1469.     function wpDirAuth_retrieveUserDetails($rscConnection,$strBaseDn,$strFilterQuery,$rscResult=NULL){
  1470.         //now that we have a valid connection and are bound, we need to find the user.
  1471.  
  1472.         if(is_null($rscResult)){
  1473.             $rscResult = ldap_search($rscConnection,$strBaseDn,$strFilterQuery,unserialize(WPDIRAUTH_LDAP_RETURN_KEYS));
  1474.         }
  1475.  
  1476.         /**
  1477.          * At this point, we will no longer use $strFilterQuery EXCEPT in the output of an error message.  To ensure we dont introduce an injection point, we will encode any
  1478.          * html entities that might be present.
  1479.          */
  1480.         $strFilterQuery = htmlentities($strFilterQuery,ENT_QUOTES,'UTF-8');
  1481.  
  1482.         if(!$rscResult){
  1483.             return new WP_Error ('noprofile_search', __('Directory authentication initially succeeded, but no valid profile was found (search procedure).')
  1484.                 ." [$strFilter]");
  1485.         } else {
  1486.             $aryUserDetails = @ldap_get_entries($rscConnection, $rscResult);
  1487.  
  1488.             $intCount = intval($aryUserDetails['count']);
  1489.             if ($intCount < 1) {
  1490.                 return new WP_Error ('noprofile_getentries', __('Directory authentication initially succeeded, but no valid profile was found ("get entries" procedure).')
  1491.                     ." [$strFilterQuery]");
  1492.             } elseif ($intCount > 1) {
  1493.                 return new WP_Error ('not_unique', __('Directory authentication initially succeeded, but the username you sent is not a unique profile identifier.')
  1494.                     . " [$strFilterQuery]");
  1495.             } else {
  1496.                 $strEmail       = isset($aryUserDetails[0]['mail'][0]) ? $aryUserDetails[0]['mail'][0] : '';
  1497.  
  1498.                 $strLastName    = isset($aryUserDetails[0]['sn'][0]) ? $aryUserDetails[0]['sn'][0] : '';
  1499.  
  1500.                 $strFirstName   = isset($aryUserDetails[0]['givenname'][0]) ? $aryUserDetails[0]['givenname'][0] : '';
  1501.  
  1502.                 return array(
  1503.                     'email'      => $strEmail,
  1504.                     'last_name'  => $strLastName,
  1505.                     'first_name' => $strFirstName
  1506.                 );
  1507.             }
  1508.         }
  1509.     }
  1510.  
  1511.     /**
  1512.      * Handles connecting to LDAP and performing a search for the given SSOID
  1513.      *
  1514.      * @param string $strSSOID
  1515.      * @return mixed WP_Error object on failure, array of user details on success
  1516.      * @TODO this function shares a LOT with wpDirAuth_auth. see if you cant combine them some more
  1517.      */
  1518.     function wpDirAuth_ConnectAndLookupUser($strSSOID){
  1519.         $boolFound = false;
  1520.  
  1521.         $strBaseDn           = get_site_option('dirAuthBaseDn');
  1522.         $strPreBindUser      = get_site_option('dirAuthPreBindUser','');
  1523.         $strPreBindPassword  = get_site_option('dirAuthPreBindPassword','');
  1524.         $strAccountSuffix    = get_site_option('dirAuthAccountSuffix');
  1525.         $strFilter           = get_site_option('dirAuthFilter');
  1526.         $intEnableSSL        = get_site_option('dirAuthEnableSsl');
  1527.  
  1528.         if ($strAccountSuffix) $strSSOID .= $strAccountSuffix;
  1529.  
  1530.         if (!$strFilter || empty($strFilter)) $strFilter = WPDIRAUTH_DEFAULT_FILTER;
  1531.  
  1532.         $strFilterQuery = "($strFilter=$strSSOID)";
  1533.  
  1534.         $aryControllers = wpDirAuth_shuffleControllers(explode(',', get_site_option('dirAuthControllers')));
  1535.  
  1536.         if(is_wp_error($aryControllers)){
  1537.             return $aryControllers; //there werent any controllers to connect to
  1538.         }
  1539.  
  1540.         /**
  1541.          * @todo if we get a successful connection, cant we break out of the loop before we go through binding and a search?  Or is it possible that one DC in the
  1542.          * list might not allow anonymous searching and/or the pre-bind user/pass isnt valid on one of them and we need to try the next in the list?
  1543.          */
  1544.         foreach($aryControllers as $strDC){
  1545.             $rscConnection = wpDirAuth_establishConnection($strDC,$intEnableSSL);
  1546.             if(is_wp_error($rscConnection)){
  1547.                 return $rscConnection;  //tls failed to start on the DC
  1548.             }
  1549.  
  1550.             if(!wpDirAuth_bindTest($rscConnection,$strPreBindUser,$strPreBindPassword,$strBaseDn)){
  1551.                 return new WP_Error('login_failed',__('<strong>Error Connecting to LDAP Server</strong><p>'
  1552.                     . 'There was an error connecting to your LDAP server ('.  htmlentities($strDC,ENT_QUOTES,'UTF-8').'). Please see the LDAP error message below for troubleshooting:</p>'
  1553.                     . ldap_error($rscConnection)));
  1554.             }
  1555.  
  1556.             //successfully bound, now we need to get the user details
  1557.             return wpDirAuth_retrieveUserDetails($rscConnection,$strBaseDn,$strFilterQuery);
  1558.         }
  1559.     }
  1560.  
  1561.     /**
  1562.      * Checks to make sure the user doesnt already exist and that the email associated with a SSOID isnt already in use in the blog, and if not, adds the user.
  1563.      *
  1564.      * @param string $strSSOID Single Sign On ID
  1565.      * @param string $strRole Role chosen to give the new user
  1566.      * @return mixed array of user details on success or WP_Error object on failure
  1567.      */
  1568.     function wpDirAuth_add_new_user($strSSOID,$strRole,$intBlogID = 0){
  1569.         /**
  1570.          * We need to see if the user name already exists.  if not, then we need to see if the email address is already in use, if not, then we need to try and look
  1571.          * up the user.  then if we actually found something, then we'll add them into wordpress
  1572.          */
  1573.         $strSSOID = sanitize_user($strSSOID);
  1574.         $intBlogID = is_int($intBlogID) ? $intBlogID : (int) $intBlogID;   //just to make sure
  1575.  
  1576.         if(username_exists($strSSOID)){
  1577.             echo '<p>user already exists</p>';
  1578.             return new WP_Error('username_exists',__('<p>Could not create a new Wordpress account because the directory username <strong>'
  1579.                 . htmlentities($strSSOID,ENT_QUOTES,'UTF-8') . '</strong> is already registered on this site.</p>'));
  1580.         }
  1581.  
  1582.         //we'll have to go ahead and look them up in LDAP in order to check their email address
  1583.         $aryUserDetails = wpDirAuth_ConnectAndLookupUser($strSSOID);
  1584.         if(is_wp_error($aryUserDetails)){
  1585.             return $aryUserDetails;
  1586.         }
  1587.         $strUserEmail = apply_filters('user_registration_email', $aryUserDetails['email']);
  1588.  
  1589.         if(email_exists($strUserEmail)){
  1590.             echo '<p>Email address already exists</p>';
  1591.             return new WP_Error('email_exists',__('Could not create a new WP account because the email <strong>'
  1592.                 . htmlentities($strUserEmail,ENT_QUOTES,'UTF-8') . '</strong> is already registered with this site.'));
  1593.         }
  1594.  
  1595.         $aryUserDetails['user_pass'] = mt_rand();//we're going to store a random password in WP since directory users will never use it to log in anyway'
  1596.         $aryUserDetails['user_login'] = $strSSOID;
  1597.         $aryUserDetails['user_email'] = $aryUserDetails['email'] = $strUserEmail;
  1598.         /**
  1599.          * @TODO ask Stephen why he's replacing .'s with _'s in the user name of the email address. Does nickname not allow spaces?
  1600.          */
  1601.         $tmpAr = split('@',$aryUserDetails['email']);
  1602.         $aryUserDetails['nickname'] =  str_replace('.','_',$tmpAr[0]);
  1603.         $aryUserDetails['display_name'] = $aryUserDetails['first_name'].' '.$aryUserDetails['last_name'];
  1604.         $aryUserDetails['role'] = $strRole;
  1605.  
  1606.         /**
  1607.          * Switch to the blog we want to insert the user into
  1608.          */
  1609.         if(defined('MULTISITE') && MULTISITE && function_exists('switch_to_blog')) switch_to_blog($intBlogID);
  1610.         $intUserID = wp_insert_user($aryUserDetails);
  1611.  
  1612.         if(!is_int($intUserID)){
  1613.             return new WP_Error('createuser_failed',__('For an unknow reason, WP failed to create a new user.'
  1614.                 .' Failure occurred at line ' . __LINE__ . ' in the function ' . __FUNCTION__ . ' in the file ' . basename(__FILE__) . '.'));
  1615.         }
  1616.  
  1617.         $aryUserDetails['ID'] = $intUserID;
  1618.         update_usermeta($intUserID, 'wpDirAuthFlag', 1);
  1619.         wpDirAuth_remove_password_nag($intUserID);
  1620.  
  1621.         //for situations where an admin is adding a user from a site edit screen
  1622.         /**
  1623.         if($intBlogID != 0){
  1624.         add_user_to_blog($intBlogID,$intUserID,$strRole);
  1625.         }  */
  1626.  
  1627.         if(defined('MULTISITE') && MULTISITE && function_exists('switch_to_blog')) restore_current_blog();
  1628.         return $aryUserDetails;
  1629.     }
  1630.  
  1631.     /**
  1632.      * Loops through the WP_Error object and prints out the error messages it contains
  1633.      *
  1634.      * @param object $objError
  1635.      * @return void
  1636.      */
  1637.     function wpDirAuth_print_error_messages($objError){
  1638.         echo PHP_EOL,'<div class="error">',WPDIRAUTH_ERROR_TITLE,'<ul>',PHP_EOL;
  1639.         foreach($objError->get_error_messages() as $strErrMsg){
  1640.             echo '<li>',$strErrMsg,'</li>',PHP_EOL;
  1641.         }
  1642.         echo '</ul></div>',PHP_EOL;
  1643.     }
  1644.  
  1645.     /**
  1646.      * Constructs the message to be displayed when a new user has been added successfully
  1647.      *
  1648.      * @param string $strSSOID User's Single Sign On ID
  1649.      * @param integer $strUserID user's wordpress user ID
  1650.      * @param array Data on the sites and roles that the user has been added to
  1651.      * @return string
  1652.      * @uses wpDirAuth_determine_A_or_An
  1653.      *
  1654.      */
  1655.     function wpDirAuth_construct_success_msg($strSSOID,$strUserID,$arySitesData,$strExtraMsg=''){
  1656.         //$arySitesData = array('blogname','role','siteurl');
  1657.         $strMsg = '<div id="message" class="updated">
  1658.            <p>Just created user <strong><a href="user-edit.php?user_id=%d">%s</a></strong> as %s. %s
  1659.            </div>';
  1660.  
  1661.         $strSiteMessage = '%s for site <a href="%s">%s</a>';
  1662.         $arySiteMsgParts = array();
  1663.         foreach($arySitesData as $arySiteData){
  1664.             $arySiteMsgParts[] = sprintf($strSiteMessage,$arySiteData['role'],$arySiteData['siteurl'],$arySiteData['blogname']);
  1665.         }
  1666.  
  1667.         return sprintf($strMsg,$strUserID,$strSSOID,implode($arySiteMsgParts,', '),$strExtraMsg);
  1668.     }
  1669.  
  1670.     /**
  1671.      * Just determines if the word $strWord should be prefaced with 'a' or 'an'.
  1672.      * Yea, i know it's picky, but I work with editors who complain about this type of stuff all the time  =P
  1673.      *
  1674.      * @param string $strWord
  1675.      * @return string
  1676.      */
  1677.     function wpDirAuth_determine_A_or_An($strWord){
  1678.         $strAorAn = 'a';
  1679.         if(in_array(substr($strWord,0,1),array('a','e','i','o','u'))){
  1680.             $strAorAn .= 'n';
  1681.         }
  1682.  
  1683.         return $strAorAn;
  1684.     }
  1685.  
  1686.     /**
  1687.      * Adds contextual help to the Add Dir Auth page under the Users menu
  1688.      *
  1689.      */
  1690.     function wpDirAuth_add_user_contextual_help(){
  1691.         $strMarketingSSOID = get_site_option('dirAuthMarketingSSOID','Username');
  1692.         add_contextual_help('users_page_'.basename(__FILE__,'.php'),
  1693.             '<p>' . __('To add a directory authenticated user from your institution to your site, fill in the form on this screen. If you&#8217;re not sure which role to assign, you can use the link below to review the different roles and their capabilities. Here is a basic overview of roles:') . '</p>' .
  1694.             '<ul>' .
  1695.             '<li>' . __('Administrators have access to all the administration features.') . '</li>' .
  1696.             '<li>' . __('Editors can publish posts, manage posts as well as manage other people&#8217;s posts, etc.')  . '</li>' .
  1697.             '<li>' . __('Authors can publish and manage their own posts.') . '</li>' .
  1698.             '<li>' . __('Contributors can write and manage their posts but not publish posts or upload media files.') . '</li>' .
  1699.             '<li>' . __('Subscribers can read comments/comment/receive newsletters, etc.') . '</li>' .
  1700.             '</ul>' .
  1701.             '<p>' . __('The user\'s insitutional single-sign-on ID (e.g. ' . $strMarketingSSOID .') will become the user\'s Wordpress username.') . '</p>' .
  1702.             '<p>' . __('New users will receive an email letting them know they&#8217;ve been added as a user for your site.') . '</p>' .
  1703.             '<p>' . __('Remember to click the Add User button at the bottom of this screen when you are finished.') . '</p>' .
  1704.             '<p><strong>' . __('For more information:') . '</strong></p>' .
  1705.             '<p>' . __('<a href="http://wordpress.org/support/" target="_blank">Support Forums</a>') . '</p>'
  1706.         );
  1707.     }
  1708.  
  1709.     /**
  1710.      * Processes and outputs the Add Dir Auth user form.
  1711.      * @return void
  1712.      */
  1713.     function wpDirAuth_add_user_panel(){
  1714.         _log('WPDIRAUTH - function ' . __FUNCTION__ . ' activated. ');
  1715.         /**
  1716.          * Still needed?
  1717.          */
  1718.         global $id;
  1719.         /**
  1720.          * get_current_screen()->id = site-users-network will let us know if we are on the sites,edit,user tab
  1721.          */
  1722.         $strScreenID = get_current_screen()->id;
  1723.         /**
  1724.          * Are we running in a wordpress network and in the network area?
  1725.          */
  1726.         $boolIsNetworkAdminScreen = (is_network_admin() && $strScreenID != 'site-users-network') ? true : false;
  1727.         /**
  1728.          * How do we refer to their SSOID?
  1729.          */
  1730.         $strMarketingSSOID = get_site_option('dirAuthMarketingSSOID','Username');
  1731.  
  1732.         $strReferer = wpDirAuth_get_referer();
  1733.  
  1734.         /**
  1735.          * defaults
  1736.          */
  1737.         $strWpDirAuthSSOID = '';
  1738.         $strWpDirAuthRole = '';
  1739.         $boolConfirmationEmail = true;
  1740.         $objErrors = new WP_Error;
  1741.         $strSuccess = '';
  1742.         if($boolIsNetworkAdminScreen){
  1743.             $arySitesData = wpDirAuth_retrieve_multisite_blog_data();
  1744.         }
  1745.  
  1746.         if($_POST){
  1747.             if(wp_verify_nonce($_POST['_wpnonce_add-da-user'],'add-da-user')){
  1748.                 /**
  1749.                  * We gots a problem....  if they've checked all the boxes and chosen roles but forgot to enter the pawprint (it happens, you did
  1750.                  * it yourself!) then we cant rebuild the list of which sites were checked/not checked later because we're jumping out before
  1751.                  * we get to the point where we build that data.
  1752.                  */
  1753.                 if(isset($_POST['ssoid']) && $_POST['ssoid'] == ''){
  1754.                     $objErrors->add('blank_ssoid',__('<p>'.$strMarketingSSOID.' can not be left blank.</p>'));
  1755.                 } else {
  1756.                     $strWpDirAuthSSOID = wpDirAuth_sanitize($_POST['ssoid']);
  1757.  
  1758.                     if($boolIsNetworkAdminScreen && $strReferer != 'site-users.php'){
  1759.                         $arySitesAndRoles = array();
  1760.                         $aryValidSiteIDs = array_keys($arySitesData);
  1761.                         $aryValidRoles = array_keys(get_editable_roles());
  1762.                         _log('contents of the post in function ' . __FUNCTION__.' at line ' . __LINE__ . ':'.PHP_EOL.var_export($_POST,true));
  1763.                         //we SHOULD have at least one site set.
  1764.                         for($i=0;$i<count($arySitesData);++$i){
  1765.                             $strPostSite = 'site'.$i;
  1766.                             $intCountPostSite = count($_POST[$strPostSite]);
  1767.                             /**
  1768.                              * We need to make sure that the site param is set, that it's an array and that it contains at least one element, but no more than
  1769.                              * two
  1770.                              */
  1771.                             if(isset($_POST[$strPostSite]) && is_array($_POST[$strPostSite]) && $intCountPostSite>0 && $intCountPostSite<3){
  1772.                                 if($intCountPostSite == 1 && is_string(current($_POST[$strPostSite]))){
  1773.                                     /**
  1774.                                      *  If the array has only one element, then this site wasnt selected as one we want to add the user to.  but we
  1775.                                      *  need, for simplicity sake, to make the array contain two elements before we do input validation
  1776.                                      */
  1777.                                     $_POST[$strPostSite] = array('',current($_POST[$strPostSite]));
  1778.                                     /**
  1779.                                      * Since we know that the array has two elements, we'll test to make sure the siteid is valid'
  1780.                                      */
  1781.                                 } elseif(!is_numeric($_POST[$strPostSite][0]) || !in_array($_POST[$strPostSite][0],$aryValidSiteIDs)) {
  1782.                                     $_POST[$strPostSite][0] = '';
  1783.                                 }
  1784.  
  1785.                                 /**
  1786.                                  *
  1787.                                  */
  1788.                                 if(!in_array($_POST[$strPostSite][1],$aryValidRoles)){
  1789.                                     $_POST[$strPostSite][1] = '';
  1790.                                 }
  1791.  
  1792.                                 /**
  1793.                                  * If we now have non-empty values for both elements, we'll add them to our array to be used for inserting the user into sites
  1794.                                  */
  1795.                                 if($_POST[$strPostSite][0] != '' && $_POST[$strPostSite][1] != ''){
  1796.                                     $arySitesAndRoles[$i] = array('blog_id'=>$_POST[$strPostSite][0],'role'=>$_POST[$strPostSite][1]);
  1797.                                 }
  1798.  
  1799.                             }
  1800.                         }
  1801.  
  1802.                     }
  1803.  
  1804.                     $strWpDirAuthRole = (isset($_POST['role']) && in_array($_POST['role'],array_keys(get_editable_roles()))) ? $_POST['role'] : get_site_option('default_role');
  1805.                     $intBlogID = (isset($_POST['id']) && is_numeric($_POST['id'])) ? intval($_POST['id']) : '';
  1806.                     if(isset($_POST['noconfirmation']) && $_POST['noconfirmation'] == 1) $boolConfirmationEmail = false;
  1807.  
  1808.                     if(!isset($arySitesAndRoles) || !$boolIsNetworkAdminScreen){
  1809.                         $aryUserData = wpDirAuth_add_new_user($strWpDirAuthSSOID,$strWpDirAuthRole,$intBlogID);
  1810.                         _log('adding a standard user (' . $strWpDirAuthSSOID .')from either inside a site, or from the edit section of a site');
  1811.                         _log('user data from newly added user is : ' . PHP_EOL . var_export($aryUserData,true) . PHP_EOL);
  1812.                     } elseif(count($arySitesAndRoles)<1) {
  1813.                         $aryUserData = new WP_Error('no_site_role_selected','<p>You will need to select at least one site to add this user to.</p>');
  1814.                     } else {
  1815.                         $aryUserData = wpDirAuth_add_new_user_to_multi_sites($strWpDirAuthSSOID,$arySitesAndRoles);
  1816.                         _log('adding a user (' . $strWpDirAuthSSOID .')from the network Add Dir Auth user section');
  1817.                     }
  1818.  
  1819.                     if(is_wp_error($aryUserData)){
  1820.                         //foreach($objErrors->)
  1821.  
  1822.                         //$mxdErrors = $aryUserData;
  1823.                         $objErrors->add($aryUserData->get_error_code(),$aryUserData->get_error_message(),$aryUserData->get_error_data());
  1824.                     } else {
  1825.                         $arySitesAddedTo = array();
  1826.                         if(isset($arySitesAndRoles) && count($arySitesAndRoles)!=0){
  1827.                             foreach($arySitesAndRoles as $arySiteData){
  1828.                                 $arySitesAddedTo[] = array(
  1829.                                     'blogname'=>$arySitesData[$arySiteData['blog_id']],
  1830.                                     'aoran'   =>wpDirAuth_determine_A_or_An($arySiteData['role']),
  1831.                                     'role'    =>$arySiteData['role'],
  1832.                                     'siteurl' =>get_site_url($arySiteData['blog_id'],'','https')
  1833.  
  1834.                                 );
  1835.                             }
  1836.                         } else {
  1837.                             $arySitesAddedTo[] = array(
  1838.                                 'blogname'  =>get_site_option('blogname'),
  1839.                                 'aoran'     =>wpDirAuth_determine_A_or_An($strWpDirAuthRole),
  1840.                                 'role'      =>$strWpDirAuthRole,
  1841.                                 'siteurl'   =>site_url()
  1842.                             );
  1843.                         }
  1844.  
  1845.                         /**
  1846.                          * ok, the admin has just successfully added a user to a site from the sites->edit->users tab.  Since we cant seem to
  1847.                          * redirect them back to the screen automatically, let's give them a link to go back.'
  1848.                          */
  1849.                         if($strReferer == 'site-users.php' && $boolIsNetworkAdminScreen){
  1850.                             $strReturnToURL = wp_get_referer();
  1851.                             $strExtraMessage = '<a href="'.$strReturnToURL.'">Return to the User tab</a> of the '. $arySitesData[$intBlogID] . ' site.';
  1852.                         } else {
  1853.                             $strExtraMessage = '';
  1854.                         }
  1855.  
  1856.                         $strSuccess = wpDirAuth_construct_success_msg($strWpDirAuthSSOID,$aryUserData['ID'],$arySitesAddedTo,$strExtraMessage);
  1857.                         _log('for user ' . $strWpDirAuthSSOID . ', added them to ' . var_export($arySitesAddedTo,true).'.');
  1858.  
  1859.                         if($boolConfirmationEmail){
  1860.                             foreach($arySitesAddedTo as $arySiteAddedToData){
  1861.                                 $strMsg = sprintf(WPDIRAUTH_EMAIL_NEWUSER_NOTIFY,$arySiteAddedToData['blogname'],$arySiteAddedToData['aoran'],$arySiteAddedToData['role'],$strMarketingSSOID,$strWpDirAuthSSOID,$arySiteAddedToData['siteurl'].'/wp-login.php');
  1862.                                 wp_mail($aryUserData['email'],'['.$arySiteAddedToData['blogname'].'] You\'ve been added!',$strMsg);
  1863.                             }
  1864.                         }
  1865.  
  1866.                         //reset back to defaults
  1867.                         $strWpDirAuthSSOID = '';
  1868.                         $strWpDirAuthRole = '';
  1869.                         $boolConfirmationEmail = true;
  1870.                     }
  1871.                 }
  1872.             } else {
  1873.                 $objErrors->add('invalid-nonce',__('Invalid nonce value'));
  1874.             }
  1875.         }
  1876.  
  1877.  
  1878.  
  1879.  
  1880.         ?>
  1881.         <h3>Add New Directory Authentication User</h3>
  1882.         <?php
  1883.         if(count($objErrors->errors) != 0) {
  1884.             wpDirAuth_print_error_messages($objErrors);
  1885.         } elseif($strSuccess != ''){
  1886.             echo $strSuccess;
  1887.         }
  1888.         ?>      <p><?php _e('Add a directory authenticated user to this site/network'); ?></p>
  1889.         <p><?php _e('Please note: Your LDAP/AD instance must allow anonymous profile searches, or you must provide a pre-bind account/password in the <a href="options-general.php?page='.basename(__FILE__).'">Directory Auth settings page.</a>') ?></p>
  1890.  
  1891.         <form action="<?php if(isset($strScreenID) && $strScreenID == 'site-users-network') echo 'users.php?page=wpDirAuth'; ?>" method="post" name="adddauser" id="createuser" class="add:users: validate"<?php do_action('user_new_form_tag');?>>
  1892.             <?php
  1893.             if(isset($id) && $id != '' && is_multisite()){
  1894.                 echo '<input type="hidden" name="id" value="',$id,'" />',PHP_EOL;
  1895.             }
  1896.             ?>
  1897.             <input name="action" type="hidden" value="add-da-user" />
  1898.             <?php wp_nonce_field( 'add-da-user', '_wpnonce_add-da-user' ); ?>
  1899.             <table class="form-table">
  1900.                 <tr class="form-field form-required">
  1901.                     <th scope="row">
  1902.                         <label for="ssoid"><?php _e($strMarketingSSOID.'/SSOID'); ?> <span class="description"><?php _e('(required)'); ?></span></label>
  1903.                     </th>
  1904.                     <td>
  1905.                         <input name="ssoid" type="text" id="ssoid" value="<?php echo esc_attr($strWpDirAuthSSOID); ?>" aria-required="true" />
  1906.                     </td>
  1907.                 </tr>
  1908.                 <?php if($boolIsNetworkAdminScreen):?>
  1909.                     <tr class="form-field">
  1910.                         <th scope="row"><label for="blogs"><?php _e('Site');?></label></th>
  1911.                         <th><label for="role"><?php _e('Role');?></label></th>
  1912.                     </tr>
  1913.                     <?php
  1914.  
  1915.                     $i=0;
  1916.  
  1917.                     foreach($arySitesData as $intSiteID=>$strSiteName){
  1918.                         $boolChecked = false;
  1919.  
  1920.                         if(isset($arySitesAndRoles[$i])){
  1921.                             $aryFormSiteData = $arySitesAndRoles[$i];
  1922.                         } elseif(isset($_POST['site'.$i])) {
  1923.                             $aryFormSiteData = $_POST['site'.$i];
  1924.                         } else {
  1925.                             $aryFormSiteData = array();
  1926.                         }
  1927.  
  1928.                         _log('aryFormSiteData at line ' . __LINE__ . ': ' . var_export($aryFormSiteData,true));
  1929.  
  1930.                         /**
  1931.                          * We are working on the assumption that there are either ALWAYS two elements in aryformSiteData or the array is empty.
  1932.                          * If the first element in the array isnt empty, then the current site needs to be checked
  1933.                          */
  1934.                         if(reset($aryFormSiteData) != ''){
  1935.                             $boolChecked = true;
  1936.                         }
  1937.  
  1938.                         /**
  1939.                          * If the last element (eg second, role) isnt empty, then we want to select it from the list
  1940.                          */
  1941.                         $strRoleSelected = (end($aryFormSiteData) != '') ? current($aryFormSiteData) : '';
  1942.  
  1943.                         echo '<tr>
  1944.                            <td>
  1945.                                <input name="site'.$i.'[]" value="'.$intSiteID.'" id="blog_'.$intSiteID.'" type="checkbox"';
  1946.  
  1947.                         if($boolChecked) echo ' checked="checked"';
  1948.  
  1949.                         echo ' />&nbsp;&nbsp;'.$strSiteName.'
  1950.                            </td>
  1951.                            <td>
  1952.                                <select name="site'.$i.'[]" id="role_'.$intSiteID.'">';
  1953.                         wp_dropdown_roles($strRoleSelected);
  1954.                         echo PHP_EOL,'</select>
  1955.                        </td>
  1956.                    </tr>';
  1957.                         ++$i;
  1958.                     }
  1959.  
  1960.                     ?>
  1961.                 <?php else: ?>
  1962.                     <tr class="form-field">
  1963.                         <th scope="row"><label for="role"><?php _e('Role'); ?></label></th>
  1964.                         <td><select name="role" id="role">
  1965.                                 <?php
  1966.                                 $strCurrentRole = empty($strWpDirAuthRole) ? get_site_option('default_role') : $strWpDirAuthRole;
  1967.                                 wp_dropdown_roles($strCurrentRole);
  1968.                                 ?>
  1969.                             </select>
  1970.                         </td>
  1971.                     </tr>
  1972.                 <?php endif;?>
  1973.                 <tr>
  1974.                     <th scope="row"><label for="noconfirmation"><?php _e('Skip Confirmation Email') ?></label></th>
  1975.                     <td><label for="noconfirmation"><input type="checkbox" name="noconfirmation" id="noconfirmation" value="1"  <?php checked(!$boolConfirmationEmail); ?> /> <?php _e( 'Add the user without sending them a confirmation email.' ); ?></label></td>
  1976.                 </tr>
  1977.             </table>
  1978.  
  1979.             <?php submit_button( __( 'Add New User '), 'primary', 'createuser', true, array( 'id' => 'createusersub' ) ); ?>
  1980.  
  1981.         </form>
  1982.  
  1983.     <?php
  1984.     } // end  wpDirAuth_add_user_panel() function
  1985.  
  1986.     /**
  1987.      * Add custom WordPress actions
  1988.      *
  1989.      * @uses wpDirAuth_addMenu
  1990.      * @uses wpDirAuth_loginFormExtra
  1991.      * @uses wpDirAuth_profileUpdate
  1992.      * @uses wpDirAuth_add_user_contextual_help
  1993.      */
  1994.     if (function_exists('add_action')) {
  1995.         /**
  1996.          *ok, if we are in a multisite, we want to add the settings for wpDirAuth
  1997.          * to the Network Admin area, but NOT the child sites. Otherwise, for
  1998.          * single sites, we need to add an admin panel
  1999.          *
  2000.          * Also for MUTLISITE, we need to add extra add user pages since we can
  2001.          * add users in multiple areas when we are running a MULTISITE
  2002.          */
  2003.         if(WPDIRAUTH_MULTISITE){
  2004.             add_action('network_admin_menu','wpDirAuth_addNetworkMenu');
  2005.             add_action('show_network_site_users_add_new_form', 'wpDirAuth_add_user_panel');
  2006.             //add_action('network_site_users_after_list_table', 'wpDirAuth_add_user_panel');
  2007.             add_action('network_admin_menu','wpDirAuth_network_adduser');
  2008.         } else {
  2009.             add_action('admin_menu',     'wpDirAuth_addMenu');
  2010.         }
  2011.  
  2012.         /**
  2013.          * EVERYSITE, regardless of multi or not, needs the ability to add users
  2014.          */
  2015.         add_action('admin_menu','wpDirAuth_add_users_page');
  2016.  
  2017.         add_action('login_form',     'wpDirAuth_loginFormExtra');
  2018.         add_action('profile_update', 'wpDirAuth_profileUpdate');
  2019.  
  2020.         add_action('admin_head-users_page_'.basename(__FILE__,'.php'),'wpDirAuth_add_user_contextual_help');
  2021.     }
  2022.  
  2023.  
  2024.     /**
  2025.      * Add custom WordPress filters
  2026.      *
  2027.      * @uses wpDirAuth_hidePassFields
  2028.      */
  2029.     if (function_exists('add_filter')) {
  2030.         add_filter('show_password_fields', 'wpDirAuth_hidePassFields');
  2031.     }
  2032.  
  2033.     function wpDirAuth_add_users_page(){
  2034.         if(function_exists('add_users_page')){
  2035.             add_users_page(
  2036.                 'Add Directory Authentication Users',
  2037.                 'Add Directory Authenticated User',
  2038.                 'administrator',
  2039.                 basename(__FILE__),
  2040.                 'wpDirAuth_add_user_panel'
  2041.             );
  2042.         }
  2043.     }
  2044.  
  2045.     /**
  2046.      * TESTING
  2047.      */
  2048.     function wpDirAuth_network_adduser(){
  2049.         add_submenu_page('users.php','Add Directory Authenticated User','Add Dir Auth User','add_users','wpDirAuth','wpDirAuth_add_user_panel');
  2050.     }
  2051.  
  2052.     function wpDirAuth_addNetworkMenu(){
  2053.         add_submenu_page('settings.php','wpDirAuth Directory Authentication Options','wpDirAuth','manage_options','wpDirAuth_optionsPanel','wpDirAuth_optionsPanel');
  2054.     }
  2055.  
  2056.     function wpDirAuth_retrieve_multisite_blog_data(){
  2057.         global $wpdb;
  2058.         $aryBlogData = array();
  2059.         $arySites = $wpdb->get_results($wpdb->prepare('SELECT blog_id FROM '. $wpdb->prefix . 'blogs ORDER BY blog_id'));
  2060.         _log('result of arySites: '.PHP_EOL.var_export($arySites,true).PHP_EOL);
  2061.         foreach($arySites as $objSiteData){
  2062.             $intSiteKey = $objSiteData->blog_id;
  2063.             $strTableName = $wpdb->prefix;
  2064.             $strTableName .= ($intSiteKey != 1) ? $intSiteKey . '_' : '';
  2065.             $strTableName .= 'options';
  2066.             /**
  2067.              * Wonder if I should do wpdb->get_var here instead?
  2068.              */
  2069.             $arySiteData = $wpdb->get_results($wpdb->prepare("SELECT option_value from $strTableName WHERE option_name = 'blogname'"),ARRAY_A);
  2070.             $aryBlogData[$intSiteKey] = (isset($arySiteData[0]['option_value']) && $arySiteData[0]['option_value'] != '') ? $arySiteData[0]['option_value'] : 'Unable to Retrive Blog Name';
  2071.         }
  2072.         _log('aryBlogData:'.PHP_EOL.var_export($aryBlogData,true).PHP_EOL);
  2073.         return $aryBlogData;
  2074.     }
  2075.  
  2076.     /**
  2077.      * put your comment there...
  2078.      *
  2079.      * @param string $strSSOID
  2080.      * @param array $aryBlogIDsRoles should be a nested array with the sub-array containing the keys 'blog_id' and 'role'
  2081.      * @return mixed WP_Error or user details upon success.
  2082.      */
  2083.     function wpDirAuth_add_new_user_to_multi_sites($strSSOID,$aryBlogIDsRoles){
  2084.         $mxdFirstElement = reset($aryBlogIDsRoles);//reset back to the beginning
  2085.         if(count($aryBlogIDsRoles)<1 || !$mxdFirstElement){
  2086.             return new WP_Error('blog_id_role_missing',__('<p>Could not create a new Wordpress account because data on blog id and role is '
  2087.                 . 'missing.  Function: ' . __FUNCTION__.', line ' . __LINE__.'.</p>'));
  2088.         } else {
  2089.  
  2090.             $aryFirstSite = current($aryBlogIDsRoles);
  2091.             $aryUserData = wpDirAuth_add_new_user($strSSOID,$aryFirstSite['role'],$aryFirstSite['blog_id']);
  2092.             if(is_wp_error($aryUserData)){
  2093.                 return $aryUserData;
  2094.             } else {
  2095.                 //we already added for the first site
  2096.                 unset($aryBlogIDsRoles[key($aryBlogIDsRoles)]);
  2097.                 foreach($aryBlogIDsRoles as $arySiteDetails){
  2098.                     add_user_to_blog($arySiteDetails['blog_id'],$aryUserData['ID'],$arySiteDetails['role']);
  2099.                 }
  2100.             }
  2101.  
  2102.             return $aryUserData;
  2103.         }
  2104.     }
  2105.  
  2106.     function wpDirAuth_get_referer(){
  2107.         $strReferer = basename(wp_get_referer());
  2108.         if(strpos($strReferer,'?') !== FALSE){
  2109.             $aryRefererParts = explode('?',$strReferer);
  2110.             $strReferer = $aryRefererParts[0];
  2111.         }
  2112.  
  2113.         return $strReferer;
  2114.     }
  2115. }
  2116.  
  2117. register_activation_hook(__FILE__, 'wpDirAuth_activation');
  2118.  
  2119. function wpDirAuth_activation(){
  2120.     if(WPDIRAUTH_MULTISITE){
  2121.         /**
  2122.          * Prior to v1.7.5, wpDirAuth options were stored in wp_options when
  2123.          * network activated instead of wp_sitemeta.  To ensure that users dont
  2124.          * lose their settings when upgrading to 1.7.5 or newer, we'll check
  2125.          * to see if there are wpDirAuth options in wp_options when network
  2126.          * activating.  If so, we'll copy them over to wp_sitemeta and then
  2127.          * delete them from wp_options
  2128.          */
  2129.         $mxdWpDirAuthEnable = get_option('dirAuthEnable');
  2130.         if(is_integer($mxdWpDirAuthEnable) && $mxdWpDirAuthEnable !== FALSE){
  2131.             foreach(unserialize(WPDIRAUTH_OPTIONS) as $strOption){
  2132.                 update_site_option($strOption,  get_site_option($strOption));
  2133.                 delete_option($strOption);
  2134.             }
  2135.  
  2136.             $aryBlogsData = wpDirAuth_retrieve_multisite_blog_data();
  2137.             //we only care about the blog ID
  2138.             $aryBlogIDs = array_keys($aryBlogsData);
  2139.             foreach($aryBlogIDs as $intBlogID){
  2140.                 switch_to_blog($intBlogID);
  2141.                 global $wpdb;
  2142.                 $wpdb->query(
  2143.                     "DELETE from {$wpdb->options} WHERE option_name LIKE 'dirAuth%'"
  2144.                 );
  2145.                 /**
  2146.                  * Why restore after every switch? Because if you dont, wordpress can get all kinds of lost..
  2147.                  * @see http://wordpress.stackexchange.com/questions/89113/restore-current-blog-vs-switch-to-blog
  2148.                  */
  2149.                 restore_current_blog();
  2150.             }
  2151.  
  2152.         }
  2153.     }
  2154. }
  2155.  
  2156. if(!function_exists('_log')){
  2157.     /**
  2158.      * For logging debug messages into the debug log.
  2159.      *
  2160.      * @param mixed $message
  2161.      */
  2162.     function _log( $message, $boolBackTraced = false ) {
  2163.         _wpdirauth_log($message,null,$boolBackTraced);
  2164.     }
  2165. }
  2166.  
  2167. if(!function_exists('_wpdirauth_log')){
  2168.     /**
  2169.      * For logging debug messages into the debug log.
  2170.      *
  2171.      * @param mixed $mxdVariable variable we need to debug
  2172.      * @param $strPrependMessage message to include
  2173.      * @param boolean $boolBackTraced
  2174.      * @param array $aryDetails details for doing a mini backtrace instead of the full thing
  2175.      *
  2176.      */
  2177.     function _wpdirauth_log( $mxdVariable, $strPrependMessage = null, $boolBackTraced = false, $aryDetails = array() ) {
  2178.         $boolBackTrace = false;
  2179.         if( WP_DEBUG === true ){
  2180.             $strMessage = 'WPDIRAUTH: ';
  2181.  
  2182.             if(count($aryDetails) > 0){
  2183.                 if(isset($aryDetails['line'])){
  2184.                     $strMessage .= 'At line number ' . $aryDetails['line'] . ' ';
  2185.                 }
  2186.  
  2187.                 if(isset($aryDetails['func'])){
  2188.                     $strMessage .= 'inside of function ' . $aryDetails['func'] . ' ';
  2189.                 }
  2190.  
  2191.                 if(isset($aryDetails['file'])){
  2192.                     $strMessage .= 'in file ' . $aryDetails['file'] .' ';
  2193.                 }
  2194.  
  2195.                 $strMessage .= PHP_EOL;
  2196.             }
  2197.  
  2198.             if(!is_null($strPrependMessage)) $strMessage .= $strPrependMessage.' ';
  2199.  
  2200.             if( is_array( $mxdVariable ) || is_object( $mxdVariable ) ){
  2201.                 $strMessage .= PHP_EOL . var_export($mxdVariable,true);
  2202.             } else {
  2203.                 $strMessage .= $mxdVariable;
  2204.             }
  2205.  
  2206.             if($boolBackTrace && $boolBackTraced){
  2207.                 $aryBackTrace = debug_backtrace();
  2208.  
  2209.                 $strMessage .= PHP_EOL.'Contents of backtrace:'.PHP_EOL.var_export($aryBackTrace,true).PHP_EOL;
  2210.             }
  2211.  
  2212.             error_log($strMessage);
  2213.         }
  2214.     }
  2215. }
  2216.  
  2217. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement