I've spent way too much time trying to get this work. So, I decided to rewrite some of it (and webserver_auth).

It now works (for me) and is pretty reliable. Alas, I had to hard code a couple of URLS because I don't know Drupal well enough to do that yet.

Enjoy.

(I might wrap the two into a single module one day).

cosign_module
<?php
// $Id: webserver_auth.module,v 1.13.2.3 2006/03/03 05:08:12 weitzman Exp $

function webserver_auth_init() {
  global $user, $account;

  if ($user->uid) {
    //do nothing because user is already logged into Drupal
  }
  else {
    if ($name = $_SERVER["REMOTE_USER"]) {
      // user is logged into webserver.
      $account->name = $name;
      //modules get to change the user bits before saving. use a global $account to do so.
      // only loaded modules will see this hook
      module_invoke_all("webserver_auth");
      // if we are in bootstrap, load user.module ourselves
      if (!module_exists('user')) {
       drupal_load('module', 'user');
      }

      // try to log into Drupal. if unsuccessful, register the user
     //if ($user = user_external_load($account->name);
    $query = db_query("select * from users where name = '%s'", $account->name);
    $user_exist = db_result($query);
if ($user_exist == 0)
{
  if (!$user->uid) {
        if (variable_get("user_register", 1) == 1) {
          $user_default = array("name" => $account->name, "pass" => "cyan", "init" => db_escape_string($name), "authname_webserver_auth" => $account->name, "status" => 1, "roles" => array(DRUPAL_AUTHENTICATED_RID));
          // TODO - the hook_user('register') will fire but only for loaded modules. cold be a problem for sites using page cache and that hook+operation
          $user = user_save("", array_merge($user_default, (array)$account));
          watchdog("user", "new user: $user->name (webserver_auth)", l(t("edit user"), "admin/user/edit/$user->uid"));
        }
else {
}
      }
      else {
       }

     }
     else {
    $user = user_external_load($account->name);
  }

   }
  }
}

// using a global to change your bits. module_invoke_all miffs me.
function webserver_auth_webserver_auth() {
  global $account;

  // pretties up the username for NTLM authentication (i.e. Windows)
  if ($_SERVER["AUTH_TYPE"] == "NTLM" || $_SERVER["AUTH_TYPE"] == 'Negotiate') {
    $account->name = substr(trim($account->name), strrpos(trim($account->name), "\\")+1);
  }

  if ($domain = variable_get("webserver_auth_domain", "")) {
    if ($account->name) {
      $account->mail = $account->name. "@$domain";
    }
  }
}

function webserver_auth_settings() {
  $form["webserver_auth_domain"] = array(
    '#type' => 'textfield',
    '#title' => t("Email Domain"),
    '#default_value' => variable_get("webserver_auth_domain", ""),
    '#size' => 30,
    '#maxlength' => 55,
    '#description' => t("Append this domain name to each new user in order generate his email address."),
    );
  return $form;
}

function webserver_auth_help($section) {
  $output ="";

  switch ($section) {
    case 'admin/help#webserver_auth':
      break;
    case 'admin/modules#description':
      $output .= t("Use web server authentication instead of Drupal");
      break;
  }

  return $output;
}


?>

cosign_module
<?php
// $Id: cosign.module,v 1.2 2007/01/26 18:27:37 wnorthway Exp $

function cosign_init( ) {
  global $user;

  if ( $_GET['q'] == 'logout' ) {
    watchdog('cosign', "logout: $user->name");
    cosign_logout( );
  }
  elseif ($user->uid) {
    // do nothing, user is logged in, and not logging out...
  }
  else {
    watchdog('cosign', "login: $user->name");
    webserver_auth_init();
  }

  return true;
}

function cosign_help($section) {
  switch ($section) {
    case 'admin/modules#description':
    return t("Allows users to authenticate via Cosign.");

  case "admin/help#cosign":
    return '<p>'. t("Allows users to authenticate via Cosign"). '</p>';
  }
}

function cosign_logout() {
        return true;
}

function cosign_block($op='list', $delta=0) {
        global $user;

        $block[0]["info"] = t("Cosign status and logout");

        if ($name = $_SERVER["REMOTE_USER"]) {

                $cosign_action = '<a href="https://unisign.auckland.ac.nz/logout/?'
                . 'http://phd.business.auckland.ac.nz/logout">Logout: '
                . $user->name .'</a>';
                // $block['content'] = 'logout <a href="' . base_path() . '?q=logout">' .  $user->name . '</a>';

        } else {
                $cosign_action = '<a href="https://phd.business.auckland.ac.nz/">Login</a>';
        }

        $block['content'] = $cosign_action;

        return $block;
}

function cosign_enable() {

  // copy all user sfrom the user table into the authmap table
  $result = db_query('SELECT uid, name FROM users WHERE uid > 0 AND name NOT IN (SELECT authname FROM authmap)');
  while($user_info = db_fetch_object($result)) {
    if (strlen($user_info->name)) {
      db_query(
        "INSERT INTO {authmap} (authname, uid, module) VALUES ('%s', %d, '%s')",
        $user_info->name,
        $user_info->uid,
        'cosign'
      );
    }
  }

  // default, not interpolated
  $realm = '$_SERVER[REMOTE_REALM]';
  if (isset($_SERVER[REMOTE_REALM])) {
    $realm = $_SERVER[REMOTE_REALM];
  }

  drupal_set_message('Warning: All users mentioned in the user
    table have been copied into the authmap table. This
    means that any pre-existing local users have been
    converted to <b>user@' .$realm . '</b>.  This may cause a
    mis-identification, and potential security issue if
    you had a user registered locally, and that name is
    mapped to someone else when using cosign.', 'status');

  return true;
}

?>

Comments

wnorthway’s picture

I'm sorry to hear that you encountered issues with the code. I don't see much that should be contributed back to the project. I notice that you didn't work with the latest version of the webserver_auth.module, which was based on v1.16

To get around hard-coding the URLs, I originally wrote code like this:

drupal_goto('https://' . $_SERVER[ 'SERVER_NAME' ] . '/cgi-bin/logout?'
. 'https://' . $_SERVER[ 'SERVER_NAME' ] . base_path());

Opting to pull variables from the webserver, so that it could run in anyone's system.

I'd be very interested if you do decide to combine the webserver_auth module with cosign. Since it appears that webserver_auth isn't being maintained currently, we may want to re-think our dependence upon it.

wnorthway’s picture

Status: Active » Closed (fixed)