You are here

ip_login.module in IP Login 7.2

Allow user login by IP addresses, ranges or wildcards.

Originally by David W Thomas Major enhancements and 2.x branch by Jim Kirkpatrick Other big contributions from:

File

ip_login.module
View source
<?php

/**
 * @file
 * Allow user login by IP addresses, ranges or wildcards.
 *
 * Originally by David W Thomas
 * Major enhancements and 2.x branch by Jim Kirkpatrick
 * Other big contributions from:
 *  - JohnV: Code tidy/refactor & D7 version - http://drupal.org/node/1151458
 *  - PeterX: Many bug fixes and tweaks
 */

/*
 * @todo for security, IP addresses and ranges should really be checked for collisions between existing accounts users
 * @todo Check usage of $GLOBALS['conf']['cache'] in ip_login_attempt_login())
 */
define('ATTEMPT_IP_LOGIN', 'user/login_by_ip');

// path for ip login
define('IP_LOGOUT', 'user/logout');

// path for user logout (different between D6/D7)
define('IP_CHECKED', 'ip_login_checked');

// TRUE when IP check has happened
define('IP_UID_MATCH', 'ip_login_uid');

// TRUE when a user account matches the request IP
define('LOGIN_AS_DIFFERENT_USER', 'ip_login_as_different_user');

// TRUE when user wants alternate account
define('CACHE_DISABLED', 0);

// D7 TODO: this is removed from bootstrap.inc, and now in?? --> avoid double definition

/**
 * Implementation of hook_boot().
 *
 *   see http://drupal.org/node/509028
 */
function ip_login_boot() {

  // skip rest of this if user is logged in
  global $user;
  if ($user->uid != 0) {
    return;
  }

  // skip rest of this if the admin has disabled IP login
  if (!variable_get('ip_login_enabled', 1)) {
    return;
  }

  // Avoid settings cookies if not on an IP Login-enabled page to improve
  // external caching support - http://drupal.org/node/1263234 thanks Vacilando
  if (ip_login_check_path() === FALSE) {
    return;
  }

  // check the user IP
  $matched_uid = ip_login_check(ip_address());
  if ($matched_uid > 0) {
    $can_login_as_another_user = isset($_COOKIE[LOGIN_AS_DIFFERENT_USER]) ? $_COOKIE[LOGIN_AS_DIFFERENT_USER] : NULL;

    // for clarity about every scenario, use extensive logic
    if (is_null($can_login_as_another_user)) {

      // first time login for user, so log in automatically.
      ip_login_login($matched_uid);
      drupal_goto(ltrim(request_uri(), '/'));
    }
    elseif ($can_login_as_another_user == FALSE) {

      // user logged out, but is not allowed to use another user, so log in again.
      ip_login_login($matched_uid);
      drupal_goto(ltrim(request_uri(), '/'));
    }
    elseif ($can_login_as_another_user == TRUE) {

      // user logged out, and is allowed to login as another user,
      // so do nothing, just stay on this page and wait for user action.
    }
    else {

      // do automatic login.
      ip_login_login($matched_uid);
      drupal_goto(ltrim(request_uri(), '/'));
    }
  }
}

/**
 * Implementation of hook_help().
 */
function ip_login_help($path, $arg) {

  // @todo use t()
  switch ($path) {
    case 'admin/config/people/ip_login':
      $help = '<p>';
      $help .= t("This module allows this site to automatically authenticate and login users arriving with a chosen IP address - optionally at certain pages only.") . '</p> <p>';
      $help .= t('It also allows users with the <code>administer ip login</code> and <code>can log in as another user</code> <a href="@permissions-link">permissions</a> to log out and log in as another user, with other users being forced to stay logged in.', array(
        '@permissions-link' => '/admin/people/permissions#module-ip_login',
      ));
      $help .= '</p>';
      $help .= ip_login_help_ranges();
      return $help;
  }
}

/**
 * Provides help about accepted values of IP ranges etc.
 */
function ip_login_help_ranges($intro = '') {
  $help = '<p id="ip_login">' . $intro . ' ' . t('Accepted IP Login match values are:') . '</p>';
  $help .= '<ul><li>';
  $help .= t("Single IP matches like <code>123.123.123.123</code>");
  $help .= '</li><li>';
  $help .= t("Wildcards using an asterisk (<code>*</code>) in any quadrant except the first one, for example <code>123.123.123.*</code> or <code>100.*.*.*</code> etc.");
  $help .= '</li><li>';
  $help .= t("Ranges using a hyphen (<code>-</code>) in any quadrant except the first one, for example <code>123.123.123.100-200</code> etc.");
  $help .= '</li><li>';
  $help .= t("Any number of comma-separated IP addresses or ranges like <code>10.11.12.13, 123.123.123.100-200, 123.123.124-125.*</code> etc.");
  $help .= '</li></ul>';
  return $help;
}

/**
 * Implementation of hook_menu().
 */
function ip_login_menu() {
  $items[ATTEMPT_IP_LOGIN] = array(
    'title' => 'Automatically log me in by IP',
    'access callback' => 'ip_login_is_possible',
    'page callback' => 'ip_login_attempt_login',
    'type' => MENU_CALLBACK,
  );
  $items['admin/config/people/ip_login'] = array(
    'title' => 'IP Login',
    'description' => 'Configure IP Login settings',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer ip login',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'ip_login_admin_settings',
    ),
    'file' => 'ip_login.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/people/ip_login'] = array(
    'title' => 'Users with IP Login',
    'description' => 'Lists the users who can auto-login by IP address',
    'access callback' => 'user_access',
    'access arguments' => array(
      'administer ip login',
    ),
    'page callback' => 'ip_login_user_list',
    'file' => 'ip_login.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Callback function for hook_menu (menu access)
 *
 * @return boolean
 *    TRUE if login by IP can happen because a user match has happened
 */
function ip_login_is_possible() {

  // Return TRUE if a matching uid is found.
  return !empty($_SESSION[IP_UID_MATCH]);
}

/**
 * Checks the request IP and logs user in there's a match by calling
 * ip_login_check then ip_login_attempt_login
 *
 * Callback function for hook_menu
 */
function ip_login_attempt_login() {
  $GLOBALS['conf']['cache'] = FALSE;

  // don't cache - not sure if this is correct usage
  $matched_uid = ip_login_check(ip_address());
  if ($matched_uid > 0) {
    ip_login_login($matched_uid);
  }
  drupal_goto(variable_get('ip_login_destination', 'user'));
}

/**
 * Implementation of hook_permission().
 */
function ip_login_permission() {

  // @todo add perms checks to correct places in module
  return array(
    'administer ip login' => array(
      'title' => t('Administer IP Login module'),
      'description' => t('Perform administration tasks for IP Login.'),
    ),
    'can log in as another user' => array(
      'title' => t('Can login as other user'),
      'description' => t('Allow user to logout and login as another user.'),
    ),
  );
}

/**
 * Implementation of hook_form_alter().
 */
function ip_login_form_alter(&$form, &$form_state, $form_id) {

  // @todo should call hook_theme ideally
  switch ($form_id) {
    case 'user_login':
      $matched_uid = ip_login_check(ip_address());
      if ($matched_uid > 0) {
        $link_text = t(variable_get('ip_login_link_login_page', 'Log in automatically'));
        if (drupal_strlen($link_text)) {

          // hide if no link text
          $link_help = t(variable_get('ip_login_link_login_page_help', "Your computer's IP address has been matched and validated."));
          $markup = '<br/>';
          $markup .= '<ul class="item-list">';
          $markup .= '<li><strong>' . l($link_text, ATTEMPT_IP_LOGIN, array(
            'query' => array(
              'ip_login_override_pages' => 'yes',
            ),
          )) . '</strong>';
          if (drupal_strlen($link_help)) {
            $markup .= '<br/><small>' . filter_xss_admin($link_help) . '</small>';
          }
          $markup .= '</li></ul>';
          $form['ip_login'] = array(
            '#markup' => $markup,
            '#weight' => variable_get('ip_login_link_login_page_weight', -10),
          );
        }
      }
      break;
    case 'user_login_block':
      $matched_uid = ip_login_check(ip_address());
      if ($matched_uid > 0) {
        $link_text = t(variable_get('ip_login_link_login_block', 'Log in automatically'));
        if (drupal_strlen($link_text)) {

          // hide if no link text
          $markup = '<ul class="item-list">';
          $markup .= '<li><strong>' . l($link_text, ATTEMPT_IP_LOGIN, array(
            'query' => array(
              'ip_login_override_pages' => 'yes',
            ),
          )) . '</strong>';
          $markup .= '</li></ul>';
          $form['ip_login'] = array(
            '#markup' => $markup,
            '#weight' => variable_get('ip_login_link_login_page_weight', -10),
          );
        }
      }
      break;
    case 'user_profile_form':

    // change user
    case 'user_register_form':

      //create user
      global $user;
      if (user_access('administer ip login', $user)) {
        $account = $form['#user'];

        // set the validation callback
        $form['#validate'][] = '_ip_login_user_form_validate';

        // wrap in a fieldset
        $form['ip_login_matches'] = array(
          '#type' => 'fieldset',
          '#title' => t('IP Login Settings'),
          '#description' => ip_login_help_ranges(t('This user can be automatically logged in by IP address.')),
          '#weight' => '-1',
        );
        $form['ip_login_matches']['ip_login_match'] = array(
          '#type' => 'textfield',
          '#title' => t('IP address matches'),
          '#description' => t('IP matches based in format listed above. Leave blank to disable automatic login by IP for this user.'),
          '#default_value' => _ip_login_get_user_range($account->uid),
          '#default_value' => _ip_login_get_user_range($account->uid),
          '#maxlength' => 255,
        );
      }
      break;
  }
}

/**
 * Implementation of hook_block_info
 *
 * Adds the simple 'Automatic login' link block
 */
function ip_login_block_info() {
  $blocks = array();
  $blocks['ip-login-link'] = array(
    'info' => t('Log in by IP link'),
    'cache' => DRUPAL_NO_CACHE,
  );
  return $blocks;
}

/**
 * Implementation of hook_block_view
 *
 * Makes simple a 'Automatic login' link available for those not wanting to use the
 * overridden 'User Login' block.
 */
function ip_login_block_view($delta = '') {

  // only show for anonymous users who can log in
  global $user;
  if ($user->uid > 0 || !ip_login_is_possible()) {
    return;
  }
  if ($delta != 'ip-login-link') {
    return;
  }

  // build simple block
  // @todo should be a hook_theme call
  $link_text = t(variable_get('ip_login_link_login_block', 'Log in automatically'));
  $markup = '<div class="ip-login-available"><span class="ip-login-link">';
  $markup .= l($link_text, ATTEMPT_IP_LOGIN, array(
    'query' => array(
      'ip_login_override_pages' => 'yes',
    ),
  ));
  $markup .= '</span></div>';
  $block = array(
    'subject' => t('Automatic login'),
    'content' => $markup,
  );
  return $block;
}

/**
 * Callback for hook_form_alter().
 */
function _ip_login_user_form_validate($form, &$form_state) {

  //TODO: replace with regexp ideally

  // validate: replace all non-numeric but legal IP range chars with '|'
  $value = $form['ip_login_matches']['ip_login_match']['#value'];
  $ip_login_addresses = strtr($value, ' ,.-*', '|||||');
  foreach (explode('|', $ip_login_addresses) as $quad) {
    if (!empty($quad) && !is_numeric($quad)) {

      // bad entry, warn & bail
      form_set_error('ip_login_matches', t('Only numbers, spaces, commas, dots, asterisks and hyphens allowed in IP ranges.'));
    }
  }
}

/**
 * Implements hook_user_insert().
 */
function ip_login_user_insert(&$edit, $account, $category) {
  _ip_login_set_user_range($account->uid, isset($edit['ip_login_match']) ? trim(check_plain($edit['ip_login_match'])) : NULL);
}

/**
 * Implements hook_user_update().
 */
function ip_login_user_update(&$edit, $account, $category) {

  // Only update if ip_login_match field returned to avoid issue with Remember Me
  // (and others using hook_user update) wiping the field. By PeterX
  // http://drupal.org/node/1482934
  if (!isset($edit['ip_login_match'])) {
    return;
  }

  // all ok, save the data.
  _ip_login_set_user_range($account->uid, isset($edit['ip_login_match']) ? trim(check_plain($edit['ip_login_match'])) : NULL);
}

/**
 * Implements hook_user_delete().
 */
function ip_login_user_delete($account) {
  _ip_login_set_user_range($account->uid, NULL);
}
function ip_login_user_form_submit(&$edit, $account, $category) {
  _ip_login_set_user_range($account->uid, isset($edit['ip_login_match']) ? trim(check_plain($edit['ip_login_match'])) : NULL);
}

/**
 * Compares the current request's IP address to the ip_login_user table
 * and then does a proper match for each match on exact, ranges and wildcards
 *
 * @param $ip
 *    An ip address string, usually from the current user's request
 * @return $uid_matched
 *    The uid of the matching user account
 */
function ip_login_check($ip, $diagnostics = FALSE) {

  // have we checked user IP already this session?
  if (!empty($_SESSION[IP_CHECKED])) {
    return $_SESSION[IP_UID_MATCH];
  }

  // break up IP for ip address
  $addr = explode(".", check_plain($ip));
  $matches = FALSE;
  $uid_matched = 0;

  // Find user ip matches on the first part of the user's IP ANYWHERE except the end.
  // Not desperately efficient but works consistently with comma separated IP ranges and spaces,
  // and these checks are only done once per session anyway.
  $partial_matches = db_query("SELECT uid, ip_match\n       FROM {ip_login_user}\n       WHERE ip_match LIKE (:addr)\n       ORDER by LENGTH(ip_match) ASC", array(
    ':addr' => '%' . $addr[0] . '.%',
  ));
  foreach ($partial_matches as $row) {

    // multiple values are separated with commas so try each in turn
    $user_ip_ranges = explode(",", $row->ip_match);
    foreach ($user_ip_ranges as $ip_range) {

      // clear any whitespace, break into quads, then compare
      $ip_range = explode('.', trim($ip_range));
      foreach ($ip_range as $index => $quad) {
        $matches = ip_login_match_quad($addr[$index], $quad);
        if (!$matches) {
          break;
        }

        // no match, escape this foreach and move on to next IP range
      }

      // if it matches, stop here and do login
      if ($matches) {
        $uid_matched = $row->uid;
        break 2;

        // escape the foreach (ranges) and while (db_result)
      }
    }
  }

  // if not diagnostic test, set processed session flag, store matching user (if there is one)
  if (!$diagnostics) {
    $_SESSION[IP_CHECKED] = TRUE;
    $_SESSION[IP_UID_MATCH] = $uid_matched;
  }
  return $uid_matched;
}

/**
 * Checks path of current page matches any set as options on the admin page to
 * see if IP login should occur. Adapted from core Block module's block_list().
 *
 * @return $uid_matched
 *    The uid of the matching user account
 */
function ip_login_check_path() {
  if (!isset($_GET['ip_login_override_pages'])) {
    $pages = variable_get('ip_login_active_pages', '');
    if ($pages) {
      $page_match = FALSE;

      // first char, if variable set, is 'check_mode' - remainder is paths to match or PHP
      $check_mode = substr($pages, 0, 1);
      $pages = substr($pages, 1);
      if ($check_mode < 2) {

        // Compare with the path with allowed pages.
        // Since this happens in hook_boot, we cannot call drupal_get_path_alias
        // so call our own path matcher code and avoid a DB/alias check
        $path = isset($_GET['q']) ? $_GET['q'] : '';
        $page_match = ip_login_match_path($path, $pages);

        // When $check_mode has a value of 0, the IP check happens on
        // all pages except those listed in $pages. When set to 1, IPs
        // are checked only on those pages listed in $pages.
        $page_match = !($check_mode xor $page_match);
      }
      else {

        // evaluate PHP
        $page_match = drupal_eval($pages);
      }

      // if we don't have a path/PHP match, don't log in
      if (!$page_match) {
        return FALSE;
      }
    }
  }

  // all is well, continue with login.
  return TRUE;
}

/**
 * Check if a path matches any pattern in a set of patterns. This is a clone of
 * drupal_match_path() found in path.inc because the bootstrap hasn't occurred,
 * so path.inc isn't available.
 *
 * See: http://api.drupal.org/api/drupal/includes--path.inc/function/drupal_match_path/6
 */
function ip_login_match_path($path, $patterns) {
  static $regexps;
  if (!isset($regexps[$patterns])) {
    $regexps[$patterns] = '/^(' . preg_replace(array(
      '/(\\r\\n?|\\n)/',
      '/\\\\\\*/',
      '/(^|\\|)\\\\<front\\\\>($|\\|)/',
    ), array(
      '|',
      '.*',
      '\\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\\2',
    ), preg_quote($patterns, '/')) . ')$/';
  }
  return preg_match($regexps[$patterns], $path);
}

/**
 * Performs a login for user with $uid and stores IP Login variables for later
 *
 * @param $uid
 *    The UID of the account to be logged in
 */
function ip_login_login($uid) {
  if ($uid) {

    // if a uid is passed in
    // check this page's path is ok to login automatically from
    if (ip_login_check_path() === FALSE) {
      return;
    }

    // get user module and include some handy functions
    drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

    // get account (reload from db) , bail if no loaded active user
    $account = user_load($uid, TRUE);
    if (!$account || $account->status != 1) {
      return;
    }

    // login by assigning account to global $user object
    global $user;
    $user = $account;
    if (!variable_get('ip_login_suppress_messages', 0)) {

      // notify user - if messages not suppressed
      $message = t('Welcome %name. You have been automatically logged into %sitename.', array(
        '%name' => $user->name,
        '%sitename' => variable_get('site_name', 'this website'),
      ));
      drupal_set_message($message);

      // add handy message for those who can log out and then back in as another user
      if (_ip_login_can_login_as_another_user($user)) {
        $message = t('You may also <a href="@other_user_link">log in as another user</a> if required.', array(
          '@other_user_link' => url(IP_LOGOUT),
        ));
        drupal_set_message($message);
      }
    }

    // following borrowed from user_authenticate_finalize(), but with slightly different message
    watchdog('user', 'Session opened for %name by IP Login.', array(
      '%name' => $user->name,
    ));

    // This is also used to invalidate one-time login links.
    $user->login = time();
    db_update('users')
      ->fields(array(
      'login' => $user->login,
    ))
      ->condition('uid', $user->uid)
      ->execute();

    // Regenerate the session ID to prevent against session fixation attacks.
    // This is called before hook_user in case one of those functions fails
    // or incorrectly does a redirect which would leave the old session in place.
    $edit = NULL;
    drupal_session_regenerate();
    user_module_invoke('login', $edit, $user);

    // following borrowed from ipAuthenticator's login and avoids caching issues
    if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED && !isset($_GET['ip_login_no_cache'])) {

      // make a url to reload page, remove newlines from the URL to avoid header injection attacks.
      // use admin settings for destination if set.
      $url = variable_get('ip_login_destination', '');
      if (drupal_strlen($url) == 0) {
        $url = str_replace(array(
          "\n",
          "\r",
        ), '', $_GET["q"]);
      }
      if ($url == 'logout') {
        $url = '<front>';
      }
      $url = url($url, array(
        'query' => array(
          'ip_login_no_cache=' . md5(time()),
        ),
        'absolute' => TRUE,
      ));

      // Before the redirect, allow modules to react to the end of the page request.
      module_invoke_all('exit', $url);

      // Even though session_write_close() is registered as a shutdown function, we
      // need all session data written to the database before redirecting.
      session_write_close();
      header('Location: ' . $url, TRUE, 302);
      exit;
    }
  }
}

/**
 * Implementation of hook_user_logout
 *
 * Called from hook_user on logout, most of the code taken from user_logout()
 * and _drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION).
 * D7-changes: this is now an implementation of a hook, so:
 *  - Only do a logout, leave the automatic login to ip_login_boot;
 *  - prevent logging out if needed, just by calling drupal_goto()
 *  - N.B. check user_logout() in user.pages.inc; this is the calling function;
 *  - N.B. check devel_switch_user() in devel.module; here users are switched, too;
 */
function ip_login_user_logout() {

  // prevent recursive call via user_module_invoke() / module_invoke_all() in user.pages.inc
  if (!ip_login_is_possible()) {
    return;
  }
  else {
    $_SESSION[IP_CHECKED] = FALSE;
    $_SESSION[IP_UID_MATCH] = 0;
  }
  global $user;

  // store whether this user can log back in automatically
  $can_login_as_another_user = _ip_login_can_login_as_another_user($user);

  // sets indicator to behaviour in hook_boot().
  $expire = 0;

  // Cookie expires at the end of the session (when the browser closes).
  setcookie(LOGIN_AS_DIFFERENT_USER, $can_login_as_another_user, $expire, '/');
  if (!$can_login_as_another_user) {

    // @todo: it is possible that some other hook_user_logout() has been called already
    // does this generate an undetermined state?
    $message = t(variable_get('ip_login_logged_back_in', 'This account does not have permission to log out once logged in automatically. You have been logged back in.'));
    $message = token_replace($message, array(
      'user' => $user,
    ), array(
      'clear' => TRUE,
    ));
    drupal_set_message($message, 'warning');

    // show the login page
    drupal_goto(variable_get('ip_login_destination', 'user'));
  }
}

/**
 * Compares a single IP quadrant to a matching quadrant.
 *
 * The matching quad can contain wildcards (*), ranges (10-12) or exact numbers
 * @param $find_value
 *    A string containing the quadrant value being looked for
 * @param $in_range
 *    String with a quadrant value, range or wildcard to compare to
 * @return TRUE
 *    If $find_value matches an IP address $in_range
 *
 */
function ip_login_match_quad($find_value, $in_range) {

  // if we've got a wildcard just return TRUE
  if ($in_range == '*') {
    return TRUE;
  }

  // check if this quad contains the range character '-'
  $range = explode('-', $in_range);
  if (isset($range[1])) {

    // we've got a range, test upper and lower bounds
    if ($find_value >= $range[0] && $find_value <= $range[1]) {
      return TRUE;
    }
  }
  else {

    // no range, just do normal match
    return $range[0] == $find_value;
  }
  return FALSE;
}

/*
 * Returns TRUE if a user has permission to log out and back in as another user
 */
function _ip_login_can_login_as_another_user($user) {

  // super user can log in as another user
  if ($user->uid == 1) {
    return TRUE;
  }

  // people who can administer this module can
  if (user_access('administer ip login', $user)) {
    return TRUE;
  }

  // people running from their own machines can

  //if (ip_address() == '127.0.0.1') return TRUE;

  // If the user doesn't have a matching IP, then we let them log in normally
  if (!ip_login_check(ip_address())) {
    return TRUE;
  }

  // all others check correct permission, making sure only TRUE, FALSE is returned
  return user_access('can log in as another user', $user) ? TRUE : FALSE;
}

/**
 * Gets a user's IP range match string by uid
 * @param $uid
 *    The user ID
 * @return
 *    The IP range string for the user if one is found, otherwise NULL.
 *
 */
function _ip_login_get_user_range($uid) {
  if (isset($uid) && is_numeric($uid)) {
    $result = db_query('SELECT * FROM {ip_login_user} WHERE uid = :uid', array(
      ':uid' => $uid,
    ));
    foreach ($result as $record) {
      return $record->ip_match;
    }
  }
  return NULL;
}

/**
 * Sets the IP range match string for a user.
 *
 * If $ip_range is NULL, any IP Login record for this user is removed. Otherwise a row is inserted or updated.
 * @param $uid
 *    The user ID
 * @param $ip_range
 *    IP range match string
 * @return TRUE
 *    If an update occured sucessfully.
 */
function _ip_login_set_user_range($uid, $ip_range = NULL) {
  if (isset($uid) && is_numeric($uid)) {
    if (is_null($ip_range) || empty($ip_range)) {

      // null ip range = delete row
      db_delete('ip_login_user')
        ->condition('uid', $uid)
        ->execute();
    }
    else {
      if (is_null(_ip_login_get_user_range($uid))) {

        // no range presently = insert row
        db_insert('ip_login_user')
          ->fields(array(
          'uid' => $uid,
          'ip_match' => $ip_range,
        ))
          ->execute();
      }
      else {
        db_update('ip_login_user')
          ->fields(array(
          'ip_match' => $ip_range,
        ))
          ->condition('uid', $uid)
          ->execute();
      }
    }
  }
  return FALSE;
}

Functions

Namesort descending Description
ip_login_attempt_login Checks the request IP and logs user in there's a match by calling ip_login_check then ip_login_attempt_login
ip_login_block_info Implementation of hook_block_info
ip_login_block_view Implementation of hook_block_view
ip_login_boot Implementation of hook_boot().
ip_login_check Compares the current request's IP address to the ip_login_user table and then does a proper match for each match on exact, ranges and wildcards
ip_login_check_path Checks path of current page matches any set as options on the admin page to see if IP login should occur. Adapted from core Block module's block_list().
ip_login_form_alter Implementation of hook_form_alter().
ip_login_help Implementation of hook_help().
ip_login_help_ranges Provides help about accepted values of IP ranges etc.
ip_login_is_possible Callback function for hook_menu (menu access)
ip_login_login Performs a login for user with $uid and stores IP Login variables for later
ip_login_match_path Check if a path matches any pattern in a set of patterns. This is a clone of drupal_match_path() found in path.inc because the bootstrap hasn't occurred, so path.inc isn't available.
ip_login_match_quad Compares a single IP quadrant to a matching quadrant.
ip_login_menu Implementation of hook_menu().
ip_login_permission Implementation of hook_permission().
ip_login_user_delete Implements hook_user_delete().
ip_login_user_form_submit
ip_login_user_insert Implements hook_user_insert().
ip_login_user_logout Implementation of hook_user_logout
ip_login_user_update Implements hook_user_update().
_ip_login_can_login_as_another_user
_ip_login_get_user_range Gets a user's IP range match string by uid
_ip_login_set_user_range Sets the IP range match string for a user.
_ip_login_user_form_validate Callback for hook_form_alter().

Constants