View source  
  <?php
define('CAS_NO_LINK', 0);
define('CAS_ADD_LINK', 1);
define('CAS_MAKE_DEFAULT', 2);
define('CAS_REDIRECT', 3);
define('CAS_LOGIN_INVITE_DEFAULT', 'Log in using CAS');
define('CAS_LOGIN_DRUPAL_INVITE_DEFAULT', 'Cancel CAS login');
define('CAS_LOGIN_REDIR_MESSAGE', 'You will be redirected to the secure CAS login page.');
define('CAS_EXCLUDE', 'services/*');
define('CAS_CHECK_NEVER', -2);
define('CAS_CHECK_ONCE', -1);
define('CAS_CHECK_ALWAYS', 0);
function cas_init() {
  global $user;
  if (module_exists('cas_test') && arg(0) == 'cas_test') {
    
    return;
  }
  elseif (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE === 'install') {
    
    return;
  }
  
  _cas_single_sign_out_check();
  
  if (!$user->uid) {
    $force_authentication = _cas_force_login();
    $check_authentication = _cas_allow_check_for_login();
    $request_type = $_SERVER['REQUEST_METHOD'];
    $perform_login_check = $force_authentication || $check_authentication && $request_type == 'GET';
    if ($perform_login_check) {
      cas_login_check($force_authentication);
    }
  }
}
function cas_login_check($force_authentication = TRUE) {
  global $user;
  if ($user->uid) {
    
    return;
  }
  if (!cas_phpcas_load()) {
    
    return;
  }
  
  drupal_session_start();
  _cas_single_sign_out_save_ticket();
  
  if (cas_phpcas_init() === FALSE) {
    return;
  }
  
  if ($force_authentication) {
    try {
      phpCAS::forceAuthentication();
    } catch (CAS_AuthenticationException $e) {
      drupal_set_message(t('Error authenticating with CAS. Please try again or contact your website administrator if the problem persists.'), 'error');
      watchdog_exception('cas', $e);
      
      drupal_goto('');
    }
  }
  else {
    $logged_in = phpCAS::checkAuthentication();
    
    if (!$logged_in) {
      return;
    }
  }
  
  $cas_user = array(
    'name' => phpCAS::getUser(),
    'login' => TRUE,
    'register' => variable_get('cas_user_register', TRUE),
    'attributes' => cas_phpcas_attributes(),
  );
  drupal_alter('cas_user', $cas_user);
  
  if (empty($cas_user['login']) || empty($cas_user['name'])) {
    
    if ($force_authentication) {
      drupal_set_message(t('The user account %name is not available on this site.', array(
        '%name' => $cas_user['name'],
      )), 'error');
    }
    return;
  }
  
  $cas_name = $cas_user['name'];
  
  $blocked = FALSE;
  if (_cas_external_user_is_blocked($cas_name)) {
    $blocked = 'The username %cas_name has been blocked.';
  }
  
  if ($blocked) {
    
    if ($force_authentication) {
      watchdog('cas', $blocked, array(
        '%cas_name' => $cas_name,
      ), WATCHDOG_WARNING);
      drupal_set_message(t($blocked, array(
        '%cas_name' => $cas_name,
      )), 'error');
    }
    return;
  }
  $account = cas_user_load_by_name($cas_name);
  
  if (!$account && $cas_user['register']) {
    
    $account = cas_user_register($cas_name);
    if (!$account) {
      
      if ($force_authentication) {
        drupal_set_message(t('A new account could not be created for %cas_name. The username is already in use on this site.', array(
          '%cas_name' => $cas_name,
        )), 'error');
      }
      return;
    }
  }
  
  if ($account && $account->uid > 0) {
    
    $_SESSION['cas_name'] = $cas_name;
    $cas_first_login = !$account->login;
    
    if (!empty($_SESSION['cas_ticket'])) {
      _cas_single_sign_out_save_token($account);
    }
    
    $edit['cas_user'] = $cas_user;
    $edit['roles'] = $account->roles + cas_roles();
    if (module_exists('persistent_login') && !empty($_SESSION['cas_remember'])) {
      $edit['values']['persistent_login'] = 1;
    }
    
    cas_user_module_invoke('presave', $edit, $account);
    
    $user = user_save($account, $edit);
    user_login_finalize($edit);
    drupal_set_message(t(variable_get('cas_login_message', 'Logged in via CAS as %cas_username.'), array(
      '%cas_username' => format_username($user),
    )));
    if (!empty($edit['persistent_login'])) {
      drupal_set_message(t('You will remain logged in on this computer even after you close your browser.'));
    }
    _cas_redirect_after_login($cas_first_login);
  }
  else {
    $user = drupal_anonymous_user();
    unset($_SESSION['phpCAS']);
    
    if ($force_authentication) {
      drupal_set_message(t('No account found for %cas_name.', array(
        '%cas_name' => $cas_name,
      )), 'error');
    }
  }
}
function cas_phpcas_load($path = NULL) {
  if (!isset($path)) {
    if (module_exists('libraries')) {
      $path = libraries_get_path('CAS');
    }
    else {
      $path = variable_get('cas_library_dir', 'CAS');
    }
  }
  
  if ($path != '') {
    $path = rtrim($path, '/') . '/';
  }
  $filename = $path . 'CAS.php';
  include_once $filename;
  if (!defined('PHPCAS_VERSION') || !class_exists('phpCAS')) {
    
    return FALSE;
  }
  return PHPCAS_VERSION;
}
function cas_phpcas_init() {
  if (!defined('PHPCAS_VERSION') || !class_exists('phpCAS')) {
    cas_phpcas_load();
  }
  $initialized =& drupal_static(__FUNCTION__, FALSE);
  if ($initialized) {
    
    return;
  }
  $initialized = TRUE;
  
  $server_version = (string) variable_get('cas_version', '3.0');
  $server_cas_server = (string) variable_get('cas_server', '');
  $server_port = (int) variable_get('cas_port', '443');
  $server_uri = (string) variable_get('cas_uri', '');
  $cas_cert = (string) variable_get('cas_cert', '');
  $debug_file = (string) variable_get('cas_debugfile', '');
  
  if (empty($server_cas_server)) {
    watchdog('cas', 'Unable to initialize phpCAS because no CAS server hostname has been configured.', array(), WATCHDOG_ERROR);
    return FALSE;
  }
  if ($debug_file != '') {
    phpCAS::setDebug($debug_file);
  }
  $start_session = (bool) FALSE;
  if (variable_get('cas_proxy', 0)) {
    phpCAS::proxy($server_version, $server_cas_server, $server_port, $server_uri, $start_session);
    $cas_pgt_storage_path = variable_get('cas_pgtpath', '');
    if ($cas_pgt_storage_path != '') {
      if (version_compare(PHPCAS_VERSION, '1.3', '>=')) {
        phpCAS::setPGTStorageFile($cas_pgt_storage_path);
      }
      else {
        $cas_pgt_format = variable_get('cas_pgtformat', 'plain');
        phpCAS::setPGTStorageFile($cas_pgt_format, $cas_pgt_storage_path);
      }
    }
  }
  else {
    phpCAS::client($server_version, $server_cas_server, $server_port, $server_uri, $start_session);
  }
  
  $proxy_list = variable_get('cas_proxy_list', '');
  if ($proxy_list) {
    $proxy_list = explode("\n", $proxy_list);
    phpCAS::allowProxyChain(new CAS_ProxyChain($proxy_list));
  }
  
  if ($cas_cert = variable_get('cas_cert', '')) {
    phpCAS::setCasServerCACert($cas_cert);
  }
  else {
    phpCAS::setNoCasServerValidation();
  }
  phpCAS::setFixedServiceURL(url(current_path(), array(
    'query' => drupal_get_query_parameters(),
    'absolute' => TRUE,
  )));
  phpCAS::setCacheTimesForAuthRecheck((int) variable_get('cas_check_frequency', CAS_CHECK_NEVER));
  
  module_invoke_all('cas_phpcas_alter');
}
function cas_permission() {
  return array(
    'administer cas' => array(
      'title' => t('Administer CAS'),
      'description' => t('Configure CAS server, default CAS user roles, login/logout redirection, and other settings.'),
      'restrict access' => TRUE,
    ),
  );
}
function cas_help($section) {
  switch ($section) {
    case 'admin/help#cas':
      return t("Allows users to authenticate via a Central Authentication Service.");
  }
}
function cas_menu() {
  global $user;
  $items = array();
  
  $items['admin/config/people/cas'] = array(
    'title' => 'CAS settings',
    'description' => 'Configure central authentication services',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'cas_admin_settings',
    ),
    'access arguments' => array(
      'administer cas',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'cas.admin.inc',
  );
  $items['admin/config/people/cas/settings'] = array(
    'title' => 'CAS',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/people/cas/create'] = array(
    'title' => 'Add CAS user(s)',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'cas_add_user_form',
    ),
    'access arguments' => array(
      'administer users',
    ),
    'type' => MENU_LOCAL_ACTION,
    'file' => 'cas.user.inc',
    'tab_parent' => 'admin/people',
    'weight' => 1,
  );
  $items['user/%user/cas'] = array(
    'title' => 'CAS',
    'page callback' => 'cas_user_identities',
    'page arguments' => array(
      1,
    ),
    'access arguments' => array(
      'administer users',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'cas.pages.inc',
    'tab_parent' => 'user/%/edit',
    'weight' => 1,
  );
  $items['user/%user/cas/delete'] = array(
    'title' => 'Delete CAS username',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'cas_user_delete_form',
      1,
    ),
    'access arguments' => array(
      'administer users',
    ),
    'file' => 'cas.pages.inc',
  );
  $items['cas'] = array(
    'path' => 'cas',
    'title' => 'CAS Login',
    'page callback' => 'cas_login_page',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_SUGGESTED_ITEM,
  );
  $items['caslogout'] = array(
    'title' => 'CAS Logout',
    'page callback' => 'cas_logout',
    'access callback' => 'cas_user_is_logged_in',
    'type' => MENU_SUGGESTED_ITEM,
  );
  return $items;
}
function cas_cron() {
  
  $max_days = (int) variable_get('cas_single_logout_session_lifetime', 25);
  $seconds_in_day = 86400;
  $seconds = $max_days * $seconds_in_day;
  if ($seconds > 0) {
    db_delete('cas_login_data')
      ->condition('created', time() - $seconds, '<=')
      ->execute();
  }
}
function cas_user_is_logged_in() {
  return user_is_logged_in() || !empty($_SESSION['phpCAS']['user']);
}
function cas_menu_site_status_alter(&$menu_site_status, $path) {
  if (user_is_logged_in() && strtolower($path) == 'cas') {
    
    drupal_goto('');
  }
}
function cas_menu_link_alter(&$item) {
  $link_path = strtolower($item['link_path']);
  if ($link_path == 'cas' || $link_path == 'caslogout') {
    $item['options']['alter'] = TRUE;
  }
}
function cas_translated_menu_link_alter(&$item) {
  $href = strtolower($item['href']);
  $append_destination = $href == 'cas' || $href == 'caslogout' && !variable_get('cas_logout_destination', '');
  if ($append_destination) {
    
    if (isset($item['localized_options']['query'])) {
      $menu_link_query_params = array_merge(drupal_get_destination(), $item['localized_options']['query']);
    }
    else {
      $menu_link_query_params = drupal_get_destination();
    }
    $item['localized_options']['query'] = $menu_link_query_params;
  }
}
function cas_user_operations($form = array(), $form_state = array()) {
  $operations['cas_create'] = array(
    'label' => t('Create CAS username'),
    'callback' => 'cas_user_operations_create_username',
  );
  $operations['cas_remove'] = array(
    'label' => t('Remove CAS usernames'),
    'callback' => 'cas_user_operations_remove_usernames',
  );
  return $operations;
}
function cas_user_operations_create_username($uids) {
  $accounts = user_load_multiple($uids);
  foreach ($accounts as $account) {
    $count = db_select('cas_user', 'c')
      ->condition('cas_name', $account->name)
      ->condition('uid', $account->uid, '<>')
      ->countQuery()
      ->execute()
      ->fetchfield();
    if ($count) {
      drupal_set_message(t('CAS username %username already in use.', array(
        '%username' => $account->name,
      )), 'error');
      continue;
    }
    db_merge('cas_user')
      ->key(array(
      'cas_name' => $account->name,
    ))
      ->fields(array(
      'uid' => $account->uid,
    ))
      ->execute();
  }
}
function cas_user_operations_remove_usernames($uids) {
  db_delete('cas_user')
    ->condition('uid', $uids, 'IN')
    ->execute();
}
function cas_admin_paths() {
  $paths = array(
    'user/*/cas' => TRUE,
    'user/*/cas/delete/*' => TRUE,
  );
  return $paths;
}
function cas_user_load($users) {
  foreach (array_keys($users) as $uid) {
    $users[$uid]->cas_names = array();
  }
  $result = db_query('SELECT aid, uid, cas_name FROM {cas_user} WHERE uid IN (:uids)', array(
    ':uids' => array_keys($users),
  ));
  foreach ($result as $record) {
    $users[$record->uid]->cas_names[$record->aid] = $record->cas_name;
  }
  foreach (array_keys($users) as $uid) {
    $users[$uid]->cas_name = reset($users[$uid]->cas_names);
  }
}
function cas_user_insert(&$edit, $account, $category) {
  if (!empty($edit['cas_name'])) {
    db_insert('cas_user')
      ->fields(array(
      'cas_name' => $edit['cas_name'],
      'uid' => $account->uid,
    ))
      ->execute();
  }
  
  $users = array(
    $account->uid => $account,
  );
  cas_user_load($users);
}
function cas_user_update(&$edit, $account, $category) {
  if (!array_key_exists('cas_name', $edit)) {
    
    return;
  }
  $cas_name = $edit['cas_name'];
  
  reset($account->cas_names);
  if ($aid = key($account->cas_names)) {
    
    if (empty($cas_name)) {
      
      db_delete('cas_user')
        ->condition('uid', $account->uid)
        ->condition('aid', $aid)
        ->execute();
    }
    else {
      
      if ($cas_name != $account->cas_names[$aid]) {
        db_update('cas_user')
          ->fields(array(
          'cas_name' => $cas_name,
        ))
          ->condition('uid', $account->uid)
          ->condition('aid', $aid)
          ->execute();
      }
    }
  }
  else {
    
    if (!empty($cas_name)) {
      
      db_insert('cas_user')
        ->fields(array(
        'uid' => $account->uid,
        'cas_name' => $cas_name,
      ))
        ->execute();
    }
  }
  
  $users = array(
    $account->uid => $account,
  );
  cas_user_load($users);
}
function cas_user_delete($account) {
  db_delete('cas_user')
    ->condition('uid', $account->uid)
    ->execute();
}
function cas_user_load_by_name($cas_name, $alter = FALSE, $reset = FALSE) {
  if ($alter) {
    $cas_user = array(
      'name' => $cas_name,
      'login' => TRUE,
      'register' => FALSE,
    );
    drupal_alter('cas_user', $cas_user);
    $cas_name = $cas_user['name'];
  }
  $uid = db_select('cas_user')
    ->fields('cas_user', array(
    'uid',
  ))
    ->condition('cas_name', db_like($cas_name), 'LIKE')
    ->range(0, 1)
    ->execute()
    ->fetchField();
  if ($uid) {
    return user_load($uid, $reset);
  }
  return FALSE;
}
function cas_login_page() {
  drupal_goto('');
}
function cas_logout($invoke_hook = TRUE) {
  global $user;
  
  cas_phpcas_init();
  if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) {
    
    $destination = $_GET['destination'];
  }
  else {
    $destination = variable_get('cas_logout_destination', '');
  }
  
  if ($destination) {
    $destination_url = url($destination, array(
      'absolute' => TRUE,
    ));
    $options = array(
      'service' => $destination_url,
      'url' => $destination_url,
    );
  }
  else {
    $options = array();
  }
  
  if ($invoke_hook) {
    watchdog('user', 'Session closed for %name.', array(
      '%name' => format_username($user),
    ));
    module_invoke_all('user_logout', $user);
  }
  
  phpCAS::logout($options);
}
function cas_block_info() {
  $blocks['login']['info'] = t('CAS login');
  
  $blocks['login']['cache'] = DRUPAL_NO_CACHE;
  return $blocks;
}
function cas_block_view($delta = '') {
  global $user;
  $block = array();
  switch ($delta) {
    case 'login':
      
      if (!$user->uid && !(arg(0) == 'user' && !is_numeric(arg(1)))) {
        $block['subject'] = t('User login');
        $block['content'] = drupal_get_form('cas_login_block');
      }
      return $block;
  }
}
function cas_login_block($form) {
  $form['#action'] = url('cas', array(
    'query' => drupal_get_destination(),
  ));
  $form['#id'] = 'cas-login-form';
  $form['cas_login_redirection_message'] = array(
    '#type' => 'item',
    '#markup' => t(variable_get('cas_login_redir_message', CAS_LOGIN_REDIR_MESSAGE)),
    '#weight' => -1,
  );
  $form['actions'] = array(
    '#type' => 'actions',
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT)),
  );
  return $form;
}
function _cas_allow_check_for_login() {
  
  if (variable_get('maintenance_mode', 0)) {
    return FALSE;
  }
  if (variable_get('cas_check_frequency', CAS_CHECK_NEVER) == CAS_CHECK_NEVER) {
    
    return FALSE;
  }
  
  if (isset($_SERVER['HTTP_USER_AGENT'])) {
    $crawlers = array(
      'Google',
      'msnbot',
      'Rambler',
      'Yahoo',
      'AbachoBOT',
      'accoona',
      'AcoiRobot',
      'ASPSeek',
      'CrocCrawler',
      'Dumbot',
      'FAST-WebCrawler',
      'GeonaBot',
      'Gigabot',
      'Lycos',
      'MSRBOT',
      'Scooter',
      'AltaVista',
      'IDBot',
      'eStyle',
      'Scrubby',
      'gsa-crawler',
    );
    
    foreach ($crawlers as $c) {
      if (stripos($_SERVER['HTTP_USER_AGENT'], $c) !== FALSE) {
        return FALSE;
      }
    }
  }
  
  if (stristr($_SERVER['SCRIPT_FILENAME'], 'xmlrpc.php')) {
    return FALSE;
  }
  if (stristr($_SERVER['SCRIPT_FILENAME'], 'cron.php')) {
    return FALSE;
  }
  if (stristr($_SERVER['SCRIPT_FILENAME'], 'drush')) {
    return FALSE;
  }
  if (!empty($_SERVER['argv'][0]) && stristr($_SERVER['argv'][0], 'drush')) {
    return FALSE;
  }
  
  if ($pages = variable_get('cas_exclude', CAS_EXCLUDE)) {
    $path = drupal_get_path_alias($_GET['q']);
    if (drupal_match_path($path, $pages)) {
      return FALSE;
    }
  }
  return TRUE;
}
function _cas_force_login() {
  
  if (strtolower(arg(0)) == 'cas') {
    return TRUE;
  }
  
  if (variable_get('maintenance_mode', 0)) {
    return FALSE;
  }
  
  if (stristr($_SERVER['SCRIPT_FILENAME'], 'xmlrpc.php')) {
    return FALSE;
  }
  if (stristr($_SERVER['SCRIPT_FILENAME'], 'cron.php')) {
    return FALSE;
  }
  if (function_exists('drush_verify_cli') && drush_verify_cli()) {
    return FALSE;
  }
  
  if ($pages = variable_get('cas_exclude', CAS_EXCLUDE)) {
    $path = drupal_get_path_alias($_GET['q']);
    if (drupal_match_path($path, $pages)) {
      return FALSE;
    }
  }
  
  $force_login = variable_get('cas_access', 0);
  
  if ($pages = variable_get('cas_pages', '')) {
    $path = drupal_get_path_alias($_GET['q']);
    if (drupal_match_path($path, $pages)) {
      $force_login = !$force_login;
    }
  }
  return $force_login;
}
function cas_form_alter(&$form, &$form_state, $form_id) {
  
  if ($form_id == 'user_login' && variable_get('cas_login_form', CAS_NO_LINK) == CAS_REDIRECT) {
    drupal_goto('cas');
  }
  switch ($form_id) {
    case 'user_login':
    case 'user_login_block':
      if (variable_get('cas_login_form', CAS_NO_LINK) != CAS_NO_LINK) {
        $form['#attached']['css'][] = drupal_get_path('module', 'cas') . '/cas.css';
        $form['#attached']['js'][] = drupal_get_path('module', 'cas') . '/cas.js';
        if (!empty($form_state['input']['cas_identifier'])) {
          $form['name']['#required'] = FALSE;
          $form['pass']['#required'] = FALSE;
          unset($form['#validate']);
          $form['#submit'] = array(
            'cas_login_submit',
          );
        }
        $items = array();
        $items[] = array(
          'data' => l(t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT)), '#'),
          'class' => array(
            'cas-link',
          ),
        );
        $items[] = array(
          'data' => l(t(variable_get('cas_login_drupal_invite', CAS_LOGIN_DRUPAL_INVITE_DEFAULT)), '#'),
          'class' => array(
            'uncas-link',
          ),
        );
        $form['cas_links'] = array(
          '#theme' => 'item_list',
          '#items' => $items,
          '#attributes' => array(
            'class' => array(
              'cas-links',
            ),
          ),
          '#weight' => 101,
        );
        $form['links']['#weight'] = 2;
        $form['cas_login_redirection_message'] = array(
          '#type' => 'item',
          '#markup' => t(variable_get('cas_login_redir_message', CAS_LOGIN_REDIR_MESSAGE)),
          '#weight' => -1,
        );
        $form['cas_identifier'] = array(
          '#type' => 'checkbox',
          '#title' => t(variable_get('cas_login_invite', CAS_LOGIN_INVITE_DEFAULT)),
          '#default_value' => variable_get('cas_login_form', CAS_NO_LINK) == CAS_MAKE_DEFAULT,
          '#weight' => -1,
          '#description' => t(variable_get('cas_login_redir_message', CAS_LOGIN_REDIR_MESSAGE)),
        );
        $form['cas.return_to'] = array(
          '#type' => 'hidden',
          '#value' => user_login_destination(),
        );
      }
      break;
    case 'user_profile_form':
      $account = $form['#user'];
      if (user_access('administer users')) {
        
        $cas_names = $account->cas_names;
        $aids = array_keys($cas_names);
        $element = array(
          '#type' => 'textfield',
          '#title' => t('CAS username'),
          '#default_value' => array_shift($cas_names),
          '#cas_user_aid' => array_shift($aids),
          '#description' => t('<a href="@url">Create, edit or delete</a> additional CAS usernames associated with this account.', array(
            '@url' => url('user/' . $account->uid . '/cas'),
          )),
          '#element_validate' => array(
            '_cas_name_element_validate',
          ),
          '#weight' => -9,
        );
        
        if (!empty($cas_names)) {
          $element['#description'] .= ' <br />' . t('Other CAS usernames: %cas_names.', array(
            '%cas_names' => implode(', ', $cas_names),
          ));
        }
        $form['account']['cas_name'] = $element;
      }
      elseif (cas_is_external_user($account)) {
        
        if (variable_get('cas_hide_email', 0)) {
          $form['account']['mail']['#access'] = FALSE;
        }
        if (variable_get('cas_hide_password', 0)) {
          $form['account']['pass']['#access'] = FALSE;
        }
      }
      if (cas_is_external_user($account) && variable_get('cas_hide_password', 0)) {
        
        $form['account']['current_pass']['#access'] = FALSE;
        $form['account']['current_pass_required_values']['#access'] = FALSE;
        $form['account']['current_pass_required_values']['#value'] = array();
        $form['#validate'] = array_diff($form['#validate'], array(
          'user_validate_current_pass',
        ));
      }
      break;
    case 'user_pass':
      if (!user_access('administer users') && variable_get('cas_changePasswordURL', '') != '') {
        drupal_goto(variable_get('cas_changePasswordURL', ''));
      }
      break;
    case 'user_register_form':
      if (user_access('administer users')) {
        $form['account']['cas_name'] = array(
          '#type' => 'textfield',
          '#title' => t('CAS username'),
          '#default_value' => '',
          '#description' => t('If necessary, additional CAS usernames can be added after the account is created.'),
          '#element_validate' => array(
            '_cas_name_element_validate',
          ),
          '#weight' => -9,
        );
      }
      elseif (variable_get('cas_registerURL', '') != '') {
        drupal_goto(variable_get('cas_registerURL', ''));
      }
      break;
    case 'user_admin_account':
      
      _cas_array_insert($form['accounts']['#header'], 1, array(
        'cas' => array(
          'data' => 'CAS usernames',
        ),
      ));
      foreach ($form['accounts']['#options'] as $uid => &$row) {
        $cas_usernames = db_query('SELECT cas_name FROM {cas_user} WHERE uid = :uid', array(
          ':uid' => $uid,
        ))
          ->fetchCol();
        $row['cas'] = theme('item_list', array(
          'items' => $cas_usernames,
        ));
      }
      break;
  }
}
function _cas_name_element_validate($element, &$form_state) {
  if (empty($element['#value'])) {
    
    return;
  }
  $query = db_select('cas_user')
    ->fields('cas_user', array(
    'uid',
  ))
    ->condition('cas_name', $element['#value']);
  
  if (isset($element['#cas_user_aid'])) {
    $query
      ->condition('aid', $element['#cas_user_aid'], '<>');
  }
  $uid = $query
    ->execute()
    ->fetchField();
  if ($uid !== FALSE) {
    
    form_set_error('cas_name', t('The CAS username is <a href="@edit-user-url">already in use</a> on this site.', array(
      '@edit-user-url' => url('user/' . $uid . '/edit'),
    )));
  }
}
function cas_login_submit(&$form, &$form_state) {
  if (!empty($form_state['values']['persistent_login'])) {
    $_SESSION['cas_remember'] = 1;
  }
  
  unset($_GET['destination']);
  drupal_goto('cas', array(
    'query' => $form_state['values']['cas.return_to'],
  ));
}
function _cas_single_sign_out_check() {
  if (isset($_POST["logoutRequest"])) {
    $cas_logout_request_xml_string = utf8_encode(urldecode($_POST["logoutRequest"]));
    $cas_logout_request_xml = new SimpleXMLElement($cas_logout_request_xml_string);
    if (is_object($cas_logout_request_xml)) {
      $namespaces = $cas_logout_request_xml
        ->getNameSpaces();
      $xsearch = 'SessionIndex';
      if (isset($namespaces['samlp'])) {
        $cas_session_indexes = $cas_logout_request_xml
          ->children($namespaces['samlp'])->SessionIndex;
      }
      else {
        $cas_session_indexes = $cas_logout_request_xml
          ->xpath($xsearch);
      }
      if ($cas_session_indexes) {
        $cas_session_index = (string) $cas_session_indexes[0];
        
        $hashed_ticket = hash('sha256', $cas_session_index);
        $record = db_query_range("SELECT cld.uid, u.name FROM {users} u JOIN {cas_login_data} cld ON u.uid = cld.uid WHERE cld.cas_session_id = :ticket", 0, 1, array(
          ':ticket' => $hashed_ticket,
        ))
          ->fetchObject();
        if ($record) {
          watchdog('user', 'Session closed for %name by CAS logout request.', array(
            '%name' => $record->name,
          ));
          
          db_delete('cas_login_data')
            ->condition('uid', $record->uid)
            ->execute();
          
          db_delete('sessions')
            ->condition('uid', $record->uid)
            ->execute();
        }
      }
    }
    
    exit;
  }
}
function cas_current_user() {
  return isset($_SESSION['cas_name']) ? $_SESSION['cas_name'] : FALSE;
}
function cas_is_external_user($account = NULL) {
  if (!isset($account)) {
    $account = $GLOBALS['user'];
  }
  return in_array(cas_current_user(), $account->cas_names);
}
function _cas_single_sign_out_save_token($user) {
  
  if ($user->uid && $user->uid > 0 && !empty($_SESSION['cas_ticket'])) {
    $hashed_ticket = hash('sha256', $_SESSION['cas_ticket']);
    db_merge('cas_login_data')
      ->key(array(
      'cas_session_id' => $hashed_ticket,
    ))
      ->fields(array(
      'cas_session_id' => $hashed_ticket,
      'uid' => $user->uid,
      'created' => time(),
    ))
      ->execute();
    unset($_SESSION['cas_ticket']);
  }
}
function _cas_single_sign_out_save_ticket() {
  if (isset($_GET['ticket'])) {
    $_SESSION['cas_ticket'] = $_GET['ticket'];
  }
}
function _cas_external_user_is_blocked($cas_name) {
  return db_query("SELECT name FROM {users} u JOIN {cas_user} c ON u.uid = c.uid WHERE u.status = 0 AND c.cas_name = :cas_name", array(
    ':cas_name' => $cas_name,
  ))
    ->fetchField();
}
function cas_user_module_invoke($type, &$edit, $account) {
  foreach (module_implements('cas_user_' . $type) as $module) {
    $function = $module . '_cas_user_' . $type;
    $function($edit, $account);
  }
}
function cas_roles() {
  $cas_roles =& drupal_static(__FUNCTION__);
  if (!isset($cas_roles)) {
    $cas_roles = array_intersect_key(user_roles(), array_filter(variable_get('cas_auto_assigned_role', array(
      DRUPAL_AUTHENTICATED_RID => TRUE,
    ))));
  }
  return $cas_roles;
}
function cas_user_register($cas_name, $options = array()) {
  
  $edit = isset($options['edit']) ? $options['edit'] : array();
  $edit += array(
    'name' => $cas_name,
    'pass' => user_password(),
    'init' => $cas_name,
    'mail' => variable_get('cas_domain', '') ? $cas_name . '@' . variable_get('cas_domain', '') : '',
    'status' => 1,
    'roles' => array(),
  );
  $edit['roles'] += cas_roles();
  $edit['cas_name'] = $cas_name;
  
  if ((bool) db_select('users')
    ->fields('users', array(
    'name',
  ))
    ->condition('name', db_like($edit['name']), 'LIKE')
    ->range(0, 1)
    ->execute()
    ->fetchField()) {
    return FALSE;
  }
  
  $account = user_save(drupal_anonymous_user(), $edit);
  watchdog("user", 'new user: %n (CAS)', array(
    '%n' => format_username($account),
  ), WATCHDOG_NOTICE, l(t("edit user"), "user/edit/{$account->uid}"));
  if (!empty($options['invoke_cas_user_presave'])) {
    
    $edit = array(
      'cas_user' => array(
        'name' => $cas_name,
      ),
    );
    
    cas_user_module_invoke('presave', $edit, $account);
    
    unset($edit['cas_user']);
    $account = user_save($account, $edit);
  }
  
  return user_load($account->uid);
}
function cas_phpcas_attributes($cas_name = NULL) {
  if (isset($cas_name) && $cas_name != cas_current_user()) {
    
    return array();
  }
  cas_phpcas_init();
  if (phpCAS::isAuthenticated()) {
    if (method_exists('phpCAS', 'getAttributes')) {
      return phpCAS::getAttributes();
    }
  }
  return array();
}
function _cas_array_insert(&$array, $position, $insert_array) {
  $first_array = array_splice($array, 0, $position);
  $array = array_merge($first_array, $insert_array, $array);
}
function cas_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'cas') . '/includes/views',
  );
}
function _cas_redirect_after_login($cas_first_login) {
  
  if ($cas_first_login && variable_get('cas_first_login_destination', '')) {
    $destination = variable_get('cas_first_login_destination', '');
    drupal_goto($destination);
  }
  else {
    
    if (strtolower(current_path()) == 'cas') {
      drupal_goto('');
    }
    else {
      drupal_goto(current_path(), array(
        'query' => drupal_get_query_parameters(),
      ));
    }
  }
}