Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.50 diff -F^f -u -r1.50 bootstrap.inc --- includes/bootstrap.inc 21 May 2005 11:33:03 -0000 1.50 +++ includes/bootstrap.inc 5 Jun 2005 22:11:41 -0000 @@ -779,6 +779,18 @@ function drupal_get_messages() { return $messages; } +/** + * Perform an access check for a given mask and rule type. Rules are usually created via admin/access/rules page. + * + */ +function drupal_deny($type, $mask) { + $allow = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 1 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask)); + $deny = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 0 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask)); + + return $deny && !$allow; +} + + // Start a page timer: timer_start('page'); @@ -787,6 +799,14 @@ function drupal_get_messages() { include_once "$config/settings.php"; include_once 'includes/database.inc'; + +// deny access to hosts which were banned. t() is not yet available. +if (drupal_deny('ip_address', $_SERVER['REMOTE_ADDR'])) { + header('HTTP/1.0 403 Forbidden'); + // print "Sorry, ". $_SERVER['REMOTE_ADDR']. " has been banned."; + // exit(); +} + include_once 'includes/session.inc'; include_once 'includes/module.inc'; Index: modules/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics.module,v retrieving revision 1.194 diff -F^f -u -r1.194 statistics.module --- modules/statistics.module 31 May 2005 21:14:26 -0000 1.194 +++ modules/statistics.module 5 Jun 2005 22:11:42 -0000 @@ -47,6 +47,8 @@ function statistics_help($section) { return t('

This page shows you the most recent hits.

'); case 'admin/logs/referrers': return t('

This page shows you all external referrers. These are links pointing to your web site from outside your web site.

'); + case 'admin/logs/visitors': + return t('

When you ban a visitor, you prevent his IP address from accessing your site. Unlike blocking a user, banning a visitor works even for anonymous users. The most common use for this is to block bots/web crawlers that are consuming too many resources.

'); } } @@ -281,18 +283,21 @@ function statistics_top_visitors() { array('data' => t('Hits'), 'field' => 'hits', 'sort' => 'desc'), array('data' => t('Visitor'), 'field' => 'u.name'), array('data' => t('Total page generation time'), 'field' => 'total'), + array('data' => t('Operations')) ); - $sql = "SELECT COUNT(a.uid) AS hits, a.uid, u.name, a.hostname, SUM(a.timer) AS total FROM {accesslog} a LEFT JOIN {users} u ON a.uid = u.uid GROUP BY a.hostname". tablesort_sql($header); + $sql = "SELECT COUNT(a.uid) AS hits, a.uid, u.name, a.hostname, SUM(a.timer) AS total, ac.aid FROM {accesslog} a LEFT JOIN {access} ac ON a.hostname = ac.mask LEFT JOIN {users} u ON a.uid = u.uid GROUP BY a.hostname". tablesort_sql($header); $sql_cnt = "SELECT COUNT(DISTINCT(uid)) FROM {accesslog}"; $result = pager_query($sql, 30, 0, $sql_cnt); while ($account = db_fetch_object($result)) { - $rows[] = array($account->hits, ($account->uid ? format_name($account) : $account->hostname), format_interval(round($account->total / 1000))); + $qs = "edit[mask]=$account->hostname&edit[type]=ip_address"; + $ban_link = $account->aid ? l(t('unban'), "admin/access/rules/delete/$account->aid", array(), $qs) : l(t('ban'), 'admin/access/rules/add', array(), $qs); + $rows[] = array($account->hits, ($account->uid ? format_name($account) : $account->hostname), format_interval(round($account->total / 1000)), $ban_link); } if ($pager = theme('pager', NULL, 30, 0, tablesort_pager())) { - $rows[] = array(array('data' => $pager, 'colspan' => '3')); + $rows[] = array(array('data' => $pager, 'colspan' => '4')); } drupal_set_title(t('Top visitors in the past %interval', array('%interval' => format_interval(variable_get('statistics_flush_accesslog_timer', 259200))))); @@ -388,6 +393,7 @@ function statistics_title_list($dbfield, return db_query_range(db_rewrite_sql("SELECT n.nid, n.title, u.uid, u.name FROM {node_counter} s INNER JOIN {node} n ON s.nid = n.nid INNER JOIN {users} u ON n.uid = u.uid WHERE %s <> '0' AND n.status = 1 ORDER BY %s DESC"), 's.'. $dbfield, 's.'. $dbfield, 0, $dbrows); } + /** * Retrieves a node's "view statistics". * Index: modules/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user.module,v retrieving revision 1.478 diff -F^f -u -r1.478 user.module --- modules/user.module 1 Jun 2005 20:21:35 -0000 1.478 +++ modules/user.module 5 Jun 2005 22:11:44 -0000 @@ -376,13 +376,6 @@ function user_mail($mail, $subject, $mes } } -function user_deny($type, $mask) { - $allow = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 1 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask)); - $deny = db_fetch_object(db_query("SELECT * FROM {access} WHERE status = 0 AND type = '%s' AND LOWER('%s') LIKE LOWER(mask)", $type, $mask)); - - return $deny && !$allow; -} - function user_fields() { static $fields; @@ -805,7 +798,7 @@ function user_login($edit = array(), $ms drupal_goto('user'); } - if (user_deny('user', $edit['name'])) { + if (drupal_deny('user', $edit['name'])) { $error = t('The name %s has been denied access.', array('%s' => theme('placeholder', $edit['name']))); } else if ($edit['name'] && $edit['pass']) { @@ -1123,7 +1116,7 @@ function user_edit_validate($uid, &$edit else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['name'])) > 0) { form_set_error('name', t('The name %name is already taken.', array('%name' => theme('placeholder', $edit['name'])))); } - else if (user_deny('user', $edit['name'])) { + else if (drupal_deny('user', $edit['name'])) { form_set_error('name', t('The name %name has been denied access.', array('%name' => theme('placeholder', $edit['name'])))); } @@ -1134,7 +1127,7 @@ function user_edit_validate($uid, &$edit else if (db_num_rows(db_query("SELECT uid FROM {users} WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $uid, $edit['mail'])) > 0) { form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => theme('placeholder', $edit['mail'])))); } - else if (user_deny('mail', $edit['mail'])) { + else if (drupal_deny('mail', $edit['mail'])) { form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => theme('placeholder', $edit['mail'])))); } @@ -1391,7 +1384,7 @@ function user_admin_access_check() { $edit = $_POST['edit']; if ($op) { - if (user_deny($edit['type'], $edit['test'])) { + if (drupal_deny($edit['type'], $edit['test'])) { drupal_set_message(t('%test is not allowed.', array('%test' => theme('placeholder', $edit['test'])))); } else { @@ -1428,7 +1421,7 @@ function user_admin_access_add() { } } - $form = _user_admin_access_form($edit); + $form = _user_admin_access_form($_REQUEST['edit']); $form .= form_submit(t('Add rule')); return form($form, 'post', NULL, array('id' => 'access-rules')); @@ -1482,7 +1475,7 @@ function user_admin_access_edit($aid = 0 function _user_admin_access_form($edit) { $output = '
'. form_radios(t('Access type'), 'status', $edit['status'], array('1' => t('Allow'), '0' => t('Deny'))) .'
'; - $output .= '
'. form_radios(t('Rule type'), 'type', $edit['type'] ? $edit['type'] : 'user', array('user' => t('Username'), 'mail' => t('E-mail'))) .'
'; + $output .= '
'. form_radios(t('Rule type'), 'type', $edit['type'] ? $edit['type'] : 'user', array('user' => t('Username'), 'mail' => t('E-mail'), 'ip_address' => t('IP address'))) .'
'; $output .= '
'. form_textfield(t('Mask'), 'mask', $edit['mask'], 32, 64, '%: '. t('Matches any number of characters, even zero characters') .'.
_: '. t('Matches exactly one character.'), NULL, TRUE) .'
'; return $output; @@ -1494,7 +1487,7 @@ function _user_admin_access_form($edit) function user_admin_access() { $header = array(array('data' => t('Access type'), 'field' => 'status'), array('data' => t('Rule type'), 'field' => 'type'), array('data' =>t('Mask'), 'field' => 'mask'), array('data' => t('Operations'), 'colspan' => 2)); $result = db_query("SELECT aid, type, status, mask FROM {access}". tablesort_sql($header)); - $access_types = array('user' => t('username'), 'mail' => t('e-mail')); + $access_types = array('user' => t('username'), 'mail' => t('e-mail'), 'ip_address' => t('IP address')); $rows = array(); while ($rule = db_fetch_object($result)) { $rows[] = array($rule->status ? t('allow') : t('deny'), $access_types[$rule->type], $rule->mask, l(t('edit'), 'admin/access/rules/edit/'. $rule->aid), l(t('delete'), 'admin/access/rules/delete/'. $rule->aid)); @@ -1751,8 +1744,8 @@ function user_help($section) { case 'admin/user/create': case 'admin/user/account/create': return t('

This web page allows the administrators to register a new users by hand. Note that you cannot have a user where either the e-mail address or the username match another user in the system.

'); - case 'admin/access/rules': - return t('

Set up username and e-mail address access rules for new accounts. If a username or email address for a new account matches any deny rule, but not an allow rule, then the new account will not be allowed to be created.

'); + case strstr($section, 'admin/access/rules'): + return t('

Set up username and e-mail address access rules for new accounts. If a username or email address for a new account matches any deny rule, but not an allow rule, then the new account will not be allowed to be created. An IP address rule is effective for every page view, not just registrations.

'); case 'admin/access': return t('

In this area you will define the permissions for each user role (role names are defined on the user roles page). Each permission describes a fine-grained logical operation, such as being able to access the administration pages, or adding/modifying a user account. You could say a permission represents access granted to a user to perform a set of operations.

', array('%role' => url('admin/access/roles'))); case 'admin/access/roles':