Location: PHPKode > projects > Sierra-php PHP Application Framework > sierra/lib/auth/SRA_OsAuthenticator.php
<?php
// {{{ Header
/*
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | SIERRA : PHP Application Framework  http://code.google.com/p/sierra-php |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | Copyright 2005 Jason Read                                               |
 |                                                                         |
 | Licensed under the Apache License, Version 2.0 (the "License");         |
 | you may not use this file except in compliance with the License.        |
 | You may obtain a copy of the License at                                 |
 |                                                                         |
 |     http://www.apache.org/licenses/LICENSE-2.0                          |
 |                                                                         |
 | Unless required by applicable law or agreed to in writing, software     |
 | distributed under the License is distributed on an "AS IS" BASIS,       |
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.|
 | See the License for the specific language governing permissions and     |
 | limitations under the License.                                          |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 */
// }}}

// {{{ Imports
include_once('SRA_Authenticator.php');
// }}}

// {{{ Constants

// }}}

// {{{ SRA_OsAuthenticator
/**
 * Authenticates a user using expect (http://expect.nist.gov) and the linux "su" 
 * command. in order to use this authentication method, expect MUST be installed
 * (yum install expect expectk). Alternatively, if the PHP script requiring 
 * authentication is running from the command line, the user invoking that 
 * script will be assumed and no authentication will be required. when using 
 * sierra/bin/sra-console.php, an alternate user may be specified using the 
 * PASSWD_FILE or USERNAME/PASSWORD arguments
 * This SRA_Authenticator utilizes the following parameters:
 *   exclude  => (optional) space separated list of users that should not be 
 *               authenticated
 *   groups   => (optional) space separated list of group names one of which a 
 *               user must belong to in order to be authenticated
 *   profile  => (optional) user directory relative, or absolute path to a 
 *               properties file containing user attributes (key/value pairs) 
 *               each of these values will be set in the 
 *               SRA_Authenticator::attrs instance variable. this path may 
 *               contain the key ${user} which will be substituted with the 
 *               user name
 *   transpose =>(optional) identifies user names that should be transposed. 
 *               the format for this parameter is: [authenticator user]=[os user]
 *               multiple transpose usernames may be specified each separated 
 *               by a space. direct authentication for transposed users is 
 *               automatically disallowed
 * in addition to the authenticator 'user' key that is automatically set by 
 * SRA_Authenticator and the keys set through the 'profile' parameter above, 
 * this authenticator will also automatically set the following keys: 
 *   uid:      : the user's os uid
 *   gid:      : the user's primary group gid
 *   groups    : array of groups that the user is a member of
 *   home      : absolute path to the user's home directory
 *   transposed: if the username was transposed, this value will be the 
 *               transposed username ('user' will be the non-transposed user)
 * @author  Jason Read <hide@address.com>
 * @package sierra.auth
 */
class SRA_OsAuthenticator extends SRA_Authenticator {
  // {{{ Attributes
  // public attributes
  
  
  // private attributes
  
  
  // }}}
  
  // {{{ Operations
  // constructor(s)
  // {{{ SRA_OsAuthenticator
  /**
   * Constructor
   * @access  public
   */
  function SRA_OsAuthenticator($id, $accessLog, $cancelTpl, $entityType, $entityUserCol, $failureLog, $globalVar, $loginTpl, 
                         $logoutFwdUri, $logoutGetVar, $logoutPostVar, $logoutTpl, $matchAllAttrs, $matchOneAttrs, 
                         $matchFailTpl, $maxAttempts, $maxAttemptTpl, $maxAttemptIp, 
                         $maxAttemptTimeout, & $params, $resource, $sysErrTpl, 
                         $tplVar, $useSessions) {
    parent::SRA_Authenticator($id, $accessLog, $cancelTpl, $entityType, $entityUserCol, $failureLog, $globalVar, $loginTpl, 
                         $logoutFwdUri, $logoutGetVar, $logoutPostVar, $logoutTpl, $matchAllAttrs,$matchOneAttrs, 
                         $matchFailTpl, $maxAttempts, $maxAttemptTpl, $maxAttemptIp, 
                         $maxAttemptTimeout, $params, $resource, $sysErrTpl, 
                         $tplVar, $useSessions);
  }
  // }}}
  // }}}
  
  
  // public operations
  
  // {{{ authenticatedFromCli
  /**
   * returns TRUE if the PHP script is running from the command line, this 
   * authenticator was invoked, and the command line user was used for the 
   * authentication instead of prompting the user for login credentials
   * @access public static
   * @return boolean
   */
  function authenticatedFromCli() {
    global $_sraOsAuthenticatorFromCli;
    return $_sraOsAuthenticatorFromCli ? TRUE : FALSE;
  }
  // }}}
  
  // {{{ promptConsole
  /**
   * when running from the console, no login credentials are required
   * @access public
   * @return boolean
   */
  function promptConsole() {
    if (!$_SERVER['PHP_AUTH_USER'] && !$_SERVER['PHP_AUTH_PW']) {
      $_SERVER['PHP_AUTH_USER'] = SRA_Util::getCurrentUser();
      return TRUE;
    }
    else {
      return parent::promptConsole();
    }
  }
  // }}}
  
  
  // private operations
  // {{{ _authenticate
  /**
   * Authenticates user against operating system based on the user/password and 
   * parameters specified
   * @param string $user the username to authenticate
   * @param string $pswd the password to authenticate
   * @param array $params used for invoking this method statically
   * @return void or ERROR
   */
  function _authenticate($user, $pswd, $params=NULL) {
    if (!SRA_Controller::runningFromCli() && (!trim($user) || !trim($pswd))) {
      return;
    }
    $isStatic = $params ? TRUE : FALSE;
    $params = $isStatic ? $params : $this->_params;
    // construct transpose hash
    $transpose = array();
    if (SRA_Params::isValid($params) && $params->getParam('transpose')) {
      foreach(explode(' ', $params->getParam('transpose')) as $pair) {
        $tmp = explode('=', $pair);
        $transpose[$tmp[0]] = $tmp[1];
      }
    }
    
    // don't allow login from exclude and transpose users
    if ((in_array($user, $transpose) && !SRA_Controller::runningFromCli()) || (SRA_Params::isValid($params) && $params->getParam('exclude') && !in_array($user, explode(' ', $params->getParam('exclude'))))) {
      $this->status = SRA_AUTHENTICATOR_STATUS_INVALID_USER;
      return;
    }
    
    // transpose user
    if (isset($transpose[$user])) {
      $this->attrs['transposed'] = $transpose[$user];
      $user = $transpose[$user];
    }
    
    $tmpFile = uniqid();
    if (!$this->_entityType) {
      $cmds = array('cd ~;pwd', 'groups', "cd ~;touch $tmpFile", 'cd ~;ls -l -n', "cd ~;rm -f $tmpFile");
      $callbacks = array('groups' => 'explode(" ", ${results})');
      if (SRA_Params::isValid($params) && $params->getParam('profile')) {
        $profile = SRA_Util::substituteParams($params->getParam('profile'), array('user' => $user));
        $profile = 'cat ' . (SRA_Util::beginsWith($profile, '/') || SRA_Util::beginsWith($profile, '~') ? $profile : '~/' . $profile);
        $cmds[] = $profile;
        $callbacks[$profile] = 'SRA_Util::propertiesStringToHash';
      }
    }
    $login = SRA_Util::suCmds($user, $pswd, $this->_entityType ? NULL : $cmds, $this->_entityType ? NULL : $callbacks, SRA_Controller::runningFromCli());
    
    if ($login == 0) {
      $msg = 'SRA_OsAuthenticator::_authenticate: Failed - expect is not installed';
      return SRA_Error::logError($msg, __FILE__, __LINE__);
    }
    
    $status = $login === -1 ? SRA_AUTHENTICATOR_STATUS_INVALID_USER : ($login === -2 ? SRA_AUTHENTICATOR_STATUS_INVALID_PSWD : SRA_AUTHENTICATOR_STATUS_SUCCESS);
    
    if ($status == SRA_AUTHENTICATOR_STATUS_SUCCESS) {
      // user not member of required group
      if (!$this->_entityType && SRA_Params::isValid($params) && $params->getParam('groups') && !array_intersect(explode(' ', $params->getParam('groups')), $login['groups'])) {
        $status = SRA_AUTHENTICATOR_STATUS_INVALID_USER;
      }
      else if (!$this->_entityType) {
        $gid = NULL;
        $uid = NULL;
        foreach(explode("\n", $login['cd ~;ls -l -n']) as $tmp) {
          if (strpos($tmp, $tmpFile)) {
            $temp = explode(' ', $tmp);
            $started = FALSE;
            foreach($temp as $piece) {
              if ($started && !$uid) { $uid = $piece*1; }
              else if ($started && $uid) { 
                $gid = $piece*1;
                break;
              }
              else if (is_numeric($piece)) { $started = TRUE; }
            }
          }
        }
        
        $attrs = array('groups' => $login['groups'], 'home' => $login['cd ~;pwd'], 'uid' => $uid, 'gid' => $gid);
        if ($profile && is_array($login[$profile])) { $attrs = array_merge($login[$profile], $attrs); }
      }
    }
    
    if (SRA_Controller::runningFromCli() && $status == SRA_AUTHENTICATOR_STATUS_SUCCESS && $user == SRA_Util::getCurrentUser()) {
      global $_sraOsAuthenticatorFromCli;
      $_sraOsAuthenticatorFromCli = TRUE;
    }
    if ($isStatic) {
      return array('status' => $status, 'attrs' => $attrs);
    }
    else {
      $this->status = $status;
      if (is_array($attrs)) $this->attrs = array_merge($attrs, $this->attrs);
    }
  }
  // }}}

  
}
// }}}
?>
Return current item: Sierra-php PHP Application Framework