home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Writing Apache Modules with Perl and C
By:   Lincoln Stein and Doug MacEachern
Published:   O'Reilly & Associates, Inc.  - March 1999

Copyright © 1999 by O'Reilly & Associates, Inc.


 


   Show Contents   Previous Page   Next Page

Chapter 9 - Perl API Reference Guide / The Apache Request Object
Access Control Methods

The Apache API provides several methods that are used for access control, authentication, and authorization. We gave complete examples of using these methods in Chapter 6.

allow_options()

The allow_options() method gives module writers access to the per-directory Options configuration. It returns a bitmap in which a bit is set to 1 if the corresponding option is enabled. The Apache::Constants module provides symbolic constants for the various options when you import the tab :options. You will typically perform a bitwise AND (&) on the options bitmap to check which ones are enabled.

For example, a script engine such as Apache::Registry or Apache::SSI might want to check if it's allowed to execute a script in the current location using this code:

use Apache::Constants qw(:common :options);
unless($r->allow_options & OPT_EXECCGI) {
   $r->log_reason("Options ExecCGI is off in this directory",
                  $r->filename);
   return FORBIDDEN;
}

A full list of option constants can be found in the Apache::Constants manual page.

auth_name()

This method will return the current value of the per-directory configuration directive AuthName, which is used in conjunction with password-protected directories. AuthName declares an authorization "realm," which is intended as a high-level grouping of an authentication scheme and a URI tree to which it applies.

If the requested file or directory is password-protected, auth_name() will return the realm name. An authentication module can then use this realm name to determine which database to authenticate the user against. This method can also be used to set the value of the realm for use by later handlers.

my $auth_name = $r->auth_name();
$r->auth_name("Protected Area");

auth_type()

Password-protected files and directories will also have an authorization type, which is usually one of "Basic" or "Digest." The authorization type is set with the configuration directive AuthType and retrieved with the API method auth_type(). Here's an example from a hypothetical authentication handler that can only authenticate using the Basic method:

my $auth_type = $r->auth_type;
unless (lc($auth_type) eq "basic") {
   $r->warn(__PACKAGE__, " can't handle AuthType $auth_type");
   return DECLINED;
}

The differences between Basic and Digest authentication are discussed in Chapter 6.

get_basic_auth_pw()

The get_basic_auth_pw() method returns a two-element list. If the current request is protected with Basic authentication, the first element of the returned list will be OK and the second will be the plaintext password entered by the user. Other possible return codes include DECLINED, SERVER_ERROR, and AUTH_REQUIRED, which are described in Chapter 6.

my($ret, $sent_pw) = $r->get_basic_auth_pw;

You can get the username part of the pair by calling $r->connection->user as described in the section "The Apache::Connection Class."

note_basic_auth_failure()

If a URI is protected by Basic authentication and the browser fails to provide a valid username/password combination (or none at all), authentication handlers are expected to call the note_basic_auth_failure() method. This sets up the outgoing HTTP headers in such a way that users will be (re)challenged to provide their usernames and passwords for the current security realm.

my($ret, $sent_pw) = $r->get_basic_auth_pw;
unless($r->connection->user and $sent_pw) {
   $r->note_basic_auth_failure;
   $r->log_reason("Both a username and password must be provided");
   return AUTH_REQUIRED;
}

Although it would make sense for note_basic_auth_failure() to return a status code of AUTH_REQUIRED, it actually returns no value.

requires()

This method returns information about each of the require directives currently in force for the requested URI. Since there may be many require directives, this method returns an array reference. Each item in the array is a hash that contains information about a different require directive. The format of this data structure is described in detail in Chapter 6, under "A Gender-Based Authorization Module."

satisfies()

Documents can be under access control (e.g., access limited by hostname or password) and authentication/authorization control (password protection) simultaneously. The Satisfy directive determines how Apache combines the two types of restriction. If Satisfy All is specified, Apache will not grant access to the requested document unless both the access control and authentication/authorization rules are satisfied. If Satisfy Any is specified, remote users are allowed to retrieve the document if they meet the requirements of either one of the restrictions.

Authorization and access control modules gain access to this configuration variable through the satisfies() method. It will return one of the three constants SATISFY_ALL, SATISFY_ANY, or SATISFY_NOSPEC. The latter is returned when there is no applicable satisfy directive at all. These constants can be imported by requesting the :satisfy tag from Apache::Constants.

The following code fragment illustrates an access control handler that checks the status of the satisfy directive. If the current document is forbidden by access control rules, the code checks whether SATISFY_ANY is in effect and, if so, whether authentication is also required (using the some_auth_required() method call described next). Unless both of these conditions are true, the handler logs an error message. Otherwise, it just returns the result code, knowing that any error logging will be performed by the authentication handler.

 use Apache::Constants qw(:common :satisfy);
 if ($ret == FORBIDDEN) {
    $r->log_reason("Client access denied by server configuration")
        unless $r->satisfies == SATISFY_ANY && $r->some_auth_required;
    return $ret;
}

some_auth_required()

If the configuration for the current request requires some form of authentication or authorization, this method returns true. Otherwise, it returns an undef value.

unless ($r->some_auth_required) {
   $r->log_reason("I won't go further unless the user is authenticated");
   return FORBIDDEN;
}
   Show Contents   Previous Page   Next Page
Copyright © 1999 by O'Reilly & Associates, Inc.