From ee56b6fd387d3d099324495132b2df23ff5ba36b Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@unknown> Date: Tue, 11 Jun 2002 05:33:07 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'APACHE_2_0_37'. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/tags/2.0.37@95607 13f79535-47bb-0310-9956-ffa450edef68 --- docs/manual/content-negotiation.html.en | 622 ----------- docs/manual/developer/modules.html.en | 258 ----- docs/manual/dso.html.en | 344 ------ docs/manual/invoking.html.en | 139 --- docs/manual/logs.html.en | 666 ------------ docs/manual/mod/directive-dict.html.en | 327 ------ docs/manual/mod/module-dict.html.en | 123 --- docs/manual/sitemap.html.en | 201 ---- docs/manual/stopping.html.en | 209 ---- docs/manual/urlmapping.html.en | 296 ------ docs/manual/vhosts/fd-limits.html.en | 73 -- docs/manual/vhosts/index.html.en | 84 -- docs/manual/vhosts/name-based.html.en | 231 ---- modules/experimental/mod_auth_ldap.c | 866 --------------- modules/experimental/mod_auth_ldap.def | 6 - modules/experimental/util_ldap.c | 1110 -------------------- modules/experimental/util_ldap.def | 6 - modules/experimental/util_ldap_cache.c | 321 ------ modules/experimental/util_ldap_cache.h | 216 ---- modules/experimental/util_ldap_cache_mgr.c | 538 ---------- support/dbmmanage | 350 ------ support/log_server_status | 114 -- support/logresolve.pl | 261 ----- support/phf_abuse_log.cgi | 22 - support/split-logfile | 98 -- 25 files changed, 7481 deletions(-) delete mode 100644 docs/manual/content-negotiation.html.en delete mode 100644 docs/manual/developer/modules.html.en delete mode 100644 docs/manual/dso.html.en delete mode 100644 docs/manual/invoking.html.en delete mode 100644 docs/manual/logs.html.en delete mode 100644 docs/manual/mod/directive-dict.html.en delete mode 100644 docs/manual/mod/module-dict.html.en delete mode 100644 docs/manual/sitemap.html.en delete mode 100644 docs/manual/stopping.html.en delete mode 100755 docs/manual/urlmapping.html.en delete mode 100644 docs/manual/vhosts/fd-limits.html.en delete mode 100644 docs/manual/vhosts/index.html.en delete mode 100644 docs/manual/vhosts/name-based.html.en delete mode 100644 modules/experimental/mod_auth_ldap.c delete mode 100644 modules/experimental/mod_auth_ldap.def delete mode 100644 modules/experimental/util_ldap.c delete mode 100644 modules/experimental/util_ldap.def delete mode 100644 modules/experimental/util_ldap_cache.c delete mode 100644 modules/experimental/util_ldap_cache.h delete mode 100644 modules/experimental/util_ldap_cache_mgr.c delete mode 100644 support/dbmmanage delete mode 100644 support/log_server_status delete mode 100644 support/logresolve.pl delete mode 100644 support/phf_abuse_log.cgi delete mode 100644 support/split-logfile diff --git a/docs/manual/content-negotiation.html.en b/docs/manual/content-negotiation.html.en deleted file mode 100644 index 8e6f68c6911..00000000000 --- a/docs/manual/content-negotiation.html.en +++ /dev/null @@ -1,622 +0,0 @@ - - - - - - - Apache Content Negotiation - - - - - - -

Content Negotiation

- -

Apache's supports content negotiation as described in - the HTTP/1.1 specification. It can choose the best - representation of a resource based on the browser-supplied - preferences for media type, languages, character set and - encoding. It also implements a couple of features to give - more intelligent handling of requests from browsers that send - incomplete negotiation information.

- -

Content negotiation is provided by the mod_negotiation module, - which is compiled in by default.

-
- -

About Content Negotiation

- -

A resource may be available in several different - representations. For example, it might be available in - different languages or different media types, or a combination. - One way of selecting the most appropriate choice is to give the - user an index page, and let them select. However it is often - possible for the server to choose automatically. This works - because browsers can send as part of each request information - about what representations they prefer. For example, a browser - could indicate that it would like to see information in French, - if possible, else English will do. Browsers indicate their - preferences by headers in the request. To request only French - representations, the browser would send

-
-  Accept-Language: fr
-
- -

Note that this preference will only be applied when there is - a choice of representations and they vary by language.

- -

As an example of a more complex request, this browser has - been configured to accept French and English, but prefer - French, and to accept various media types, preferring HTML over - plain text or other text types, and preferring GIF or JPEG over - other media types, but also allowing any other media type as a - last resort:

-
-  Accept-Language: fr; q=1.0, en; q=0.5
-  Accept: text/html; q=1.0, text/*; q=0.8, image/gif; q=0.6,
-        image/jpeg; q=0.6, image/*; q=0.5, */*; q=0.1
-
- Apache supports 'server driven' content negotiation, as - defined in the HTTP/1.1 specification. It fully supports the - Accept, Accept-Language, Accept-Charset and Accept-Encoding - request headers. Apache also supports 'transparent' - content negotiation, which is an experimental negotiation - protocol defined in RFC 2295 and RFC 2296. It does not offer - support for 'feature negotiation' as defined in these RFCs. - -

A resource is a conceptual entity - identified by a URI (RFC 2396). An HTTP server like Apache - provides access to representations of the - resource(s) within its namespace, with each representation in - the form of a sequence of bytes with a defined media type, - character set, encoding, etc. Each resource may be associated - with zero, one, or more than one representation at any given - time. If multiple representations are available, the resource - is referred to as negotiable and each of its - representations is termed a variant. The ways - in which the variants for a negotiable resource vary are called - the dimensions of negotiation.

- -

Negotiation in Apache

- -

In order to negotiate a resource, the server needs to be - given information about each of the variants. This is done in - one of two ways:

- - - -

Using a type-map file

- -

A type map is a document which is associated with the - handler named type-map (or, for - backwards-compatibility with older Apache configurations, the - mime type application/x-type-map). Note that to - use this feature, you must have a handler set in the - configuration that defines a file suffix as - type-map; this is best done with a

-
-  AddHandler type-map .var
-
- in the server configuration file. - -

Type map files should have the same name as the resource - which they are describing, and have an entry for each available - variant; these entries consist of contiguous HTTP-format header - lines. Entries for different variants are separated by blank - lines. Blank lines are illegal within an entry. It is - conventional to begin a map file with an entry for the combined - entity as a whole (although this is not required, and if - present will be ignored). An example map file is shown below. - This file would be named foo.html, as it describes - a resource named foo.

-
-  URI: foo
-
-  URI: foo.en.html
-  Content-type: text/html
-  Content-language: en
-
-  URI: foo.fr.de.html
-  Content-type: text/html;charset=iso-8859-2
-  Content-language: fr, de
-
- Note also that a typemap file will take precedence over the - filename's extension, even when Multiviews is on. If the - variants have different source qualities, that may be indicated - by the "qs" parameter to the media type, as in this picture - (available as jpeg, gif, or ASCII-art): -
-  URI: foo
-
-  URI: foo.jpeg
-  Content-type: image/jpeg; qs=0.8
-
-  URI: foo.gif
-  Content-type: image/gif; qs=0.5
-
-  URI: foo.txt
-  Content-type: text/plain; qs=0.01
-
- -

qs values can vary in the range 0.000 to 1.000. Note that - any variant with a qs value of 0.000 will never be chosen. - Variants with no 'qs' parameter value are given a qs factor of - 1.0. The qs parameter indicates the relative 'quality' of this - variant compared to the other available variants, independent - of the client's capabilities. For example, a jpeg file is - usually of higher source quality than an ascii file if it is - attempting to represent a photograph. However, if the resource - being represented is an original ascii art, then an ascii - representation would have a higher source quality than a jpeg - representation. A qs value is therefore specific to a given - variant depending on the nature of the resource it - represents.

- -

The full list of headers recognized is available in the mod_negotation - documentation.

- - -

Multiviews

- -

MultiViews is a per-directory option, meaning - it can be set with an Options directive within a - <Directory>, <Location> - or <Files> section in - access.conf, or (if AllowOverride is - properly set) in .htaccess files. Note that - Options All does not set MultiViews; - you have to ask for it by name.

- -

The effect of MultiViews is as follows: if the - server receives a request for /some/dir/foo, if - /some/dir has MultiViews enabled, and - /some/dir/foo does not exist, then the - server reads the directory looking for files named foo.*, and - effectively fakes up a type map which names all those files, - assigning them the same media types and content-encodings it - would have if the client had asked for one of them by name. It - then chooses the best match to the client's requirements.

- -

MultiViews may also apply to searches for the - file named by the DirectoryIndex directive, if the - server is trying to index a directory. If the configuration - files specify

-
-  DirectoryIndex index
-
- then the server will arbitrate between index.html - and index.html3 if both are present. If neither - are present, and index.cgi is there, the server - will run it. - -

If one of the files found when reading the directory does not - have an extension recognized by mod_mime to designate - its Charset, Content-Type, Language, or Encoding, then the result - depends on the setting of the MultiViewsMatch - directive. This directive determines whether handlers, filters, - and other extension types can participate in MultiViews - negotiation.

- -

The Negotiation Methods

- After Apache has obtained a list of the variants for a given - resource, either from a type-map file or from the filenames in - the directory, it invokes one of two methods to decide on the - 'best' variant to return, if any. It is not necessary to know - any of the details of how negotiation actually takes place in - order to use Apache's content negotiation features. However the - rest of this document explains the methods used for those - interested. - -

There are two negotiation methods:

- -
    -
  1. Server driven negotiation with the Apache - algorithm is used in the normal case. The Apache - algorithm is explained in more detail below. When this - algorithm is used, Apache can sometimes 'fiddle' the quality - factor of a particular dimension to achieve a better result. - The ways Apache can fiddle quality factors is explained in - more detail below.
  2. - -
  3. Transparent content negotiation is used - when the browser specifically requests this through the - mechanism defined in RFC 2295. This negotiation method gives - the browser full control over deciding on the 'best' variant, - the result is therefore dependent on the specific algorithms - used by the browser. As part of the transparent negotiation - process, the browser can ask Apache to run the 'remote - variant selection algorithm' defined in RFC 2296.
  4. -
- -

Dimensions of Negotiation

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DimensionNotes
Media TypeBrowser indicates preferences with the Accept header - field. Each item can have an associated quality factor. - Variant description can also have a quality factor (the - "qs" parameter).
LanguageBrowser indicates preferences with the Accept-Language - header field. Each item can have a quality factor. Variants - can be associated with none, one or more than one - language.
EncodingBrowser indicates preference with the Accept-Encoding - header field. Each item can have a quality factor.
CharsetBrowser indicates preference with the Accept-Charset - header field. Each item can have a quality factor. Variants - can indicate a charset as a parameter of the media - type.
- -

Apache Negotiation Algorithm

- -

Apache can use the following algorithm to select the 'best' - variant (if any) to return to the browser. This algorithm is - not further configurable. It operates as follows:

- -
    -
  1. First, for each dimension of the negotiation, check the - appropriate Accept* header field and assign a - quality to each variant. If the Accept* header for - any dimension implies that this variant is not acceptable, - eliminate it. If no variants remain, go to step 4.
  2. - -
  3. - Select the 'best' variant by a process of elimination. Each - of the following tests is applied in order. Any variants - not selected at each test are eliminated. After each test, - if only one variant remains, select it as the best match - and proceed to step 3. If more than one variant remains, - move on to the next test. - -
      -
    1. Multiply the quality factor from the Accept header - with the quality-of-source factor for this variant's - media type, and select the variants with the highest - value.
    2. - -
    3. Select the variants with the highest language quality - factor.
    4. - -
    5. Select the variants with the best language match, - using either the order of languages in the - Accept-Language header (if present), or else the order of - languages in the LanguagePriority directive - (if present).
    6. - -
    7. Select the variants with the highest 'level' media - parameter (used to give the version of text/html media - types).
    8. - -
    9. Select variants with the best charset media - parameters, as given on the Accept-Charset header line. - Charset ISO-8859-1 is acceptable unless explicitly - excluded. Variants with a text/* media type - but not explicitly associated with a particular charset - are assumed to be in ISO-8859-1.
    10. - -
    11. Select those variants which have associated charset - media parameters that are not ISO-8859-1. If - there are no such variants, select all variants - instead.
    12. - -
    13. Select the variants with the best encoding. If there - are variants with an encoding that is acceptable to the - user-agent, select only these variants. Otherwise if - there is a mix of encoded and non-encoded variants, - select only the unencoded variants. If either all - variants are encoded or all variants are not encoded, - select all variants.
    14. - -
    15. Select the variants with the smallest content - length.
    16. - -
    17. Select the first variant of those remaining. This - will be either the first listed in the type-map file, or - when variants are read from the directory, the one whose - file name comes first when sorted using ASCII code - order.
    18. -
    -
  4. - -
  5. The algorithm has now selected one 'best' variant, so - return it as the response. The HTTP response header Vary is - set to indicate the dimensions of negotiation (browsers and - caches can use this information when caching the resource). - End.
  6. - -
  7. To get here means no variant was selected (because none - are acceptable to the browser). Return a 406 status (meaning - "No acceptable representation") with a response body - consisting of an HTML document listing the available - variants. Also set the HTTP Vary header to indicate the - dimensions of variance.
  8. -
- -

Fiddling with Quality - Values

- -

Apache sometimes changes the quality values from what would - be expected by a strict interpretation of the Apache - negotiation algorithm above. This is to get a better result - from the algorithm for browsers which do not send full or - accurate information. Some of the most popular browsers send - Accept header information which would otherwise result in the - selection of the wrong variant in many cases. If a browser - sends full and correct information these fiddles will not be - applied.

- -

Media Types and Wildcards

- -

The Accept: request header indicates preferences for media - types. It can also include 'wildcard' media types, such as - "image/*" or "*/*" where the * matches any string. So a request - including:

-
-  Accept: image/*, */*
-
- would indicate that any type starting "image/" is acceptable, - as is any other type (so the first "image/*" is redundant). - Some browsers routinely send wildcards in addition to explicit - types they can handle. For example: -
-  Accept: text/html, text/plain, image/gif, image/jpeg, */*
-
- The intention of this is to indicate that the explicitly listed - types are preferred, but if a different representation is - available, that is ok too. However under the basic algorithm, - as given above, the */* wildcard has exactly equal preference - to all the other types, so they are not being preferred. The - browser should really have sent a request with a lower quality - (preference) value for *.*, such as: -
-  Accept: text/html, text/plain, image/gif, image/jpeg, */*; q=0.01
-
- The explicit types have no quality factor, so they default to a - preference of 1.0 (the highest). The wildcard */* is given a - low preference of 0.01, so other types will only be returned if - no variant matches an explicitly listed type. - -

If the Accept: header contains no q factors at all, - Apache sets the q value of "*/*", if present, to 0.01 to - emulate the desired behavior. It also sets the q value of - wildcards of the format "type/*" to 0.02 (so these are - preferred over matches against "*/*". If any media type on the - Accept: header contains a q factor, these special values are - not applied, so requests from browsers which send the - correct information to start with work as expected.

- -

Language Negotiation Exceptions

- -

New in Apache 2.0, some exceptions have been added to the - negotiation algorithm to allow graceful fallback when language - negotiation fails to find a match.

- -

When a client requests a page on your server, but the server - cannot find a single page that matches the Accept-language sent by - the browser, the server will return either a "No Acceptable - Variant" or "Multiple Choices" response to the client. To avoid - these error messages, it is possible to configure Apache to ignore - the Accept-language in these cases and provide a document that - does not explictly match the client's request. The ForceLanguagePriority - directive can be used to override one or both of these error - messages and subsitute the servers judgement in the form of the LanguagePriority - directive.

- -

The server will also attempt to match language-subsets when no - other match can be found. For example, if a client requests - documents with the language en-GB for British - English, the server is not normally allowed by the HTTP/1.1 - standard to match that against a document that is marked as simply - en. (Note that it is almost surely a configuration - error to include en-GB and not en in the - Accept-Language header, since it is very unlikely that a reader - understands British English, but doesn't understand English in - general. Unfortunately, many current clients have default - configurations that resemble this.) However, if no other language - match is possible and the server is about to return a "No - Acceptable Variants" error or fallback to the - LanguagePriority, the server will ignore the subset - specification and match en-GB against en - documents. Implicitly, Apache will add the parent language to - the client's acceptable language list with a very low quality - value. But note that if the client requests "en-GB; qs=0.9, fr; - qs=0.8", and the server has documents designated "en" and "fr", - then the "fr" document will be returned. This is necessary to - maintain compliance with the HTTP/1.1 specification and to work - effectively with properly configured clients.

- - -

Extensions to Transparent Content Negotiation

- Apache extends the transparent content negotiation protocol - (RFC 2295) as follows. A new {encoding ..} element - is used in variant lists to label variants which are available - with a specific content-encoding only. The implementation of - the RVSA/1.0 algorithm (RFC 2296) is extended to recognize - encoded variants in the list, and to use them as candidate - variants whenever their encodings are acceptable according to - the Accept-Encoding request header. The RVSA/1.0 implementation - does not round computed quality factors to 5 decimal places - before choosing the best variant. - -

Note on hyperlinks and naming conventions

- -

If you are using language negotiation you can choose between - different naming conventions, because files can have more than - one extension, and the order of the extensions is normally - irrelevant (see the mod_mime documentation - for details).

- -

A typical file has a MIME-type extension (e.g., - html), maybe an encoding extension (e.g., - gz), and of course a language extension - (e.g., en) when we have different - language variants of this file.

- -

Examples:

- - - -

Here some more examples of filenames together with valid and - invalid hyperlinks:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FilenameValid hyperlinkInvalid hyperlink
foo.html.enfoo
- foo.html
-
foo.en.htmlfoofoo.html
foo.html.en.gzfoo
- foo.html
foo.gz
- foo.html.gz
foo.en.html.gzfoofoo.html
- foo.html.gz
- foo.gz
foo.gz.html.enfoo
- foo.gz
- foo.gz.html
foo.html
foo.html.gz.enfoo
- foo.html
- foo.html.gz
foo.gz
- -

Looking at the table above you will notice that it is always - possible to use the name without any extensions in an hyperlink - (e.g., foo). The advantage is that you - can hide the actual type of a document rsp. file and can change - it later, e.g., from html to - shtml or cgi without changing any - hyperlink references.

- -

If you want to continue to use a MIME-type in your - hyperlinks (e.g. foo.html) the language - extension (including an encoding extension if there is one) - must be on the right hand side of the MIME-type extension - (e.g., foo.html.en).

- -

Note on Caching

- -

When a cache stores a representation, it associates it with - the request URL. The next time that URL is requested, the cache - can use the stored representation. But, if the resource is - negotiable at the server, this might result in only the first - requested variant being cached and subsequent cache hits might - return the wrong response. To prevent this, Apache normally - marks all responses that are returned after content negotiation - as non-cacheable by HTTP/1.0 clients. Apache also supports the - HTTP/1.1 protocol features to allow caching of negotiated - responses.

- -

For requests which come from a HTTP/1.0 compliant client - (either a browser or a cache), the directive - CacheNegotiatedDocs can be used to allow caching of - responses which were subject to negotiation. This directive can - be given in the server config or virtual host, and takes no - arguments. It has no effect on requests from HTTP/1.1 clients. - -

More Information

- -

For more information about content negotiation, see Alan - J. Flavell's Language - Negotiation Notes. But note that this document may not be - updated to include changes in Apache 2.0.

- - - - - diff --git a/docs/manual/developer/modules.html.en b/docs/manual/developer/modules.html.en deleted file mode 100644 index ebf7c33da20..00000000000 --- a/docs/manual/developer/modules.html.en +++ /dev/null @@ -1,258 +0,0 @@ - - - - - - - Converting Modules from Apache 1.3 to Apache 2.0 - - - - - - -

From Apache 1.3 to Apache 2.0
- Modules

- -

This is a first attempt at writing the lessons I learned - when trying to convert the mod_mmap_static module to Apache - 2.0. It's by no means definitive and probably won't even be - correct in some ways, but it's a start.

-
- -

The easier changes...

- -

Cleanup Routines

- -

These now need to be of type apr_status_t and return a value - of that type. Normally the return value will be APR_SUCCESS - unless there is some need to signal an error in the cleanup. Be - aware that even though you signal an error not all code yet - checks and acts upon the error.

- -

Initialisation Routines

- -

These should now be renamed to better signify where they sit - in the overall process. So the name gets a small change from - mmap_init to mmap_post_config. The arguments passed have - undergone a radical change and now look like

- - - -

Data Types

- -

A lot of the data types have been moved into the APR. This - means that some have had a name change, such as the one shown - above. The following is a brief list of some of the changes - that you are likely to have to make.

- - -
- -

The messier changes...

- -

Register Hooks

- -

The new architecture uses a series of hooks to provide for - calling your functions. These you'll need to add to your module - by way of a new function, static void register_hooks(void). The - function is really reasonably straightforward once you - understand what needs to be done. Each function that needs - calling at some stage in the processing of a request needs to - be registered, handlers do not. There are a number of phases - where functions can be added, and for each you can specify with - a high degree of control the relative order that the function - will be called in.

- -

This is the code that was added to mod_mmap_static:

-
-static void register_hooks(void)
-{
-    static const char * const aszPre[]={ "http_core.c",NULL };
-    ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE);
-    ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST);
-};
-
- -

This registers 2 functions that need to be called, one in - the post_config stage (virtually every module will need this - one) and one for the translate_name phase. note that while - there are different function names the format of each is - identical. So what is the format?

- -

ap_hook_[phase_name](function_name, predecessors, - successors, position);

- -

There are 3 hook positions defined...

- - - -

To define the position you use the position and then modify - it with the predecessors and successors. each of the modifiers - can be a list of functions that should be called, either before - the function is run (predecessors) or after the function has - run (successors).

- -

In the mod_mmap_static case I didn't care about the - post_config stage, but the mmap_static_xlat MUST be called - after the core module had done it's name translation, hence the - use of the aszPre to define a modifier to the position - HOOK_LAST.

- -

Module Definition

- -

There are now a lot fewer stages to worry about when - creating your module definition. The old defintion looked - like

-
-module MODULE_VAR_EXPORT [module_name]_module =
-{
-    STANDARD_MODULE_STUFF,
-    /* initializer */
-    /* dir config creater */
-    /* dir merger --- default is to override */
-    /* server config */
-    /* merge server config */
-    /* command handlers */
-    /* handlers */
-    /* filename translation */
-    /* check_user_id */
-    /* check auth */
-    /* check access */
-    /* type_checker */
-    /* fixups */
-    /* logger */
-    /* header parser */
-    /* child_init */
-    /* child_exit */
-    /* post read-request */
-};
-
- -

The new structure is a great deal simpler...

-
-module MODULE_VAR_EXPORT [module_name]_module =
-{
-    STANDARD20_MODULE_STUFF,
-    /* create per-directory config structures */
-    /* merge per-directory config structures  */
-    /* create per-server config structures    */
-    /* merge per-server config structures     */
-    /* command handlers */
-    /* handlers */
-    /* register hooks */
- };
-
- -

Some of these read directly across, some don't. I'll try to - summarise what should be done below.

- -

The stages that read directly across :

- - - -

The remainder of the old functions should be registered as - hooks. There are the following hook stages defined so - far...

- - - - - diff --git a/docs/manual/dso.html.en b/docs/manual/dso.html.en deleted file mode 100644 index 41d965d6710..00000000000 --- a/docs/manual/dso.html.en +++ /dev/null @@ -1,344 +0,0 @@ - - - - - - - Dynamic Shared Object (DSO) support - - - - - - -

Dynamic Shared Object (DSO) Support

- -

The Apache HTTP Server is a modular program where the - administrator can choose the functionality to include in the - server by selecting a set of modules. The modules can be - statically compiled into the httpd binary when the - server is built. Alternatively, modules can be compiled as - Dynamic Shared Objects (DSOs) that exist separately from the - main httpd binary file. DSO modules may be - compiled at the time the server is built, or they may be - compiled and added at a later time using the Apache Extension - Tool (apxs).

- -

This document describes how to use DSO modules as well as - the theory behind their use.

- - -
- - - - - - - -
Related Modules
-
- mod_so
-
Related Directives
-
- LoadModule
-
- -

Implementation

- -

The DSO support for loading individual Apache modules is - based on a module named mod_so.c which must be - statically compiled into the Apache core. It is the only module - besides core.c which cannot be put into a DSO - itself. Practically all other distributed Apache modules - can then be placed into a DSO by individually enabling the DSO - build for them via configure's - --enable-module=shared option as disucussed - in the install documentation. After - a module is compiled into a DSO named mod_foo.so - you can use mod_so's - LoadModule - command in your httpd.conf file to load this - module at server startup or restart.

- -

To simplify this creation of DSO files for Apache modules - (especially for third-party modules) a new support program - named apxs (APache - eXtenSion) is available. It can be used to build DSO based - modules outside of the Apache source tree. The idea is - simple: When installing Apache the configure's - make install procedure installs the Apache C - header files and puts the platform-dependent compiler and - linker flags for building DSO files into the apxs - program. This way the user can use apxs to compile - his Apache module sources without the Apache distribution - source tree and without having to fiddle with the - platform-dependent compiler and linker flags for DSO - support.

- -

Usage Summary

- -

To give you an overview of the DSO features of Apache 2.0, - here is a short and concise summary:

- -
    -
  1. - Build and install a distributed Apache module, say - mod_foo.c, into its own DSO - mod_foo.so: - - - - - -
    -
    -$ ./configure --prefix=/path/to/install
    -        --enable-foo=shared
    -$ make install
    -
    -
    -
  2. - -
  3. - Build and install a third-party Apache module, say - mod_foo.c, into its own DSO - mod_foo.so: - - - - - -
    -
    -$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c 
    -        --enable-foo=shared
    -$ make install
    -
    -
    -
  4. - -
  5. - Configure Apache for later installation of shared - modules: - - - - - -
    -
    -$ ./configure --enable-so
    -$ make install
    -
    -
    -
  6. - -
  7. - Build and install a third-party Apache module, say - mod_foo.c, into its own DSO - mod_foo.so outside of the Apache - source tree using apxs: - - - - - -
    -
    -$ cd /path/to/3rdparty
    -$ apxs -c mod_foo.c
    -$ apxs -i -a -n foo mod_foo.so
    -
    -
    -
  8. -
- -

In all cases, once the shared module is compiled, you must - use a LoadModule - directive in httpd.conf to tell Apache to activate - the module.

- -

Background

- -

On modern Unix derivatives there exists a nifty mechanism - usually called dynamic linking/loading of Dynamic Shared - Objects (DSO) which provides a way to build a piece of - program code in a special format for loading it at run-time - into the address space of an executable program.

- -

This loading can usually be done in two ways: Automatically - by a system program called ld.so when an - executable program is started or manually from within the - executing program via a programmatic system interface to the - Unix loader through the system calls - dlopen()/dlsym().

- -

In the first way the DSO's are usually called shared - libraries or DSO libraries and named - libfoo.so or libfoo.so.1.2. They - reside in a system directory (usually /usr/lib) - and the link to the executable program is established at - build-time by specifying -lfoo to the linker - command. This hard-codes library references into the executable - program file so that at start-time the Unix loader is able to - locate libfoo.so in /usr/lib, in - paths hard-coded via linker-options like -R or in - paths configured via the environment variable - LD_LIBRARY_PATH. It then resolves any (yet - unresolved) symbols in the executable program which are - available in the DSO.

- -

Symbols in the executable program are usually not referenced - by the DSO (because it's a reusable library of general code) - and hence no further resolving has to be done. The executable - program has no need to do anything on its own to use the - symbols from the DSO because the complete resolving is done by - the Unix loader. (In fact, the code to invoke - ld.so is part of the run-time startup code which - is linked into every executable program which has been bound - non-static). The advantage of dynamic loading of common library - code is obvious: the library code needs to be stored only once, - in a system library like libc.so, saving disk - space for every program.

- -

In the second way the DSO's are usually called shared - objects or DSO files and can be named with an - arbitrary extension (although the canonical name is - foo.so). These files usually stay inside a - program-specific directory and there is no automatically - established link to the executable program where they are used. - Instead the executable program manually loads the DSO at - run-time into its address space via dlopen(). At - this time no resolving of symbols from the DSO for the - executable program is done. But instead the Unix loader - automatically resolves any (yet unresolved) symbols in the DSO - from the set of symbols exported by the executable program and - its already loaded DSO libraries (especially all symbols from - the ubiquitous libc.so). This way the DSO gets - knowledge of the executable program's symbol set as if it had - been statically linked with it in the first place.

- -

Finally, to take advantage of the DSO's API the executable - program has to resolve particular symbols from the DSO via - dlsym() for later use inside dispatch tables - etc. In other words: The executable program has to - manually resolve every symbol it needs to be able to use it. - The advantage of such a mechanism is that optional program - parts need not be loaded (and thus do not spend memory) until - they are needed by the program in question. When required, - these program parts can be loaded dynamically to extend the - base program's functionality.

- -

Although this DSO mechanism sounds straightforward there is - at least one difficult step here: The resolving of symbols from - the executable program for the DSO when using a DSO to extend a - program (the second way). Why? Because "reverse resolving" DSO - symbols from the executable program's symbol set is against the - library design (where the library has no knowledge about the - programs it is used by) and is neither available under all - platforms nor standardized. In practice the executable - program's global symbols are often not re-exported and thus not - available for use in a DSO. Finding a way to force the linker - to export all global symbols is the main problem one has to - solve when using DSO for extending a program at run-time.

- -

The shared library approach is the typical one, because it - is what the DSO mechanism was designed for, hence it is used - for nearly all types of libraries the operating system - provides. On the other hand using shared objects for extending - a program is not used by a lot of programs.

- -

As of 1998 there are only a few software packages available - which use the DSO mechanism to actually extend their - functionality at run-time: Perl 5 (via its XS mechanism and the - DynaLoader module), Netscape Server, etc. Starting - with version 1.3, Apache joined the crew, because Apache - already uses a module concept to extend its functionality and - internally uses a dispatch-list-based approach to link external - modules into the Apache core functionality. So, Apache is - really predestined for using DSO to load its modules at - run-time.

- -

Advantages and - Disadvantages

- -

The above DSO based features have the following - advantages:

- - - -

DSO has the following disadvantages:

- - - - - - diff --git a/docs/manual/invoking.html.en b/docs/manual/invoking.html.en deleted file mode 100644 index a9c625551f8..00000000000 --- a/docs/manual/invoking.html.en +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - Starting Apache - - - - - - -

Starting Apache

- - -
- -

Starting Apache On - Windows

- -

On Windows, Apache is normally run as a service on Windows - NT, or as a console application on Windows 95. For details, see - running Apache for - Windows.

- -

Starting Apache on Unix

- -

On Unix, the httpd program - is run as a daemon which executes continuously in the - background to handle requests.

- -

If the Listen specified in - the configuration file is default of 80 (or any other port - below 1024), then it is necessary to have root privileges in - order to start apache, so that it can bind to this privileged - port. Once the server has started and performed a few - preliminary activities such as opening its log files, it will - launch several child processes which do the work of - listening for and answering requests from clients. The main - httpd process continues to run as the root user, - but the child processes run as a less privileged user. This is - controlled by the selected Multi-Processing - Module.

- -

The first thing that httpd does when it is - invoked is to locate and read the configuration file - httpd.conf. The location of this file is set at - compile-time, but it is possible to specify its location at run - time using the -f command-line option as in

- -
- /usr/local/apache/bin/httpd -f - /usr/local/apache/conf/httpd.conf -
- -

As an alternative to invoking the httpd binary - directly, a shell script called apachectl is provided which - can be used to control the daemon process with simple commands - such as apachectl start and apachectl - stop.

- -

If all goes well during startup, the server will detach from - the terminal and the command prompt will return almost - immediately. This indicates that the server is up and running. - You can then use your browser to connect to the server and view - the test page in the DocumentRoot directory - and the local copy of the documentation linked from that - page.

- -

Errors During - Start-up

- -

If Apache suffers a fatal problem during startup, it will - write a message describing the problem either to the console or - to the ErrorLog before - exiting. One of the most common error messages is "Unable - to bind to Port ...". This message is usually caused by - either:

- - - -

For further trouble-shooting instructions, consult the - Apache FAQ.

- -

Starting at Boot-Time

- -

If you want your server to continue running after a system - reboot, you should add a call to httpd or - apachectl to your system startup files (typically - rc.local or a file in an rc.N - directory). This will start Apache as root. Before doing this - ensure that your server is properly configured for security and - access restrictions. The apachectl script is - designed so that it can often be linked directly as an init - script, but be sure to check the exact requirements of your - system.

- -

Additional Information

- -

Additional information about the command-line options of httpd and apachectl as well as other - support programs included with the server is available on the - Server and Supporting Programs page. - There is also documentation on all the modules included with the Apache distribution - and the directives that they - provide.

- - - - diff --git a/docs/manual/logs.html.en b/docs/manual/logs.html.en deleted file mode 100644 index 49ccee903a1..00000000000 --- a/docs/manual/logs.html.en +++ /dev/null @@ -1,666 +0,0 @@ - - - - - - - Log Files - Apache HTTP Server - - - - - - -

Log Files

- -

In order to effectively manage a web server, it is necessary - to get feedback about the activity and performance of the - server as well as any problems that may be occuring. The Apache - HTTP Server provides very comprehensive and flexible logging - capabilities. This document describes how to configure its - logging capabilities, and how to understand what the logs - contain.

- - -
- -

Security Warning

- -

Anyone who can write to the directory where Apache is - writing a log file can almost certainly gain access to the uid - that the server is started as, which is normally root. Do - NOT give people write access to the directory the logs - are stored in without being aware of the consequences; see the - security tips document - for details.

- -

In addition, log files may contain information supplied - directly by the client, without escaping. Therefore, it is - possible for malicious clients to insert control-characters in - the log files, so care must be taken in dealing with raw - logs.

-
- -

Error Log

- - - - - -
Related Directives
-
- ErrorLog
- LogLevel
- -

The server error log, whose name and location is set by the - ErrorLog directive, is the - most important log file. This is the place where Apache httpd - will send diagnostic information and record any errors that it - encounters in processing requests. It is the first place to - look when a problem occurs with starting the server or with the - operation of the server, since it will often contain details of - what went wrong and how to fix it.

- -

The error log is usually written to a file (typically - error_log on unix systems and - error.log on Windows and OS/2). On unix systems it - is also possible to have the server send errors to - syslog or pipe them to a - program.

- -

The format of the error log is relatively free-form and - descriptive. But there is certain information that is contained - in most error log entries. For example, here is a typical - message.

- -
- [Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] - client denied by server configuration: - /export/home/live/ap/htdocs/test -
- -

The first item in the log entry is the date and time of the - message. The second entry lists the severity of the error being - reported. The LogLevel - directive is used to control the types of errors that are sent - to the error log by restricting the severity level. The third - entry gives the IP address of the client that generated the - error. Beyond that is the message itself, which in this case - indicates that the server has been configured to deny the - client access. The server reports the file-system path (as - opposed to the web path) of the requested document.

- -

A very wide variety of different messages can appear in the - error log. Most look similar to the example above. The error - log will also contain debugging output from CGI scripts. Any - information written to stderr by a CGI script will - be copied directly to the error log.

- -

It is not possible to customize the error log by adding or - removing information. However, error log entries dealing with - particular requests have corresponding entries in the access log. For example, the above example - entry corresponds to an access log entry with status code 403. - Since it is possible to customize the access log, you can - obtain more information about error conditions using that log - file.

- -

During testing, it is often useful to continuously monitor - the error log for any problems. On unix systems, you can - accomplish this using:

- -
- tail -f error_log -
-
- -

Access Log

- - - - - - - -
Related Modules
-
- mod_log_config
-
Related Directives
-
- CustomLog
- LogFormat
- SetEnvIf -
- -

The server access log records all requests processed by the - server. The location and content of the access log are - controlled by the CustomLog - directive. The LogFormat - directive can be used to simplify the selection of the contents - of the logs. This section describes how to configure the server - to record information in the access log.

- -

Of course, storing the information in the access log is only - the start of log management. The next step is to analyze this - information to produce useful statistics. Log analysis in - general is beyond the scope of this document, and not really - part of the job of the web server itself. For more information - about this topic, and for applications which perform log - analysis, check the - Open Directory or - Yahoo.

- -

Various versions of Apache httpd have used other modules and - directives to control access logging, including - mod_log_referer, mod_log_agent, and the - TransferLog directive. The CustomLog - directive now subsumes the functionality of all the older - directives.

- -

The format of the access log is highly configurable. The - format is specified using a format string that - looks much like a C-style printf(1) format string. Some - examples are presented in the next sections. For a complete - list of the possible contents of the format string, see the mod_log_config - documentation.

- -

Common Log Format

- -

A typical configuration for the access log might look as - follows.

- -
- LogFormat "%h %l %u %t \"%r\" %>s %b" common
- CustomLog logs/access_log common
-
- -

This defines the nickname common and - associates it with a particular log format string. The format - string consists of percent directives, each of which tell the - server to log a particular piece of information. Literal - characters may also be placed in the format string and will be - copied directly into the log output. The quote character - (") must be escaped by placing a back-slash before - it to prevent it from being interpreted as the end of the - format string. The format string may also contain the special - control characters "\n" for new-line and - "\t" for tab.

- -

The CustomLog directive sets up a new log file - using the defined nickname. The filename for the - access log is relative to the ServerRoot unless it begins - with a slash.

- -

The above configuration will write log entries in a format - known as the Common Log Format (CLF). This standard format can - be produced by many different web servers and read by many log - analysis programs. The log file entries produced in CLF will - look something like this:

- -
- 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET - /apache_pb.gif HTTP/1.0" 200 2326 -
- -

Each part of this log entry is described below.

- -
-
127.0.0.1 (%h)
- -
This is the IP address of the client (remote host) which - made the request to the server. If HostnameLookups is - set to On, then the server will try to determine - the hostname and log it in place of the IP address. However, - this configuration is not recommended since it can - significantly slow the server. Instead, it is best to use a - log post-processor such as logresolve to determine - the hostnames. The IP address reported here is not - necessarily the address of the machine at which the user is - sitting. If a proxy server exists between the user and the - server, this address will be the address of the proxy, rather - than the originating machine.
- -
- (%l)
- -
The "hyphen" in the output indicates that the requested - piece of information is not available. In this case, the - information that is not available is the RFC 1413 identity of - the client determined by identd on the clients - machine. This information is highly unreliable and should - almost never be used except on tightly controlled internal - networks. Apache httpd will not even attempt to determine - this information unless IdentityCheck is set - to On.
- -
frank (%u)
- -
This is the userid of the person requesting the document - as determined by HTTP authentication. The same value is - typically provided to CGI scripts in the - REMOTE_USER environment variable. If the status - code for the request (see below) is 401, then this value - should not be trusted because the user is not yet - authenticated. If the document is not password protected, - this entry will be "-" just like the previous - one.
- -
[10/Oct/2000:13:55:36 -0700] - (%t)
- -
- The time that the server finished processing the request. - The format is: - -
- [day/month/year:hour:minute:second zone]
- day = 2*digit
- month = 3*letter
- year = 4*digit
- hour = 2*digit
- minute = 2*digit
- second = 2*digit
- zone = (`+' | `-') 4*digit
-
- It is possible to have the time displayed in another format - by specifying %{format}t in the log format - string, where format is as in - strftime(3) from the C standard library. -
- -
"GET /apache_pb.gif HTTP/1.0" - (\"%r\")
- -
The request line from the client is given in double - quotes. The request line contains a great deal of useful - information. First, the method used by the client is - GET. Second, the client requested the resource - /apache_pb.gif, and third, the client used the - protocol HTTP/1.0. It is also possible to log - one or more parts of the request line independently. For - example, the format string "%m %U%q %H" will log - the method, path, query-string, and protocol, resulting in - exactly the same output as "%r".
- -
200 (%>s)
- -
This is the status code that the server sends back to the - client. This information is very valuable, because it reveals - whether the request resulted in a successful response (codes - beginning in 2), a redirection (codes beginning in 3), an - error caused by the client (codes beginning in 4), or an - error in the server (codes beginning in 5). The full list of - possible status codes can be found in the HTTP - specification (RFC2616 section 10).
- -
2326 (%b)
- -
The last entry indicates the size of the object returned - to the client, not including the response headers. If no - content was returned to the client, this value will be - "-". To log "0" for no content, use - %B instead.
-
- -

Combined Log - Format

- -

Another commonly used format string is called the Combined - Log Format. It can be used as follows.

- -
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" - \"%{User-agent}i\"" combined
- CustomLog log/acces_log combined
-
- -

This format is exactly the same as the Common Log Format, - with the addition of two more fields. Each of the additional - fields uses the percent-directive - %{header}i, where header can be - any HTTP request header. The access log under this format will - look like:

- -
- 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET - /apache_pb.gif HTTP/1.0" 200 2326 - "http://www.example.com/start.html" "Mozilla/4.08 [en] - (Win98; I ;Nav)" -
- -

The additional fields are:

- -
-
"http://www.example.com/start.html" - (\"%{Referer}i\")
- -
The "Referer" (sic) HTTP request header. This gives the - site that the client reports having been referred from. (This - should be the page that links to or includes - /apache_pb.gif).
- -
"Mozilla/4.08 [en] (Win98; I ;Nav)" - (\"%{User-agent}i\")
- -
The User-Agent HTTP request header. This is the - identifying information that the client browser reports about - itself.
-
- -

Multiple Access - Logs

- -

Multiple access logs can be created simply by specifying - multiple CustomLog directives in the configuration - file. For example, the following directives will create three - access logs. The first contains the basic CLF information, - while the second and third contain referer and browser - information. The last two CustomLog lines show how - to mimic the effects of the ReferLog and - AgentLog directives.

- -
- LogFormat "%h %l %u %t \"%r\" %>s %b" common
- CustomLog logs/access_log common
- CustomLog logs/referer_log "%{Referer}i -> %U"
- CustomLog logs/agent_log "%{User-agent}i"
-
- -

This example also shows that it is not necessary to define a - nickname with the LogFormat directive. Instead, - the log format can be specified directly in the - CustomLog directive.

- -

Conditional - Logging

- -

There are times when it is convenient to exclude certain - entries from the access logs based on characteristics of the - client request. This is easily accomplished with the help of environment variables. First, an - environment variable must be set to indicate that the request - meets certain conditions. This is usually accomplished with SetEnvIf. Then the - env= clause of the CustomLog - directive is used to include or exclude requests where the - environment variable is set. Some examples:

- -
- # Mark requests from the loop-back interface
- SetEnvIf Remote_Addr "127\.0\.0\.1" dontlog
- # Mark requests for the robots.txt file
- SetEnvIf Request_URI "^/robots\.txt$" dontlog
- # Log what remains
- CustomLog logs/access_log common env=!dontlog
-
- -

As another example, consider logging requests from - english-speakers to one log file, and non-english speakers to a - different log file.

- -
- SetEnvIf Accept-Language "en" english
- CustomLog logs/english_log common env=english
- CustomLog logs/non_english_log common env=!english
-
- -

Although we have just shown that conditional logging is very - powerful and flexibly, it is not the only way to control the - contents of the logs. Log files are more useful when they - contain a complete record of server activity. It is often - easier to simply post-process the log files to remove requests - that you do not want to consider.

-
- -

Log Rotation

- -

On even a moderately busy server, the quantity of - information stored in the log files is very large. The access - log file typically grows 1 MB or more per 10,000 requests. It - will consequently be necessary to periodically rotate the log - files by moving or deleting the existing logs. This cannot be - done while the server is running, because Apache will continue - writing to the old log file as long as it holds the file open. - Instead, the server must be restarted after the log files are - moved or deleted so that it will open new log files.

- -

By using a graceful restart, the server can be - instructed to open new log files without losing any existing or - pending connections from clients. However, in order to - accomplish this, the server must continue to write to the old - log files while it finishes serving old requests. It is - therefore necessary to wait for some time after the restart - before doing any processing on the log files. A typical - scenario that simply rotates the logs and compresses the old - logs to save space is:

- -
- mv access_log access_log.old
- mv error_log error_log.old
- apachectl graceful
- sleep 600
- gzip access_log.old error_log.old
-
- -

Another way to perform log rotation is using piped logs as discussed in the next - section.

-
- -

Piped Logs

- -

Apache httpd is capable of writing error and access log - files through a pipe to another process, rather than directly - to a file. This capability dramatically increases the - flexibility of logging, without adding code to the main server. - In order to write logs to a pipe, simply replace the filename - with the pipe character "|", followed by the name - of the executable which should accept log entries on its - standard input. Apache will start the piped-log process when - the server starts, and will restart it if it crashes while the - server is running. (This last feature is why we can refer to - this technique as "reliable piped logging".)

- -

Piped log processes are spawned by the parent Apache httpd - process, and inherit the userid of that process. This means - that piped log programs usually run as root. It is therefore - very important to keep the programs simple and secure.

- -

Some simple examples using piped logs:

- -
- # compressed logs
- CustomLog "|/usr/bin/gzip -c >> - /var/log/access_log.gz" common
- # almost-real-time name resolution
- CustomLog "|/usr/local/apache/bin/logresolve >> - /var/log/access_log" common
-
- -

Notice that quotes are used to enclose the entire command - that will be called for the pipe. Although these examples are - for the access log, the same technique can be used for the - error log.

- -

One important use of piped logs is to allow log rotation - without having to restart the server. The Apache HTTP Server - includes a simple program called rotatelogs for this - purpose. For example, to rotate the logs every 24 hours, you - can use:

- -
- CustomLog "|/usr/local/apache/bin/rotatelogs - /var/log/access_log 86400" common -
- -

A similar, but much more flexible log rotation program - called cronolog - is available at an external site.

- -

As with conditional logging, piped logs are a very powerful - tool, but they should not be used where a simpler solution like - off-line post-processing is available.

-
- -

Virtual - Hosts

- -

When running a server with many virtual - hosts, there are several options for dealing with log - files. First, it is possible to use logs exactly as in a - single-host server. Simply by placing the logging directives - outside the <VirtualHost> sections in the - main server context, it is possible to log all requests in the - same access log and error log. This technique does not allow - for easy collection of statistics on individual virtual - hosts.

- -

If CustomLog or ErrorLog - directives are placed inside a <VirtualHost> - section, all requests or errors for that virtual host will be - logged only to the specified file. Any virtual host which does - not have logging directives will still have its requests sent - to the main server logs. This technique is very useful for a - small number of virtual hosts, but if the number of hosts is - very large, it can be complicated to manage. In addition, it - can often create problems with insufficient file - descriptors.

- -

For the access log, there is a very good compromise. By - adding information on the virtual host to the log format - string, it is possible to log all hosts to the same log, and - later split the log into individual files. For example, - consider the following directives.

- -
- LogFormat "%v %l %u %t \"%r\" %>s %b" - comonvhost
- CustomLog logs/access_log comonvhost
-
- -

The %v is used to log the name of the virtual - host that is serving the request. Then a program like split-logfile can be used to - post-process the access log in order to split it into one file - per virtual host.

- -

Unfortunately, no similar technique is available for the - error log, so you must choose between mixing all virtual hosts - in the same error log and using one error log per virtual - host.

-
- -

Other Log Files

- - - - - - - -
Related Modules
-
- mod_cgi
- mod_rewrite
Related Directives
-
- PidFile
- RewriteLog
- RewriteLogLevel
- ScriptLog
- ScriptLogLength
- ScriptLogBuffer -
- -

PID File

- -

On startup, Apache httpd saves the process id of the parent - httpd process to the file logs/httpd.pid. This - filename can be changed with the PidFile directive. The - process-id is for use by the administrator in restarting and - terminating the daemon by sending signals to the parent - process; on Windows, use the -k command line option instead. - For more information see the Stopping - and Restarting page.

- -

Script Log

- -

In order to aid in debugging, the ScriptLog directive - allows you to record the input to and output from CGI scripts. - This should only be used in testing - not for live servers. - More information is available in the mod_cgi documentation.

- -

Rewrite Log

- -

When using the powerful and complex features of mod_rewrite, it is almost - always necessary to use the RewriteLog to help - in debugging. This log file produces a detailed analysis of how - the rewriting engine transforms requests. The level of detail - is controlled by the RewriteLogLevel - directive.

- - - - diff --git a/docs/manual/mod/directive-dict.html.en b/docs/manual/mod/directive-dict.html.en deleted file mode 100644 index deedf08aca0..00000000000 --- a/docs/manual/mod/directive-dict.html.en +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - Definitions of terms used to describe Apache - directives - - - - - - -

Terms Used to Describe Apache - Directives

- -

Each Apache configuration directive is described using a - common format that looks like this:

- -
-
Syntax: - directive-name some args
- Default: - directive-name default-value
- Context: - context-list
- Override: - override
- Status: - status
- Module: - module-name
- Compatibility: - compatibility notes
- Deprecated: see - other
-
- -

Each of the directive's attributes, complete with possible - values where possible, are described in this document.

- -

Directive Terms

- - -
- -

Syntax

- -

This indicates the format of the directive as it would - appear in a configuration file. This syntax is extremely - directive-specific, and is described in detail in the - directive's definition. Generally, the directive name is - followed by a series of one or more space-separated arguments. - If an argument contains a space, the argument must be enclosed - in double quotes. Optional arguments are enclosed in square - brackets. Where an argument can take on more than one possible - value, the possible values are separated by vertical bars "|". - Literal text is presented in the default font, while - argument-types for which substitution is necessary are - emphasized. Directives which can take a variable - number of arguments will end in "..." indicating that the last - argument is repeated.

- -

Directives use a great number of different argument types. A - few common ones are defined below.

- -
-
URL
- -
A complete Uniform Resource Locator including a scheme, - hostname, and optional pathname as in - http://www.example.com/path/to/file.html
- -
URL-path
- -
The part of a url which follows the scheme and - hostname as in /path/to/file.html. The - url-path represents a web-view of a resource, as - opposed to a file-system view.
- -
file-path
- -
The path to a file in the local file-system beginning - with the root directory as in - /usr/local/apache/htdocs/path/to/file.html. - Unless otherwise specified, a file-path which does - not begin with a slash will be treated as relative to the ServerRoot.
- -
directory-path
- -
The path to a directory in the local file-system - beginning with the root directory as in - /usr/local/apache/htdocs/path/to/.
- -
filename
- -
The name of a file with no accompanying path information - as in file.html.
- -
regex
- -
A regular expression, which is a way of describing a - pattern to match in text. The directive definition will - specify what the regex is matching against.
- -
extension
- -
In general, this is the part of the filename - which follows the last dot. However, Apache recognizes - multiple filename extensions, so if a filename - contains more than one dot, each dot-separated part of the - filename following the first dot is an extension. - For example, the filename file.html.en - contains two extensions: .html and - .en. For Apache directives, you may specify - extensions with or without the leading dot. In - addition, extensions are not case sensitive.
- -
MIME-type
- -
A method of describing the format of a file which - consists of a major format type and a minor format type, - separated by a slash as in text/html.
- -
env-variable
- -
The name of an environment - variable defined in the Apache configuration process. - Note this is not necessarily the same as an operating system - environment variable. See the environment variable documentation for - more details.
-
-
- -

Default

- -

If the directive has a default value (i.e., if you - omit it from your configuration entirely, the Apache Web server - will behave as though you set it to a particular value), it is - described here. If there is no default value, this section - should say "None". Note that the default listed here - is not necessarily the same as the value the directive takes in - the default httpd.conf distributed with the server.

-
- -

Context

- -

This indicates where in the server's configuration files the - directive is legal. It's a comma-separated list of one or more - of the following values:

- -
-
server config
- -
This means that the directive may be used in the server - configuration files (e.g., httpd.conf, - srm.conf, and access.conf), but - not within any - <VirtualHost> or <Directory> - containers. It is not allowed in .htaccess files - at all.
- -
virtual host
- -
This context means that the directive may appear inside - <VirtualHost> containers in the server - configuration files.
- -
directory
- -
A directive marked as being valid in this context may be - used inside <Directory>, - <Location>, and <Files> - containers in the server configuration files, subject to the - restrictions outlined in How - Directory, Location and Files sections work.
- -
.htaccess
- -
If a directive is valid in this context, it means that it - can appear inside per-directory - .htaccess files. It may not be processed, though - depending upon the overrides currently active.
-
- -

The directive is only allowed within the designated - context; if you try to use it elsewhere, you'll get a - configuration error that will either prevent the server from - handling requests in that context correctly, or will keep the - server from operating at all -- i.e., the server won't - even start.

- -

The valid locations for the directive are actually the - result of a Boolean OR of all of the listed contexts. In other - words, a directive that is marked as being valid in - "server config, .htaccess" can be used in the - httpd.conf file and in .htaccess - files, but not within any <Directory> or - <VirtualHost> containers.

-
- -

Override

- -

This directive attribute indicates which configuration - override must be active in order for the directive to be - processed when it appears in a .htaccess file. If - the directive's context - doesn't permit it to appear in .htaccess files, - this attribute should say "Not applicable".

- -

Overrides are activated by the AllowOverride directive, and apply - to a particular scope (such as a directory) and all - descendants, unless further modified by other - AllowOverride directives at lower levels. The - documentation for that directive also lists the possible - override names available.

-
- -

Status

- -

This indicates how tightly bound into the Apache Web server - the directive is; in other words, you may need to recompile the - server with an enhanced set of modules in order to gain access - to the directive and its functionality. Possible values for - this attribute are:

- -
-
Core
- -
If a directive is listed as having "Core" status, that - means it is part of the innermost portions of the Apache Web - server, and is always available.
- -
MPM
- -
A directive labeled as having "MPM" status is provided by - a Multi-Processing Module. This - type of directive will be available if and only if you are - using one of the MPMs listed on the Module line of the directive - definition.
- -
Base
- -
A directive labeled as having "Base" status is supported - by one of the standard Apache modules which is compiled into - the server by default, and is therefore normally available - unless you've taken steps to remove the module from your - configuration.
- -
Extension
- -
A directive with "Extension" status is provided by one of - the modules included with the Apache server kit, but the - module isn't normally compiled into the server. To enable the - directive and its functionality, you will need to change the - server build configuration files and re-compile Apache.
- -
Experimental
- -
"Experimental" status indicates that the directive is - available as part of the Apache kit, but you're on your own - if you try to use it. The directive is being documented for - completeness, and is not necessarily supported. The module - which provides the directive may or may not be compiled in by - default; check the top of the page which describes the - directive and its module to see if it remarks on the - availability.
-
-
- -

Module

- -

This quite simply lists the name of the source module which - defines the directive.

-
- -

Compatibility

- -

If the directive wasn't part of the original Apache version - 1 distribution, the version in which it was introduced should - be listed here. If the directive has the same name as one from - the NCSA HTTPd server, any inconsistencies in behavior between - the two should also be mentioned. Otherwise, this attribute - should say "No compatibility issues."

-
- -

Deprecated

- -

If this directive is eliminated since the Apache version 1 - distribution, the directive or option that replaces the - behavior should be cited here. In general, directives, - features, and options are only deprecated to minimize debugging - of conflicting features, or if the feature can only continue to - be supported in an alternate manner.

- - - - diff --git a/docs/manual/mod/module-dict.html.en b/docs/manual/mod/module-dict.html.en deleted file mode 100644 index 5e7cadb8214..00000000000 --- a/docs/manual/mod/module-dict.html.en +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - Definitions of terms used to describe Apache - modules - - - - - - -

Terms Used to Describe Apache Modules

- -

Each Apache module is described using a common format that - looks like this:

- -
-
Status: - status
- Source - File: source-file
- Module - Identifier: module-identifier
- Compatibility: - compatibility notes
-
- -

Each of the attributes, complete with values where possible, - are described in this document.

- -

Module Terms

- - -
- -

Status

- -

This indicates how tightly bound into the Apache Web server - the module is; in other words, you may need to recompile the - server in order to gain access to the module and its - functionality. Possible values for this attribute are:

- -
-
MPM
- -
A module with status "MPM" is a Multi-Processing Module. Unlike the - other types of modules, Apache must have one and only one MPM - in use at any time. This type of module is responsible for - basic request handling and dispatching.
- -
Base
- -
A module labeled as having "Base" status is compiled and - loaded into the server by default, and is therefore normally - available unless you have taken steps to remove the module - from your configuration.
- -
Extension
- -
A module with "Extension" status is not normally compiled - and loaded into the server. To enable the module and its - functionality, you may need to change the server build - configuration files and re-compile Apache.
- -
Experimental
- -
"Experimental" status indicates that the module is - available as part of the Apache kit, but you are on your own - if you try to use it. The module is being documented for - completeness, and is not necessarily supported.
- -
External
- -
Modules which are not included with the base Apache - distribution ("third-party modules") may use the "External" - status. We are not responsible for, nor do we support such - modules.
-
-
- -

Source File

- -

This quite simply lists the name of the source file which - contains the code for the module. This is also the name used by - the <IfModule> - directive.

-
- -

Module - Identifier

- -

This is a string which identifies the module for use in the - LoadModule directive when - dynamically loading modules. In particular, it is the name of - the external variable of type module in the source file.

-
- -

Compatibility

- -

If the module was not part of the original Apache version 2 - distribution, the version in which it was introduced should be - listed here.

- - - - diff --git a/docs/manual/sitemap.html.en b/docs/manual/sitemap.html.en deleted file mode 100644 index d1f27cb89f7..00000000000 --- a/docs/manual/sitemap.html.en +++ /dev/null @@ -1,201 +0,0 @@ - - - - - Site Map - Apache HTTP Server 2.0 - - - - - - -

Site Map

- - - - - - diff --git a/docs/manual/stopping.html.en b/docs/manual/stopping.html.en deleted file mode 100644 index 8e2c2b12c62..00000000000 --- a/docs/manual/stopping.html.en +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - Stopping and Restarting the Server - - - - - - -

Stopping and Restarting the Server

- -

This document covers stopping and restarting Apache on - Unix-like systems. Windows users should see Signalling Apache when - running.

- -

You will notice many httpd executables running - on your system, but you should not send signals to any of them - except the parent, whose pid is in the PidFile. That is to say you - shouldn't ever need to send signals to any process except the - parent. There are three signals that you can send the parent: - TERM, HUP, and USR1, - which will be described in a moment.

- -

To send a signal to the parent you should issue a command - such as:

- -
-
-    kill -TERM `cat /usr/local/apache/logs/httpd.pid`
-
-
- You can read about its progress by issuing: - -
-
-    tail -f /usr/local/apache/logs/error_log
-
-
- Modify those examples to match your ServerRoot and PidFile settings. - -

A shell script called apachectl is provided which - automates the processing of signalling Apache. For details - about this script, see the documentation on starting Apache.

- -

Stop Now

- -

Signal: TERM
- apachectl stop

- -

Sending the TERM signal to the parent causes it - to immediately attempt to kill off all of its children. It may - take it several seconds to complete killing off its children. - Then the parent itself exits. Any requests in progress are - terminated, and no further requests are served.

- -

Graceful Restart

- -

Signal: USR1
- apachectl graceful

- -

The USR1 signal causes the parent process to - advise the children to exit after their current - request (or to exit immediately if they're not serving - anything). The parent re-reads its configuration files and - re-opens its log files. As each child dies off the parent - replaces it with a child from the new generation of - the configuration, which begins serving new requests - immediately.

- On certain platforms that do not allow USR1 to be used for a - graceful restart, an alternative signal may be used (such as - WINCH). apachectl graceful will send the right signal for your - platform. - -

This code is designed to always respect the MaxClients, MinSpareServers, - and MaxSpareServers - settings. Furthermore, it respects StartServers in the - following manner: if after one second at least StartServers new - children have not been created, then create enough to pick up - the slack. This is to say that the code tries to maintain both - the number of children appropriate for the current load on the - server, and respect your wishes with the StartServers - parameter.

- -

Users of the status module - will notice that the server statistics are not - set to zero when a USR1 is sent. The code was - written to both minimize the time in which the server is unable - to serve new requests (they will be queued up by the operating - system, so they're not lost in any event) and to respect your - tuning parameters. In order to do this it has to keep the - scoreboard used to keep track of all children across - generations.

- -

The status module will also use a G to indicate - those children which are still serving requests started before - the graceful restart was given.

- -

At present there is no way for a log rotation script using - USR1 to know for certain that all children writing - the pre-restart log have finished. We suggest that you use a - suitable delay after sending the USR1 signal - before you do anything with the old log. For example if most of - your hits take less than 10 minutes to complete for users on - low bandwidth links then you could wait 15 minutes before doing - anything with the old log.

- -

Note: If your configuration file has errors - in it when you issue a restart then your parent will not - restart, it will exit with an error. In the case of graceful - restarts it will also leave children running when it exits. - (These are the children which are "gracefully exiting" by - handling their last request.) This will cause problems if you - attempt to restart the server -- it will not be able to bind to - its listening ports. Before doing a restart, you can check the - syntax of the configuration files with the -t - command line argument (see httpd). This still will not - guarantee that the server will restart correctly. To check the - semantics of the configuration files as well as the syntax, you - can try starting httpd as a non-root user. If there are no - errors it will attempt to open its sockets and logs and fail - because it's not root (or because the currently running httpd - already has those ports bound). If it fails for any other - reason then it's probably a config file error and the error - should be fixed before issuing the graceful restart.

- -

Restart Now

- -

Signal: HUP
- apachectl restart

- -

Sending the HUP signal to the parent causes it - to kill off its children like in TERM but the - parent doesn't exit. It re-reads its configuration files, and - re-opens any log files. Then it spawns a new set of children - and continues serving hits.

- -

Users of the status module - will notice that the server statistics are set to zero when a - HUP is sent.

- -

Note: If your configuration file has errors - in it when you issue a restart then your parent will not - restart, it will exit with an error. See below for a method of - avoiding this.

- -

Appendix: signals and race conditions

- -

Prior to Apache 1.2b9 there were several race - conditions involving the restart and die signals (a simple - description of race condition is: a time-sensitive problem, as - in if something happens at just the wrong time it won't behave - as expected). For those architectures that have the "right" - feature set we have eliminated as many as we can. But it should - be noted that there still do exist race conditions on certain - architectures.

- -

Architectures that use an on disk ScoreBoardFile have the - potential to corrupt their scoreboards. This can result in the - "bind: Address already in use" (after HUP) or - "long lost child came home!" (after USR1). The - former is a fatal error, while the latter just causes the - server to lose a scoreboard slot. So it might be advisable to - use graceful restarts, with an occasional hard restart. These - problems are very difficult to work around, but fortunately - most architectures do not require a scoreboard file. See the ScoreBoardFile - documentation for a architecture uses it.

- -

NEXT and MACHTEN (68k only) have - small race conditions which can cause a restart/die signal to - be lost, but should not cause the server to do anything - otherwise problematic. - -

- -

All architectures have a small race condition in each child - involving the second and subsequent requests on a persistent - HTTP connection (KeepAlive). It may exit after reading the - request line but before reading any of the request headers. - There is a fix that was discovered too late to make 1.2. In - theory this isn't an issue because the KeepAlive client has to - expect these events because of network latencies and server - timeouts. In practice it doesn't seem to affect anything either - -- in a test case the server was restarted twenty times per - second and clients successfully browsed the site without - getting broken images or empty documents. - -

- - - diff --git a/docs/manual/urlmapping.html.en b/docs/manual/urlmapping.html.en deleted file mode 100755 index 627dcf053f9..00000000000 --- a/docs/manual/urlmapping.html.en +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - - Mapping URLs to Filesystem Locations - Apache HTTP - Server - - - - - - -

Mapping URLs to Filesystem Locations

- -

This document explains how Apache uses the URL of a request - to determine the filesystem location from which to serve a - file.

- - -
- - - - - - - -
Related Modules
-
- mod_alias
- mod_rewrite
- mod_userdir
- mod_speling
- mod_vhost_alias
-
Related Directives
-
- Alias
- AliasMatch
- CheckSpelling
- DocumentRoot
- ErrorDocument
- Options
- Redirect
- RedirectMatch
- RewriteCond
- RewriteRule
- ScriptAlias
- ScriptAliasMatch
- UserDir
-
- -

DocumentRoot

- -

In deciding what file to serve for a given request, Apache's - default behavior is to take the URL-Path for the request (the - part of the URL following the hostname and port) and add it to - the end of the DocumentRoot specified in - your configuration files. Therefore, the files and directories - underneath the DocumentRoot make up the basic - document tree which will be visible from the web.

- -

Apache is also capable of Virtual - Hosting, where the server receives requests for more than - one host. In this case, a different DocumentRoot - can be specified for each virtual host, or alternatively, the - directives provided by the module mod_vhost_alias can be used - to dynamically determine the appropriate place from which to - serve content based on the requested IP address or - hostname.

- -

Files Outside the - DocumentRoot

- -

There are frequently circumstances where it is necessary to - allow web access to parts of the filesystem that are not - strictly underneath the DocumentRoot. Apache - offers several different ways to accomplish this. On Unix - systems, symbolic links can bring other parts of the filesystem - under the DocumentRoot. For security reasons, - Apache will follow symbolic links only if the Options setting for the - relevant directory includes FollowSymLinks or - SymLinksIfOwnerMatch.

- -

Alternatively, the Alias directive will map - any part of the filesystem into the web space. For example, - with

- -
- Alias /docs /var/web/ -
- -

the URL - http://www.example.com/docs/dir/file.html will be - served from /var/web/dir/file.html. The ScriptAlias directive - works the same way, with the additional effect that all content - located at the target path is treated as CGI scripts.

- -

For situations where you require additional flexibility, you - can use the AliasMatch and ScriptAliasMatch - directives to do powerful regular-expression based matching and - substitution. For example,

- -
- ScriptAliasMatch ^/~([^/]*)/cgi-bin/(.*) - /home/$1/cgi-bin/$2 -
- -

will map a request to - http://example.com/~user/cgi-bin/script.cgi to the - path /home/user/cgi-bin/script.cgi and will treat - the resulting file as a CGI script.

- -

User Directories

- -

Traditionally on Unix systems, the home directory of a - particular user can be referred to as - ~user/. The module mod_userdir extends this idea - to the web by allowing files under each user's home directory - to be accessed using URLs such as the following.

- -
- http://www.example.com/~user/file.html -
- -

For security reasons, it is inappropriate to give direct - access to a user's home directory from the web. Therefore, the - UserDir directive - specifies a directory underneath the user's home directory - where web files are located. Using the default setting of - Userdir public_html, the above URL maps to a file - at a directory like - /home/user/public_html/file.html where - /home/user/ is the user's home directory as - specified in /etc/passwd.

- -

There are also several other forms of the - Userdir directive which you can use on systems - where /etc/passwd does not contain the location of - the home directory.

- -

Some people find the "~" symbol (which is often encoded on - the web as %7e) to be awkward and prefer to use an - alternate string to represent user directories. This - functionality is not supported by mod_userdir. However, if - users' home directories are structured in a regular way, then - it is possible to use the AliasMatch directive - to achieve the desired effect. For example, to make - http://www.example.com/upages/user/file.html map - to /home/user/public_html/file.html, use the - following AliasMatch directive:

- -
- AliasMatch ^/upages/([^/]*)/?(.*) - /home/$1/public_html/$2 -
- -

URL Redirection

- -

The configuration directives discussed in the above sections - tell Apache to get content from a specific place in the - filesystem and return it to the client. Sometimes, it is - desirable instead to inform the client that the requested - content is located at a different URL, and instruct the client - to make a new request with the new URL. This is called - redirection and is implemented by the Redirect directive. For - example, if the contents of the directory /foo/ - under the DocumentRoot are moved to the new - directory /bar/, you can instruct clients to - request the content at the new location as follows:

- -
- Redirect permanent /foo/ - http://www.example.com/bar/ -
- -

This will redirect any URL-Path starting in - /foo/ to the same URL path on the - www.example.com server with /bar/ - substituted for /foo/. You can redirect clients to - any server, not only the origin server.

- -

Apache also provides a RedirectMatch - directive for more complicated rewriting problems. For example, - to redirect requests for the site home page to a different - site, but leave all other requests alone, use the following - configuration:

- -
- RedirectMatch permanent ^/$ - http://www.example.com/startpage.html -
- -

Alternatively, to temporarily redirect all pages on a site - to one particular page, use the following:

- -
- RedirectMatch temp .* - http://www.example.com/startpage.html -
- -

Rewriting Engine

- -

When even more powerful substitution is required, the - rewriting engine provided by mod_rewrite can be useful. The - directives provided by this module use characteristics of the - request such as browser type or source IP address in deciding - from where to serve content. In addition, mod_rewrite can use - external database files or programs to determine how to handle - a request. Many practical examples employing mod_rewrite are - discussed in the URL Rewriting - Guide.

- -

File Not Found

- -

Inevitably, URLs will be requested for which no matching - file can be found in the filesystem. This can happen for - several reasons. In some cases, it can be a result of moving - documents from one location to another. In this case, it is - best to use URL redirection to inform - clients of the new location of the resource. In this way, you - can assure that old bookmarks and links will continue to work, - even though the resource is at a new location.

- -

Another common cause of "File Not Found" errors is - accidental mistyping of URLs, either directly in the browser, - or in HTML links. Apache provides the module mod_speling (sic) to help with - this problem. When this module is activated, it will intercept - "File Not Found" errors and look for a resource with a similar - filename. If one such file is found, mod_speling will send an - HTTP redirect to the client informing it of the correct - location. If several "close" files are found, a list of - available alternatives will be presented to the client.

- -

An especially useful feature of mod_speling, is that it will - compare filenames without respect to case. This can help - systems where users are unaware of the case-sensitive nature of - URLs and the unix filesystem. But using mod_speling for - anything more than the occasional URL correction can place - additional load on the server, since each "incorrect" request - is followed by a URL redirection and a new request from the - client.

- -

If all attempts to locate the content fail, Apache returns - an error page with HTTP status code 404 (file not found). The - appearance of this page is controlled with the ErrorDocument directive - and can be customized in a flexible manner as discussed in the - Custom error responses and International Server Error - Responses documents.

- - - - diff --git a/docs/manual/vhosts/fd-limits.html.en b/docs/manual/vhosts/fd-limits.html.en deleted file mode 100644 index dc09fb2d57b..00000000000 --- a/docs/manual/vhosts/fd-limits.html.en +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - Apache Server Virtual Host Support - - - - - - -

File Descriptor Limits

- -

When using a large number of Virtual Hosts, Apache may run - out of available file descriptors (sometimes called file - handles if each Virtual Host specifies different log - files. The total number of file descriptors used by Apache is - one for each distinct error log file, one for every other log - file directive, plus 10-20 for internal use. Unix operating - systems limit the number of file descriptors that may be used - by a process; the limit is typically 64, and may usually be - increased up to a large hard-limit.

- -

Although Apache attempts to increase the limit as required, - this may not work if:

- -
    -
  1. Your system does not provide the setrlimit() system - call.
  2. - -
  3. The setrlimit(RLIMIT_NOFILE) call does not function on - your system (such as Solaris 2.3)
  4. - -
  5. The number of file descriptors required exceeds the hard - limit.
  6. - -
  7. Your system imposes other limits on file descriptors, - such as a limit on stdio streams only using file descriptors - below 256. (Solaris 2)
  8. -
- In the event of problems you can: - - - -

Please see the Descriptors and Apache - document containing further details about file descriptor - problems and how they can be solved on your operating - system.

- - - - diff --git a/docs/manual/vhosts/index.html.en b/docs/manual/vhosts/index.html.en deleted file mode 100644 index 7cb19b80920..00000000000 --- a/docs/manual/vhosts/index.html.en +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - Apache Virtual Host documentation - - - - - - -

Apache Virtual Host documentation

- -

The term Virtual Host refers to the practice of - maintaining more than one server on one machine, as - differentiated by their apparent hostname. For example, it is - often desirable for companies sharing a web server to have - their own domains, with web servers accessible as - www.company1.com and - www.company2.com, without requiring the user to - know any extra path information.

- -

Apache was one of the first servers to support IP-based - virtual hosts right out of the box. Versions 1.1 and later of - Apache support both, IP-based and name-based virtual hosts - (vhosts). The latter variant of virtual hosts is sometimes also - called host-based or non-IP virtual hosts.

- -

Below is a list of documentation pages which explain all - details of virtual host support in Apache version 1.3 and - later.

-
- -

Virtual Host Support

- - - -

Configuration directives

- - - -

Folks trying to debug their virtual host configuration may - find the Apache -t -D DUMP_VHOSTS command line switch - useful. It will dump out a description of how Apache parsed the - configuration file. Careful examination of the IP addresses and - server names may help uncover configuration mistakes. - -

- - - diff --git a/docs/manual/vhosts/name-based.html.en b/docs/manual/vhosts/name-based.html.en deleted file mode 100644 index 075140a6bf8..00000000000 --- a/docs/manual/vhosts/name-based.html.en +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Name-based Virtual Hosts - - - - - - -

Name-based Virtual Host Support

- -

This document describes when and how to use name-based virtual hosts.

- - - -

See also: Virtual Host examples for common -setups, IP-based Virtual Host Support, -An In-Depth Discussion of Virtual Host -Matching, and Dynamically configured mass -virtual hosting.

- -
- -

Name-based vs. IP-based Virtual Hosts

- -

IP-based virtual hosts use the IP address of the connection to -determine the correct virtual host to serve. Therefore you need to -have a separate IP address for each host. With name-based virtual -hosting, the server relies on the client to report the hostname as -part of the HTTP headers. Using this technique, many different hosts -can share the same IP address.

- -

Name-based virtual hosting is usually simpler, since you need -only configure your DNS server to map each hostname to the correct -IP address and then configure the Apache HTTP Server to recognize -the different hostnames. Name-based virtual hosting also eases -the demand for scarce IP addresses. Therefore you should use -name-based virtual hosting unless there is a specific reason to -choose IP-based virtual hosting. Some reasons why you might consider -using IP-based virtual hosting:

- - - -

Using Name-based Virtual Hosts

- - -
-Related Directives

- -DocumentRoot
-NameVirtualHost
-ServerAlias
-ServerName
-ServerPath
-VirtualHost
-
- -

To use name-based virtual hosting, you must designate the IP -address (and possibly port) on the server that will be accepting -requests for the hosts. This is configured using the NameVirtualHost directive. -In the normal case where any and all IP addresses on the server should -be used, you can use * as the argument to -NameVirtualHost. Note that mentioning an IP address in a -NameVirtualHost directive does not automatically make the -server listen to that IP address. See Setting -which addresses and ports Apache uses for more details. In addition, -any IP address specified here must be associated with a network interface -on the server.

- -

The next step is to create a <VirtualHost> block for -each different host that you would like to serve. The argument to the -<VirtualHost> directive should be the same as the -argument to the NameVirtualHost directive (ie, an IP -address, or * for all addresses). Inside each -<VirtualHost> block, you will need at minimum a ServerName directive to -designate which host is served and a DocumentRoot directive to -show where in the filesystem the content for that host lives.

- -

For example, suppose that both www.domain.tld and -www.otherdomain.tld point at an IP address -that the server is listening to. Then you simply add the following -to httpd.conf:

- -
-    NameVirtualHost *
-
-    <VirtualHost *>
-    ServerName www.domain.tld
-    DocumentRoot /www/domain
-    </VirtualHost>
-
-    <VirtualHost *>
-    ServerName www.otherdomain.tld
-    DocumentRoot /www/otherdomain
-    </VirtualHost>
-
- -

You can alternatively specify an explicit IP address in place of -the * in both the NameVirtualHost and -<VirtualHost> directives.

- -

Many servers want to be accessible by more than one name. This is -possible with the ServerAlias -directive, placed inside the <VirtualHost> section. For -example if you add this to the first <VirtualHost> block -above

- -
-ServerAlias domain.tld *.domain.tld -
- -

then requests for all hosts in the domain.tld domain -will be served by the www.domain.tld virtual host. The -wildcard characters * and ? can be used to match names. Of course, -you can't just make up names and place them in ServerName -or ServerAlias. You must first have your DNS server -properly configured to map those names to an IP address associated -with your server.

- -

Finally, you can fine-tune the configuration of the virtual hosts -by placing other directives inside the -<VirtualHost> containers. Most directives can be -placed in these containers and will then change the configuration only -of the relevant virtual host. To find out if a particular directive -is allowed, check the Context of the -directive. Configuration directives set in the main server -context (outside any <VirtualHost> container) -will be used only if they are not overriden by the virtual host -settings.

- -

Now when a request arrives, the server will first check if it is -using an IP address that matches the NameVirtualHost. If -it is, then it will look at each <VirtualHost> -section with a matching IP address and try to find one where the -ServerName or ServerAlias matches the -requested hostname. If it finds one, then it uses the configuration -for that server. If no matching virtual host is found, then -the first listed virtual host that matches the IP -address will be used.

- -

As a consequence, the first listed virtual host is the -default virtual host. The DocumentRoot from the -main server will never be used when an IP -address matches the NameVirtualHost directive. If you -would like to have a special configuration for requests that do not -match any particular virtual host, simply put that configuration in a -<VirtualHost> container and list it first in the -configuration file.

- -

Compatibility with Older Browsers

- -

As mentioned earlier, there are some clients - who do not send the required data for the name-based virtual - hosts to work properly. These clients will always be sent the - pages from the first virtual host listed for that IP address - (the primary name-based virtual host).

- -

There is a possible workaround with the ServerPath - directive, albeit a slightly cumbersome one:

- -

Example configuration:

-
-    NameVirtualHost 111.22.33.44
-
-    <VirtualHost 111.22.33.44>
-    ServerName www.domain.tld
-    ServerPath /domain
-    DocumentRoot /web/domain
-    </VirtualHost>
-
- -

What does this mean? It means that a request for any URI - beginning with "/domain" will be served from the - virtual host www.domain.tld This means that the - pages can be accessed as - http://www.domain.tld/domain/ for all clients, - although clients sending a Host: header can also - access it as http://www.domain.tld/.

- -

In order to make this work, put a link on your primary - virtual host's page to - http://www.domain.tld/domain/ Then, in the virtual - host's pages, be sure to use either purely relative links - (e.g., "file.html" or - "../icons/image.gif" or links containing the - prefacing /domain/ (e.g., - "http://www.domain.tld/domain/misc/file.html" or - "/domain/misc/file.html").

- -

This requires a bit of discipline, but adherence to these - guidelines will, for the most part, ensure that your pages will - work with all browsers, new and old.

- -

See also: ServerPath - configuration example

- - - - diff --git a/modules/experimental/mod_auth_ldap.c b/modules/experimental/mod_auth_ldap.c deleted file mode 100644 index 064484d5d7d..00000000000 --- a/modules/experimental/mod_auth_ldap.c +++ /dev/null @@ -1,866 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/* - * mod_auth_ldap.c: LDAP authentication module - * - * Original code from auth_ldap module for Apache v1.3: - * Copyright 1998, 1999 Enbridge Pipelines Inc. - * Copyright 1999-2001 Dave Carrigan - */ - -#include -#include - -#include "ap_config.h" -#if APR_HAVE_UNISTD_H -/* for getpid() */ -#include -#endif -#include - -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_log.h" -#include "http_protocol.h" -#include "http_request.h" -#include "util_ldap.h" - -#ifndef APU_HAS_LDAP -#error mod_auth_ldap requires APR-util to have LDAP support built in -#endif - -/* per directory configuration */ -typedef struct { - apr_pool_t *pool; /* Pool that this config is allocated from */ - apr_thread_mutex_t *lock; /* Lock for this config */ - int auth_authoritative; /* Is this auth method the one and only? */ - int enabled; /* Is auth_ldap enabled in this directory? */ - - /* These parameters are all derived from the AuthLDAPURL directive */ - char *url; /* String representation of the URL */ - - char *host; /* Name of the LDAP server (or space separated list) */ - int port; /* Port of the LDAP server */ - char *basedn; /* Base DN to do all searches from */ - char *attribute; /* Attribute to search for */ - char **attributes; /* Array of all the attributes to return */ - int scope; /* Scope of the search */ - char *filter; /* Filter to further limit the search */ - deref_options deref; /* how to handle alias dereferening */ - char *binddn; /* DN to bind to server (can be NULL) */ - char *bindpw; /* Password to bind to server (can be NULL) */ - - int frontpage_hack; /* Hack for frontpage support */ - int user_is_dn; /* If true, connection->user is DN instead of userid */ - int compare_dn_on_server; /* If true, will use server to do DN compare */ - - int have_ldap_url; /* Set if we have found an LDAP url */ - - apr_array_header_t *groupattr; /* List of Group attributes */ - int group_attrib_is_dn; /* If true, the group attribute is the DN, otherwise, - it's the exact string passed by the HTTP client */ - - int netscapessl; /* True if Netscape SSL is enabled */ - int starttls; /* True if StartTLS is enabled */ -} mod_auth_ldap_config_t; - -typedef struct mod_auth_ldap_request_t { - char *dn; /* The saved dn from a successful search */ - char *user; /* The username provided by the client */ -} mod_auth_ldap_request_t; - -/* maximum group elements supported */ -#define GROUPATTR_MAX_ELTS 10 - -struct mod_auth_ldap_groupattr_entry_t { - char *name; -}; - -module AP_MODULE_DECLARE_DATA auth_ldap_module; - -/* function prototypes */ -void mod_auth_ldap_build_filter(char *filtbuf, - request_rec *r, - mod_auth_ldap_config_t *sec); -int mod_auth_ldap_check_user_id(request_rec *r); -int mod_auth_ldap_auth_checker(request_rec *r); -void *mod_auth_ldap_create_dir_config(apr_pool_t *p, char *d); - -/* ---------------------------------------- */ - - -/* - * Build the search filter, or at least as much of the search filter that - * will fit in the buffer. We don't worry about the buffer not being able - * to hold the entire filter. If the buffer wasn't big enough to hold the - * filter, ldap_search_s will complain, but the only situation where this - * is likely to happen is if the client sent a really, really long - * username, most likely as part of an attack. - * - * The search filter consists of the filter provided with the URL, - * combined with a filter made up of the attribute provided with the URL, - * and the actual username passed by the HTTP client. For example, assume - * that the LDAP URL is - * - * ldap://ldap.airius.com/ou=People, o=Airius?uid??(posixid=*) - * - * Further, assume that the userid passed by the client was `userj'. The - * search filter will be (&(posixid=*)(uid=userj)). - */ -#define FILTER_LENGTH MAX_STRING_LEN -void mod_auth_ldap_build_filter(char *filtbuf, - request_rec *r, - mod_auth_ldap_config_t *sec) -{ - char *p, *q, *filtbuf_end; - /* - * Create the first part of the filter, which consists of the - * config-supplied portions. - */ - apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", sec->filter, sec->attribute); - - /* - * Now add the client-supplied username to the filter, ensuring that any - * LDAP filter metachars are escaped. - */ - filtbuf_end = filtbuf + FILTER_LENGTH - 1; - for (p = r->user, q=filtbuf + strlen(filtbuf); - *p && q < filtbuf_end; *q++ = *p++) { - if (strchr("*()\\", *p) != NULL) { - *q++ = '\\'; - if (q >= filtbuf_end) { - break; - } - } - } - *q = '\0'; - - /* - * Append the closing parens of the filter, unless doing so would - * overrun the buffer. - */ - if (q + 2 <= filtbuf_end) - strcat(filtbuf, "))"); -} - - -/* - * Authentication Phase - * -------------------- - * - * This phase authenticates the credentials the user has sent with - * the request (ie the username and password are checked). This is done - * by making an attempt to bind to the LDAP server using this user's - * DN and the supplied password. - * - */ -int mod_auth_ldap_check_user_id(request_rec *r) -{ - const char **vals = NULL; - char filtbuf[FILTER_LENGTH]; - mod_auth_ldap_config_t *sec = - (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, &auth_ldap_module); - - util_ldap_connection_t *ldc = NULL; - const char *sent_pw; - int result = 0; - const char *dn = NULL; - - mod_auth_ldap_request_t *req = - (mod_auth_ldap_request_t *)apr_pcalloc(r->pool, sizeof(mod_auth_ldap_request_t)); - ap_set_module_config(r->request_config, &auth_ldap_module, req); - - if (!sec->enabled) { - return DECLINED; - } - - /* - * Basic sanity checks before any LDAP operations even happen. - */ - if (!sec->have_ldap_url) { - return DECLINED; - } - - /* There is a good AuthLDAPURL, right? */ - if (sec->host) { - ldc = util_ldap_connection_find(r, sec->host, sec->port, - sec->binddn, sec->bindpw, sec->deref, - sec->netscapessl, sec->starttls); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authenticate: no sec->host - weird...?", getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authenticate: using URL %s", getpid(), sec->url); - - /* Get the password that the client sent */ - if ((result = ap_get_basic_auth_pw(r, &sent_pw))) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authenticate: " - "ap_get_basic_auth_pw() returns %d", getpid(), result); - util_ldap_connection_close(ldc); - return result; - } - - /* build the username filter */ - mod_auth_ldap_build_filter(filtbuf, r, sec); - - /* do the user search */ - result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope, - sec->attributes, filtbuf, sent_pw, &dn, &vals); - util_ldap_connection_close(ldc); - - if (result != LDAP_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authenticate: " - "user %s authentication failed; URI %s [%s][%s]", - getpid(), r->user, r->uri, ldc->reason, ldap_err2string(result)); - if (LDAP_INVALID_CREDENTIALS == result) { - ap_note_basic_auth_failure(r); - return HTTP_UNAUTHORIZED; - } - else { - return sec->auth_authoritative? HTTP_UNAUTHORIZED: DECLINED; - } - } - - /* mark the user and DN */ - req->dn = apr_pstrdup(r->pool, dn); - req->user = r->user; - if (sec->user_is_dn) { - r->user = req->dn; - } - - /* add environment variables */ - if (sec->attributes && vals) { - apr_table_t *e = r->subprocess_env; - int i = 0; - while (sec->attributes[i]) { - char *str = apr_pstrcat(r->pool, "AUTHENTICATE_", sec->attributes[i], NULL); - int j = 13; - while (str[j]) { - if (str[j] >= 'a' && str[j] <= 'z') { - str[j] = str[j] - ('a' - 'A'); - } - j++; - } - apr_table_setn(e, str, vals[i]); - i++; - } - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authenticate: accepting %s", getpid(), r->user); - - return OK; -} - - -/* - * Authorisation Phase - * ------------------- - * - * After checking whether the username and password are correct, we need - * to check whether that user is authorised to view this resource. The - * require directive is used to do this: - * - * require valid-user Any authenticated is allowed in. - * require user This particular user is allowed in. - * require group The user must be a member of this group - * in order to be allowed in. - * require dn The user must have the following DN in the - * LDAP tree to be let in. - * - */ -int mod_auth_ldap_auth_checker(request_rec *r) -{ - int result = 0; - mod_auth_ldap_request_t *req = - (mod_auth_ldap_request_t *)ap_get_module_config(r->request_config, - &auth_ldap_module); - mod_auth_ldap_config_t *sec = - (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, - &auth_ldap_module); - - util_ldap_connection_t *ldc = NULL; - int m = r->method_number; - - const apr_array_header_t *reqs_arr = ap_requires(r); - require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL; - - register int x; - const char *t; - char *w; - int method_restricted = 0; - - if (!sec->enabled) { - return DECLINED; - } - - if (!sec->have_ldap_url) { - return DECLINED; - } - - if (sec->host) { - ldc = util_ldap_connection_find(r, sec->host, sec->port, - sec->binddn, sec->bindpw, sec->deref, - sec->netscapessl, sec->starttls); - } - else { - ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: no sec->host - weird...?", getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - - /* - * If there are no elements in the group attribute array, the default should be - * member and uniquemember; populate the array now. - */ - if (sec->groupattr->nelts == 0) { - struct mod_auth_ldap_groupattr_entry_t *grp; - apr_thread_mutex_lock(sec->lock); - grp = apr_array_push(sec->groupattr); - grp->name = "member"; - grp = apr_array_push(sec->groupattr); - grp->name = "uniquemember"; - apr_thread_mutex_unlock(sec->lock); - } - - if (!reqs_arr) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: no requirements array", getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - - /* Loop through the requirements array until there's no elements - * left, or something causes a return from inside the loop */ - for(x=0; x < reqs_arr->nelts; x++) { - if (! (reqs[x].method_mask & (1 << m))) { - continue; - } - method_restricted = 1; - - t = reqs[x].requirement; - w = ap_getword(r->pool, &t, ' '); - - if (strcmp(w, "valid-user") == 0) { - /* - * Valid user will always be true if we authenticated with ldap, - * but when using front page, valid user should only be true if - * he exists in the frontpage password file. This hack will get - * auth_ldap to look up the user in the the pw file to really be - * sure that he's valid. Naturally, it requires mod_auth to be - * compiled in, but if mod_auth wasn't in there, then the need - * for this hack wouldn't exist anyway. - */ - if (sec->frontpage_hack) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "deferring authorisation to mod_auth (FP Hack)", - getpid()); - return OK; - } - else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "successful authorisation because user " - "is valid-user", getpid()); - return OK; - } - } - else if (strcmp(w, "user") == 0) { - if (req->dn == NULL || strlen(req->dn) == 0) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require user: user's DN has not been defined; failing authorisation", - getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - /* - * First do a whole-line compare, in case it's something like - * require user Babs Jensen - */ - result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, t); - switch(result) { - case LDAP_COMPARE_TRUE: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require user: authorisation successful", getpid()); - return OK; - } - default: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require user: " - "authorisation failed [%s][%s]", getpid(), - ldc->reason, ldap_err2string(result)); - } - } - /* - * Now break apart the line and compare each word on it - */ - while (t[0]) { - w = ap_getword_conf(r->pool, &t); - result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, w); - switch(result) { - case LDAP_COMPARE_TRUE: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require user: authorisation successful", getpid()); - return OK; - } - default: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require user: authorisation failed [%s][%s]", - getpid(), ldc->reason, ldap_err2string(result)); - } - } - } - } - else if (strcmp(w, "dn") == 0) { - if (req->dn == NULL || strlen(req->dn) == 0) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require dn: user's DN has not been defined; failing authorisation", - getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - - result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, t, sec->compare_dn_on_server); - switch(result) { - case LDAP_COMPARE_TRUE: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require dn: authorisation successful", getpid()); - return OK; - } - default: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: " - "require dn: LDAP error [%s][%s]", - getpid(), ldc->reason, ldap_err2string(result)); - } - } - } - else if (strcmp(w, "group") == 0) { - struct mod_auth_ldap_groupattr_entry_t *ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts; - int i; - - if (sec->group_attrib_is_dn) { - if (req->dn == NULL || strlen(req->dn) == 0) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require group: user's DN has not been defined; failing authorisation", - getpid()); - return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; - } - } - else { - if (req->user == NULL || strlen(req->user) == 0) { - /* We weren't called in the authentication phase, so we didn't have a - * chance to set the user field. Do so now. */ - req->user = r->user; - } - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require group: testing for group membership in `%s'", - getpid(), t); - - for (i = 0; i < sec->groupattr->nelts; i++) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require group: testing for %s: %s (%s)", getpid(), - ent[i].name, sec->group_attrib_is_dn ? req->dn : req->user, t); - - result = util_ldap_cache_compare(r, ldc, sec->url, t, ent[i].name, - sec->group_attrib_is_dn ? req->dn : req->user); - switch(result) { - case LDAP_COMPARE_TRUE: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require group: " - "authorisation successful (attribute %s) [%s][%s]", - getpid(), ent[i].name, ldc->reason, ldap_err2string(result)); - return OK; - } - default: { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: require group: " - "authorisation failed [%s][%s]", - getpid(), ldc->reason, ldap_err2string(result)); - } - } - } - } - } - - if (!method_restricted) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: agreeing because non-restricted", - getpid()); - return OK; - } - - if (!sec->auth_authoritative) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: declining to authorise", getpid()); - return DECLINED; - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, - "[%d] auth_ldap authorise: authorisation denied", getpid()); - ap_note_basic_auth_failure (r); - - return HTTP_UNAUTHORIZED; -} - - -/* ---------------------------------------- */ -/* config directives */ - - -void *mod_auth_ldap_create_dir_config(apr_pool_t *p, char *d) -{ - mod_auth_ldap_config_t *sec = - (mod_auth_ldap_config_t *)apr_pcalloc(p, sizeof(mod_auth_ldap_config_t)); - - sec->pool = p; - apr_thread_mutex_create(&sec->lock, APR_THREAD_MUTEX_DEFAULT, p); - sec->auth_authoritative = 1; - sec->enabled = 1; - sec->groupattr = apr_array_make(p, GROUPATTR_MAX_ELTS, - sizeof(struct mod_auth_ldap_groupattr_entry_t)); - - sec->have_ldap_url = 0; - sec->url = ""; - sec->host = NULL; - sec->binddn = NULL; - sec->bindpw = NULL; - sec->deref = always; - sec->group_attrib_is_dn = 1; - - sec->frontpage_hack = 0; - sec->netscapessl = 0; - sec->starttls = 0; - - sec->user_is_dn = 0; - sec->compare_dn_on_server = 0; - - return sec; -} - -/* - * Use the ldap url parsing routines to break up the ldap url into - * host and port. - */ -static const char *mod_auth_ldap_parse_url(cmd_parms *cmd, - void *config, - const char *url) -{ - int result; - LDAPURLDesc *urld; - - mod_auth_ldap_config_t *sec = config; - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: `%s'", - getpid(), url); - - result = ldap_url_parse(url, &(urld)); - if (result != LDAP_SUCCESS) { - switch (result) { - case LDAP_URL_ERR_NOTLDAP: - return "LDAP URL does not begin with ldap://"; - case LDAP_URL_ERR_NODN: - return "LDAP URL does not have a DN"; - case LDAP_URL_ERR_BADSCOPE: - return "LDAP URL has an invalid scope"; - case LDAP_URL_ERR_MEM: - return "Out of memory parsing LDAP URL"; - default: - return "Could not parse LDAP URL"; - } - } - sec->url = apr_pstrdup(cmd->pool, url); - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: Host: %s", getpid(), urld->lud_host); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: Port: %d", getpid(), urld->lud_port); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: DN: %s", getpid(), urld->lud_dn); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: attrib: %s", getpid(), urld->lud_attrs? urld->lud_attrs[0] : "(null)"); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: scope: %s", getpid(), - (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" : - urld->lud_scope == LDAP_SCOPE_BASE? "base" : - urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown")); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap url parse: filter: %s", getpid(), urld->lud_filter); - - /* Set all the values, or at least some sane defaults */ - if (sec->host) { - char *p = apr_palloc(cmd->pool, strlen(sec->host) + strlen(urld->lud_host) + 2); - strcpy(p, urld->lud_host); - strcat(p, " "); - strcat(p, sec->host); - sec->host = p; - } - else { - sec->host = urld->lud_host? apr_pstrdup(cmd->pool, urld->lud_host) : "localhost"; - } - sec->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : ""; - if (urld->lud_attrs && urld->lud_attrs[0]) { - int i = 1; - while (urld->lud_attrs[i]) { - i++; - } - sec->attributes = apr_pcalloc(cmd->pool, sizeof(char *) * (i+1)); - i = 0; - while (urld->lud_attrs[i]) { - sec->attributes[i] = apr_pstrdup(cmd->pool, urld->lud_attrs[i]); - i++; - } - sec->attribute = sec->attributes[0]; - } - else { - sec->attribute = "uid"; - } - - sec->scope = urld->lud_scope == LDAP_SCOPE_ONELEVEL ? - LDAP_SCOPE_ONELEVEL : LDAP_SCOPE_SUBTREE; - - if (urld->lud_filter) { - if (urld->lud_filter[0] == '(') { - /* - * Get rid of the surrounding parens; later on when generating the - * filter, they'll be put back. - */ - sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter+1); - sec->filter[strlen(sec->filter)-1] = '\0'; - } - else { - sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter); - } - } - else { - sec->filter = "objectclass=*"; - } - if (strncmp(url, "ldaps", 5) == 0) { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap parse url: requesting secure LDAP", getpid()); -#ifdef APU_HAS_LDAP_STARTTLS - sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT; - sec->starttls = 1; -#else -#ifdef APU_HAS_LDAP_NETSCAPE_SSL - sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT; - sec->netscapessl = 1; -#else - return "Secure LDAP (ldaps://) not supported. Rebuild APR-Util"; -#endif -#endif - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, - cmd->server, "[%d] auth_ldap parse url: not requesting secure LDAP", getpid()); - sec->netscapessl = 0; - sec->starttls = 0; - sec->port = urld->lud_port? urld->lud_port : LDAP_PORT; - } - - sec->have_ldap_url = 1; - ldap_free_urldesc(urld); - return NULL; -} - -static const char *mod_auth_ldap_set_deref(cmd_parms *cmd, void *config, const char *arg) -{ - mod_auth_ldap_config_t *sec = config; - - if (strcmp(arg, "never") == 0 || strcasecmp(arg, "off") == 0) { - sec->deref = never; - } - else if (strcmp(arg, "searching") == 0) { - sec->deref = searching; - } - else if (strcmp(arg, "finding") == 0) { - sec->deref = finding; - } - else if (strcmp(arg, "always") == 0 || strcasecmp(arg, "on") == 0) { - sec->deref = always; - } - else { - return "Unrecognized value for AuthLDAPAliasDereference directive"; - } - return NULL; -} - -static const char *mod_auth_ldap_add_group_attribute(cmd_parms *cmd, void *config, const char *arg) -{ - struct mod_auth_ldap_groupattr_entry_t *new; - - mod_auth_ldap_config_t *sec = config; - - if (sec->groupattr->nelts > GROUPATTR_MAX_ELTS) - return "Too many AuthLDAPGroupAttribute directives"; - - new = apr_array_push(sec->groupattr); - new->name = apr_pstrdup(cmd->pool, arg); - - return NULL; -} - -command_rec mod_auth_ldap_cmds[] = { - AP_INIT_TAKE1("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG, - "URL to define LDAP connection. This should be an RFC 2255 complaint\n" - "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n" - "
    \n" - "
  • Host is the name of the LDAP server. Use a space separated list of hosts \n" - "to specify redundant servers.\n" - "
  • Port is optional, and specifies the port to connect to.\n" - "
  • basedn specifies the base DN to start searches from\n" - "
  • Attrib specifies what attribute to search for in the directory. If not " - "provided, it defaults to uid.\n" - "
  • Scope is the scope of the search, and can be either sub or " - "one. If not provided, the default is sub.\n" - "
  • Filter is a filter to use in the search. If not provided, " - "defaults to (objectClass=*).\n" - "
\n" - "Searches are performed using the attribute and the filter combined. " - "For example, assume that the\n" - "LDAP URL is ldap://ldap.airius.com/ou=People, o=Airius?uid?sub?(posixid=*). " - "Searches will\n" - "be done using the filter (&((posixid=*))(uid=username)), " - "where username\n" - "is the user name passed by the HTTP client. The search will be a subtree " - "search on the branch ou=People, o=Airius."), - - AP_INIT_TAKE1("AuthLDAPBindDN", ap_set_string_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, binddn), OR_AUTHCFG, - "DN to use to bind to LDAP server. If not provided, will do an anonymous bind."), - - AP_INIT_TAKE1("AuthLDAPBindPassword", ap_set_string_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, bindpw), OR_AUTHCFG, - "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."), - - AP_INIT_FLAG("AuthLDAPRemoteUserIsDN", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, user_is_dn), OR_AUTHCFG, - "Set to 'on' to set the REMOTE_USER environment variable to be the full " - "DN of the remote user. By default, this is set to off, meaning that " - "the REMOTE_USER variable will contain whatever value the remote user sent."), - - AP_INIT_FLAG("AuthLDAPAuthoritative", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, auth_authoritative), OR_AUTHCFG, - "Set to 'off' to allow access control to be passed along to lower modules if " - "the UserID and/or group is not known to this module"), - - AP_INIT_FLAG("AuthLDAPCompareDNOnServer", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, compare_dn_on_server), OR_AUTHCFG, - "Set to 'on' to force auth_ldap to do DN compares (for the \"require dn\" " - "directive) using the server, and set it 'off' to do the compares locally " - "(at the expense of possible false matches). See the documentation for " - "a complete description of this option."), - - AP_INIT_ITERATE("AuthLDAPGroupAttribute", mod_auth_ldap_add_group_attribute, NULL, OR_AUTHCFG, - "A list of attributes used to define group membership - defaults to " - "member and uniquemember"), - - AP_INIT_FLAG("AuthLDAPGroupAttributeIsDN", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, group_attrib_is_dn), OR_AUTHCFG, - "If set to 'on', auth_ldap uses the DN that is retrieved from the server for" - "subsequent group comparisons. If set to 'off', auth_ldap uses the string" - "provided by the client directly. Defaults to 'on'."), - - AP_INIT_TAKE1("AuthLDAPDereferenceAliases", mod_auth_ldap_set_deref, NULL, OR_AUTHCFG, - "Determines how aliases are handled during a search. Can bo one of the" - "values \"never\", \"searching\", \"finding\", or \"always\". " - "Defaults to always."), - - AP_INIT_FLAG("AuthLDAPEnabled", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, enabled), OR_AUTHCFG, - "Set to off to disable auth_ldap, even if it's been enabled in a higher tree"), - - AP_INIT_FLAG("AuthLDAPFrontPageHack", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, frontpage_hack), OR_AUTHCFG, - "Set to 'on' to support Microsoft FrontPage"), - -#ifdef APU_HAS_LDAP_STARTTLS - AP_INIT_FLAG("AuthLDAPStartTLS", ap_set_flag_slot, - (void *)APR_OFFSETOF(mod_auth_ldap_config_t, starttls), OR_AUTHCFG, - "Set to 'on' to start TLS after connecting to the LDAP server."), -#endif /* APU_HAS_LDAP_STARTTLS */ - - {NULL} -}; - -static void mod_auth_ldap_register_hooks(apr_pool_t *p) -{ - ap_hook_check_user_id(mod_auth_ldap_check_user_id, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_auth_checker(mod_auth_ldap_auth_checker, NULL, NULL, APR_HOOK_MIDDLE); -} - -module auth_ldap_module = { - STANDARD20_MODULE_STUFF, - mod_auth_ldap_create_dir_config, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - NULL, /* server config */ - NULL, /* merge server config */ - mod_auth_ldap_cmds, /* command table */ - mod_auth_ldap_register_hooks, /* set up request processing hooks */ -}; diff --git a/modules/experimental/mod_auth_ldap.def b/modules/experimental/mod_auth_ldap.def deleted file mode 100644 index 599636fb491..00000000000 --- a/modules/experimental/mod_auth_ldap.def +++ /dev/null @@ -1,6 +0,0 @@ -IMPORT util_ldap_connection_find -IMPORT util_ldap_connection_close -IMPORT util_ldap_cache_checkuserid -IMPORT util_ldap_cache_compare -IMPORT util_ldap_cache_comparedn -EXPORT auth_ldap_module diff --git a/modules/experimental/util_ldap.c b/modules/experimental/util_ldap.c deleted file mode 100644 index 9bd7682b725..00000000000 --- a/modules/experimental/util_ldap.c +++ /dev/null @@ -1,1110 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/* - * util_ldap.c: LDAP things - * - * Original code from auth_ldap module for Apache v1.3: - * Copyright 1998, 1999 Enbridge Pipelines Inc. - * Copyright 1999-2001 Dave Carrigan - */ - -#include -#include - -#include "ap_config.h" -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_log.h" -#include "http_protocol.h" -#include "http_request.h" -#include "util_ldap.h" -#include "util_ldap_cache.h" - -#if APR_HAVE_UNISTD_H -#include -#endif - -#ifndef APU_HAS_LDAP -#error mod_ldap requires APR-util to have LDAP support built in -#endif - -module AP_MODULE_DECLARE_DATA ldap_module; - -int util_ldap_handler(request_rec *r); -void *util_ldap_create_config(apr_pool_t *p, server_rec *s); - - -/* - * Some definitions to help between various versions of apache. - */ - -#ifndef DOCTYPE_HTML_2_0 -#define DOCTYPE_HTML_2_0 "\n" -#endif - -#ifndef DOCTYPE_HTML_3_2 -#define DOCTYPE_HTML_3_2 "\n" -#endif - -#ifndef DOCTYPE_HTML_4_0S -#define DOCTYPE_HTML_4_0S "\n" -#endif - -#ifndef DOCTYPE_HTML_4_0T -#define DOCTYPE_HTML_4_0T "\n" -#endif - -#ifndef DOCTYPE_HTML_4_0F -#define DOCTYPE_HTML_4_0F "\n" -#endif - -/* - * Status Handler - * -------------- - * - * This handler generates a status page about the current performance of - * the LDAP cache. It is enabled as follows: - * - * - * SetHandler ldap-status - * - * - */ -int util_ldap_handler(request_rec *r) -{ - - r->allowed |= (1 << M_GET); - if (r->method_number != M_GET) - return DECLINED; - - if (strcmp(r->handler, "ldap-status")) { - return DECLINED; - } - - r->content_type = "text/html"; - if (r->header_only) - return OK; - - ap_rputs(DOCTYPE_HTML_3_2 - "LDAP Cache Information\n", r); - ap_rputs("

LDAP Cache Information

\n", r); - - ap_rputs("

\n" - "\n" - "\n" - "" - "" - "" - "" - "" - "" - "" - "\n", r - ); - - ap_rputs(util_ald_cache_display(r->pool), r); - - ap_rputs("
Cache NameEntriesAvg. Chain Len.HitsIns/RemPurgesAvg Purge Time
\n

\n", r); - - return OK; -} - -/* ------------------------------------------------------------------ */ - - -/* - * Closes an LDAP connection by unlocking it. The next time - * util_ldap_connection_find() is called this connection will be - * available for reuse. - */ -void util_ldap_connection_close(util_ldap_connection_t *ldc) -{ - - /* - * QUESTION: - * - * Is it safe leaving bound connections floating around between the - * different modules? Keeping the user bound is a performance boost, - * but it is also a potential security problem - maybe. - * - * For now we unbind the user when we finish with a connection, but - * we don't have to... - */ - - /* mark our connection as available for reuse */ - apr_thread_mutex_unlock(ldc->lock); - -} - - -/* - * Destroys an LDAP connection by unbinding. This function is registered - * with the pool cleanup function - causing the LDAP connections to be - * shut down cleanly on graceful restart. - */ -apr_status_t util_ldap_connection_destroy(void *param) -{ - util_ldap_connection_t *ldc = param; - - /* unbinding from the LDAP server */ - if (ldc->ldap) { - ldap_unbind_s(ldc->ldap); - ldc->bound = 0; - ldc->ldap = NULL; - } - - /* release the lock we were using. The lock should have - already been released in the close connection call. - But just in case it wasn't, we first try to get the lock - before unlocking it to avoid unlocking an unheld lock. - Unlocking an unheld lock causes problems on NetWare. The - other option would be to assume that close connection did - its job. */ - apr_thread_mutex_trylock(ldc->lock); - apr_thread_mutex_unlock(ldc->lock); - - return APR_SUCCESS; -} - - -/* - * Connect to the LDAP server and binds. Does not connect if already - * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound. - * - * Returns LDAP_SUCCESS on success; and an error code on failure - */ -int util_ldap_connection_open(util_ldap_connection_t *ldc) -{ - int result = 0; - int failures = 0; - - -start_over: - if (failures++ > 10) { - /* too many failures - leave */ - return result; - } - - if (!ldc->ldap) { - ldc->bound = 0; - - /* opening connection to LDAP server */ - if ((ldc->ldap = ldap_init(ldc->host, ldc->port)) == NULL) { - /* couldn't connect */ - ldc->reason = "ldap_init() failed"; - return -1; - } - - /* add the cleanup to the pool */ - apr_pool_cleanup_register(ldc->pool, ldc, - util_ldap_connection_destroy, - apr_pool_cleanup_null); - - /* Set the alias dereferencing option */ -#if LDAP_VERSION_MAX == 2 - ldc->ldap->ld_deref = ldc->deref; -#else - result = ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &(ldc->deref)); - if (result != LDAP_SUCCESS) { - /* setting LDAP dereference option failed */ - /* we ignore this error */ - } -#endif /* LDAP_VERSION_MAX */ - -#ifdef APU_HAS_LDAP_NETSCAPE_SSL - if (ldc->netscapessl) { - if (!ldc->certdb) { - /* secure LDAP requested, but no CA cert defined */ - ldc->reason = "secure LDAP requested, but no CA cert defined"; - return -1; - } else { - result = ldapssl_install_routines(ldc->ldap); - if (result != LDAP_SUCCESS) { - /* SSL initialisation failed */ - ldc->reason = "ldapssl_install_routines() failed"; - return result; - } - result = ldap_set_option(ldc->ldap, LDAP_OPT_SSL, LDAP_OPT_ON); - if (result != LDAP_SUCCESS) { - /* SSL option failed */ - ldc->reason = "ldap_set_option() failed trying to set LDAP_OPT_SSL"; - return result; - } - } - } -#endif /* APU_HAS_LDAP_NETSCAPE_SSL */ - -#ifdef APU_HAS_LDAP_STARTTLS - if (ldc->starttls) { - int version = LDAP_VERSION3; - - /* Also we have to set the connection to use protocol version 3, - * since we're using TLS. */ - if ((result = ldap_set_option(ldc->ldap, LDAP_OPT_PROTOCOL_VERSION, - &version)) != LDAP_SUCCESS) { - /* setting LDAP version failed - ignore error */ - } - - /* - * In util_ldap_connection_find, we compare ldc->withtls to - * sec->starttls to see if we have a cache match. On the off - * chance that apache's config processing rotines set starttls to - * some other true value besides 1, we set it to 1 here to ensure - * that the comparison succeeds. - */ - ldc->starttls = 1; - - result = ldap_start_tls_s(ldc->ldap, NULL, NULL); - if (result != LDAP_SUCCESS) { - /* start TLS failed */ - ldc->withtls = 0; - ldc->reason = "ldap_start_tls_s() failed"; - return result; - } - ldc->withtls = 1; - } else { - ldc->withtls = 0; - } -#endif /* APU_HAS_LDAP_STARTTLS */ - } - - /* - * At this point the LDAP connection is guaranteed alive. If bound says - * that we're bound already, we can just return. - */ - if (ldc->bound) { - ldc->reason = "LDAP connection open successful (already bound)"; - return LDAP_SUCCESS; - } - - /* - * Now bind with the username/password provided by the - * configuration. It will be an anonymous bind if no u/p was - * provided. - */ - if ((result = ldap_simple_bind_s(ldc->ldap, ldc->binddn, ldc->bindpw)) - == LDAP_SERVER_DOWN) { - /* couldn't connect - try again */ - ldc->reason = "ldap_simple_bind_s() failed with server down"; - goto start_over; - } - - if (result != LDAP_SUCCESS) { - /* LDAP fatal error occured */ - ldc->reason = "ldap_simple_bind_s() failed"; - return result; - } - - /* note how we are bound */ - ldc->bound = 1; - - ldc->reason = "LDAP connection open successful"; - return LDAP_SUCCESS; -} - - -/* - * Find an existing ldap connection struct that matches the - * provided ldap connection parameters. - * - * If not found in the cache, a new ldc structure will be allocated from st->pool - * and returned to the caller. If found in the cache, a pointer to the existing - * ldc structure will be returned. - */ -util_ldap_connection_t *util_ldap_connection_find(request_rec *r, const char *host, int port, - const char *binddn, const char *bindpw, deref_options deref, - int netscapessl, int starttls) -{ - struct util_ldap_connection_t *l, *p; /* To traverse the linked list */ - - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(r->server->module_config, - &ldap_module); - - - /* mutex lock this function */ - if (!st->mutex) { - apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool); - } - apr_thread_mutex_lock(st->mutex); - - /* Search for an exact connection match in the list that is not - * being used. - */ - for (l=st->connections,p=NULL; l; l=l->next) { - if ( (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) - && l->port == port - && strcmp(l->host, host) == 0 - && ( (!l->binddn && !binddn) || (l->binddn && binddn && !strcmp(l->binddn, binddn)) ) - && ( (!l->bindpw && !bindpw) || (l->bindpw && bindpw && !strcmp(l->bindpw, bindpw)) ) - && l->deref == deref -#ifdef APU_HAS_LDAP_NETSCAPE_SSL - && l->netscapessl == netscapessl -#endif -#ifdef APU_HAS_LDAP_STARTTLS - && l->withtls == starttls -#endif - ) - break; - p = l; - } - - /* If nothing found, search again, but we don't care about the - * binddn and bindpw this time. - */ - if (!l) { - for (l=st->connections,p=NULL; l; l=l->next) { - if ( (APR_SUCCESS == apr_thread_mutex_trylock(l->lock)) - && l->port == port - && strcmp(l->host, host) == 0 - && l->deref == deref -#ifdef APU_HAS_LDAP_NETSCAPE_SSL - && l->netscapessl == netscapessl -#endif -#ifdef APU_HAS_LDAP_STARTTLS - && l->withtls == starttls -#endif - ) { - /* the bind credentials have changed */ - l->bound = 0; - l->binddn = apr_pstrdup(st->pool, binddn); - l->bindpw = apr_pstrdup(st->pool, bindpw); - break; - } - p = l; - } - } - -/* artificially disable cache */ -//l = NULL; - - /* If no connection what found after the second search, we - * must create one. - */ - if (!l) { - - /* - * Add the new connection entry to the linked list. Note that we - * don't actually establish an LDAP connection yet; that happens - * the first time authentication is requested. - */ - /* create the details to the pool in st */ - l = apr_pcalloc(st->pool, sizeof(util_ldap_connection_t)); - apr_thread_mutex_create(&l->lock, APR_THREAD_MUTEX_DEFAULT, st->pool); - apr_thread_mutex_lock(l->lock); - l->pool = st->pool; - l->bound = 0; - l->host = apr_pstrdup(st->pool, host); - l->port = port; - l->deref = deref; - l->binddn = apr_pstrdup(st->pool, binddn); - l->bindpw = apr_pstrdup(st->pool, bindpw); - l->netscapessl = netscapessl; - l->starttls = starttls; - l->withtls = 0; - - if (p) { - p->next = l; - } - else { - st->connections = l; - } - } - - apr_thread_mutex_unlock(st->mutex); - return l; -} - -/* ------------------------------------------------------------------ */ - -/* - * Compares two DNs to see if they're equal. The only way to do this correctly is to - * search for the dn and then do ldap_get_dn() on the result. This should match the - * initial dn, since it would have been also retrieved with ldap_get_dn(). This is - * expensive, so if the configuration value compare_dn_on_server is - * false, just does an ordinary strcmp. - * - * The lock for the ldap cache should already be acquired. - */ -int util_ldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, - const char *url, const char *dn, const char *reqdn, - int compare_dn_on_server) -{ - int result = 0; - util_url_node_t *curl; - util_url_node_t curnode; - util_dn_compare_node_t *node; - util_dn_compare_node_t newnode; - int failures = 0; - LDAPMessage *res, *entry; - char *searchdn; - - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(r->server->module_config, - &ldap_module); - - - /* read lock this function */ - if (!util_ldap_cache_lock) { - apr_thread_rwlock_create(&util_ldap_cache_lock, st->pool); - } - - /* get cache entry (or create one) */ - apr_thread_rwlock_wrlock(util_ldap_cache_lock); - curnode.url = url; - curl = util_ald_cache_fetch(util_ldap_cache, &curnode); - if (curl == NULL) { - curl = util_ald_create_caches(st, url); - } - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - /* a simple compare? */ - if (!compare_dn_on_server) { - /* unlock this read lock */ - if (strcmp(dn, reqdn)) { - ldc->reason = "DN Comparison FALSE (direct strcmp())"; - return LDAP_COMPARE_FALSE; - } - else { - ldc->reason = "DN Comparison TRUE (direct strcmp())"; - return LDAP_COMPARE_TRUE; - } - } - - /* no - it's a server side compare */ - apr_thread_rwlock_rdlock(util_ldap_cache_lock); - - /* is it in the compare cache? */ - newnode.reqdn = (char *)reqdn; - node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); - if (node != NULL) { - /* If it's in the cache, it's good */ - /* unlock this read lock */ - apr_thread_rwlock_unlock(util_ldap_cache_lock); - ldc->reason = "DN Comparison TRUE (cached)"; - return LDAP_COMPARE_TRUE; - } - - /* unlock this read lock */ - apr_thread_rwlock_unlock(util_ldap_cache_lock); - -start_over: - if (failures++ > 10) { - /* too many failures */ - return result; - } - - /* make a server connection */ - if (LDAP_SUCCESS != (result = util_ldap_connection_open(ldc))) { - /* connect to server failed */ - return result; - } - - /* search for reqdn */ - if ((result = ldap_search_ext_s(ldc->ldap, const_cast(reqdn), LDAP_SCOPE_BASE, - "(objectclass=*)", NULL, 1, - NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { - util_ldap_connection_close(ldc); - ldc->reason = "DN Comparison ldap_search_ext_s() failed with server down"; - goto start_over; - } - if (result != LDAP_SUCCESS) { - /* search for reqdn failed - no match */ - ldc->reason = "DN Comparison ldap_search_ext_s() failed"; - return result; - } - - entry = ldap_first_entry(ldc->ldap, res); - searchdn = ldap_get_dn(ldc->ldap, entry); - - ldap_msgfree(res); - if (strcmp(dn, searchdn) != 0) { - /* compare unsuccessful */ - ldc->reason = "DN Comparison FALSE (checked on server)"; - result = LDAP_COMPARE_FALSE; - } - else { - /* compare successful - add to the compare cache */ - apr_thread_rwlock_rdlock(util_ldap_cache_lock); - newnode.reqdn = (char *)reqdn; - newnode.dn = (char *)dn; - util_ald_cache_insert(curl->dn_compare_cache, &newnode); - apr_thread_rwlock_unlock(util_ldap_cache_lock); - ldc->reason = "DN Comparison TRUE (checked on server)"; - result = LDAP_COMPARE_TRUE; - } - ldap_memfree(searchdn); - return result; - -} - -/* - * Does an generic ldap_compare operation. It accepts a cache that it will use - * to lookup the compare in the cache. We cache two kinds of compares - * (require group compares) and (require user compares). Each compare has a different - * cache node: require group includes the DN; require user does not because the - * require user cache is owned by the - * - */ -int util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, - const char *url, const char *dn, - const char *attrib, const char *value) -{ - int result = 0; - util_url_node_t *curl; - util_url_node_t curnode; - util_compare_node_t *compare_nodep; - util_compare_node_t the_compare_node; - apr_time_t curtime; - int failures = 0; - - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(r->server->module_config, - &ldap_module); - - - /* read lock this function */ - if (!util_ldap_cache_lock) { - apr_thread_rwlock_create(&util_ldap_cache_lock, st->pool); - } - - /* get cache entry (or create one) */ - apr_thread_rwlock_wrlock(util_ldap_cache_lock); - curnode.url = url; - curl = util_ald_cache_fetch(util_ldap_cache, &curnode); - if (curl == NULL) { - curl = util_ald_create_caches(st, url); - } - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - /* make a comparison to the cache */ - apr_thread_rwlock_rdlock(util_ldap_cache_lock); - curtime = apr_time_now(); - - the_compare_node.dn = (char *)dn; - the_compare_node.attrib = (char *)attrib; - the_compare_node.value = (char *)value; - the_compare_node.result = 0; - - compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node); - - if (compare_nodep != NULL) { - /* found it... */ - if (curtime - compare_nodep->lastcompare > st->compare_cache_ttl) { - /* ...but it is too old */ - util_ald_cache_remove(curl->compare_cache, compare_nodep); - } - else { - /* ...and it is good */ - /* unlock this read lock */ - apr_thread_rwlock_unlock(util_ldap_cache_lock); - if (LDAP_COMPARE_TRUE == compare_nodep->result) { - ldc->reason = "Comparison true (cached)"; - return compare_nodep->result; - } - else if (LDAP_COMPARE_FALSE == compare_nodep->result) { - ldc->reason = "Comparison false (cached)"; - return compare_nodep->result; - } - else if (LDAP_NO_SUCH_ATTRIBUTE == compare_nodep->result) { - ldc->reason = "Comparison no such attribute (cached)"; - return compare_nodep->result; - } - else { - ldc->reason = "Comparison undefined (cached)"; - return compare_nodep->result; - } - } - } - /* unlock this read lock */ - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - -start_over: - if (failures++ > 10) { - /* too many failures */ - return result; - } - if (LDAP_SUCCESS != (result = util_ldap_connection_open(ldc))) { - /* connect failed */ - return result; - } - - if ((result = ldap_compare_s(ldc->ldap, const_cast(dn), - const_cast(attrib), const_cast(value))) - == LDAP_SERVER_DOWN) { - /* connection failed - try again */ - util_ldap_connection_close(ldc); - ldc->reason = "ldap_compare_s() failed with server down"; - goto start_over; - } - - ldc->reason = "Comparison complete"; - if ((LDAP_COMPARE_TRUE == result) || - (LDAP_COMPARE_FALSE == result) || - (LDAP_NO_SUCH_ATTRIBUTE == result)) { - /* compare completed; caching result */ - apr_thread_rwlock_wrlock(util_ldap_cache_lock); - the_compare_node.lastcompare = curtime; - the_compare_node.result = result; - util_ald_cache_insert(curl->compare_cache, &the_compare_node); - apr_thread_rwlock_unlock(util_ldap_cache_lock); - if (LDAP_COMPARE_TRUE == result) { - ldc->reason = "Comparison true (adding to cache)"; - return LDAP_COMPARE_TRUE; - } - else if (LDAP_COMPARE_FALSE == result) { - ldc->reason = "Comparison false (adding to cache)"; - return LDAP_COMPARE_FALSE; - } - else { - ldc->reason = "Comparison no such attribute (adding to cache)"; - return LDAP_NO_SUCH_ATTRIBUTE; - } - } - return result; -} - -int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, - const char *url, const char *basedn, int scope, char **attrs, - const char *filter, const char *bindpw, const char **binddn, - const char ***retvals) -{ - const char **vals = NULL; - int result = 0; - LDAPMessage *res, *entry; - char *dn; - int count; - int failures = 0; - util_url_node_t *curl; /* Cached URL node */ - util_url_node_t curnode; - util_search_node_t *search_nodep; /* Cached search node */ - util_search_node_t the_search_node; - apr_time_t curtime; - - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(r->server->module_config, - &ldap_module); - - /* read lock this function */ - if (!util_ldap_cache_lock) { - apr_thread_rwlock_create(&util_ldap_cache_lock, st->pool); - } - - /* Get the cache node for this url */ - apr_thread_rwlock_wrlock(util_ldap_cache_lock); - curnode.url = url; - curl = (util_url_node_t *)util_ald_cache_fetch(util_ldap_cache, &curnode); - if (curl == NULL) { - curl = util_ald_create_caches(st, url); - } - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - apr_thread_rwlock_rdlock(util_ldap_cache_lock); - the_search_node.username = filter; - search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); - if (search_nodep != NULL && search_nodep->bindpw) { - - /* found entry in search cache... */ - curtime = apr_time_now(); - - /* - * Remove this item from the cache if its expired, or if the - * sent password doesn't match the storepassword. - */ - if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) { - /* ...but entry is too old */ - util_ald_cache_remove(curl->search_cache, search_nodep); - } - else if (strcmp(search_nodep->bindpw, bindpw) != 0) { - /* ...but cached password doesn't match sent password */ - util_ald_cache_remove(curl->search_cache, search_nodep); - } - else { - /* ...and entry is valid */ - *binddn = search_nodep->dn; - *retvals = search_nodep->vals; - apr_thread_rwlock_unlock(util_ldap_cache_lock); - ldc->reason = "Authentication successful (cached)"; - return LDAP_SUCCESS; - } - } - /* unlock this read lock */ - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - - /* - * At this point, there is no valid cached search, so lets do the search. - */ - - /* - * If any LDAP operation fails due to LDAP_SERVER_DOWN, control returns here. - */ -start_over: - if (failures++ > 10) { - return result; - } - if (LDAP_SUCCESS != (result = util_ldap_connection_open(ldc))) { - return result; - } - - /* try do the search */ - if ((result = ldap_search_ext_s(ldc->ldap, - basedn, scope, - filter, attrs, 0, - NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) { - ldc->reason = "ldap_search_ext_s() for user failed with server down"; - goto start_over; - } - - /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */ - if (result != LDAP_SUCCESS) { - ldc->reason = "ldap_search_ext_s() for user failed"; - return result; - } - - /* - * We should have found exactly one entry; to find a different - * number is an error. - */ - count = ldap_count_entries(ldc->ldap, res); - if (count != 1) { - ldap_msgfree(res); - ldc->reason = "User is not unique (search found two or more matches)"; - return LDAP_NO_SUCH_OBJECT; - } - - entry = ldap_first_entry(ldc->ldap, res); - - /* Grab the dn, copy it into the pool, and free it again */ - dn = ldap_get_dn(ldc->ldap, entry); - *binddn = apr_pstrdup(st->pool, dn); - ldap_memfree(dn); - - /* - * A bind to the server with an empty password always succeeds, so - * we check to ensure that the password is not empty. This implies - * that users who actually do have empty passwords will never be - * able to authenticate with this module. I don't see this as a big - * problem. - */ - if (strlen(bindpw) <= 0) { - ldap_msgfree(res); - ldc->reason = "Empty password not allowed"; - return LDAP_INVALID_CREDENTIALS; - } - - /* - * Attempt to bind with the retrieved dn and the password. If the bind - * fails, it means that the password is wrong (the dn obviously - * exists, since we just retrieved it) - */ - if ((result = - ldap_simple_bind_s(ldc->ldap, *binddn, bindpw)) == - LDAP_SERVER_DOWN) { - ldc->reason = "ldap_simple_bind_s() to check user credentials failed with server down"; - goto start_over; - } - - /* failure? if so - return */ - if (result != LDAP_SUCCESS) { - ldc->reason = "ldap_simple_bind_s() to check user credentials failed"; - return result; - } - - /* - * Get values for the provided attributes. - */ - if (attrs) { - int k = 0; - int i = 0; - while (attrs[k++]); - vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1)); - while (attrs[i]) { - char **values; - int j = 0; - char *str = NULL; - /* get values */ - values = ldap_get_values(ldc->ldap, entry, attrs[i]); - while (values && values[j]) { - str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL) : apr_pstrdup(r->pool, values[j]); - j++; - } - vals[i] = str; - i++; - } - *retvals = vals; - } - - /* - * Add the new username to the search cache. - */ - apr_thread_rwlock_wrlock(util_ldap_cache_lock); - the_search_node.username = filter; - the_search_node.dn = *binddn; - the_search_node.bindpw = bindpw; - the_search_node.lastbind = apr_time_now(); - the_search_node.vals = vals; - util_ald_cache_insert(curl->search_cache, &the_search_node); - ldap_msgfree(res); - apr_thread_rwlock_unlock(util_ldap_cache_lock); - - ldc->reason = "Authentication successful"; - return LDAP_SUCCESS; -} - - - -/* ---------------------------------------- */ -/* config directives */ - - -static const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy, const char *bytes) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - st->cache_bytes = atol(bytes); - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting shared memory cache size to %d bytes.", - getpid(), st->cache_bytes); - - return NULL; -} - -static const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, const char *ttl) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - st->search_cache_ttl = atol(ttl) * 1000000; - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting cache TTL to %ld microseconds.", - getpid(), st->search_cache_ttl); - - return NULL; -} - -static const char *util_ldap_set_cache_entries(cmd_parms *cmd, void *dummy, const char *size) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - - st->search_cache_size = atol(size); - if (st->search_cache_size < 0) { - st->search_cache_size = 0; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting search cache size to %ld entries.", - getpid(), st->search_cache_size); - - return NULL; -} - -static const char *util_ldap_set_opcache_ttl(cmd_parms *cmd, void *dummy, const char *ttl) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - st->compare_cache_ttl = atol(ttl) * 1000000; - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting operation cache TTL to %ld microseconds.", - getpid(), st->compare_cache_ttl); - - return NULL; -} - -static const char *util_ldap_set_opcache_entries(cmd_parms *cmd, void *dummy, const char *size) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - st->compare_cache_size = atol(size); - if (st->compare_cache_size < 0) { - st->compare_cache_size = 0; - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting operation cache size to %ld entries.", - getpid(), st->compare_cache_size); - - return NULL; -} - -#ifdef APU_HAS_LDAPSSL_CLIENT_INIT -static const char *util_ldap_set_certdbpath(cmd_parms *cmd, void *dummy, const char *path) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, - &ldap_module); - - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, - "[%d] ldap cache: Setting LDAP SSL client certificate dbpath to %s.", - getpid(), path); - - st->have_certdb = 1; - if (ldapssl_client_init(path, NULL) != 0) { - return "Could not initialize SSL client"; - } - else { - return NULL; - } -} -#endif - -void *util_ldap_create_config(apr_pool_t *p, server_rec *s) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)apr_pcalloc(p, sizeof(util_ldap_state_t)); - - st->pool = p; - - st->cache_bytes = 100000; - st->search_cache_ttl = 600000000; - st->search_cache_size = 1024; - st->compare_cache_ttl = 600000000; - st->compare_cache_size = 1024; - - st->connections = NULL; -#ifdef APU_HAS_LDAP_NETSCAPE_SSL - st->have_certdb = 0; -#endif - - return st; -} - -static void util_ldap_init_module(apr_pool_t *pool, server_rec *s) -{ - util_ldap_state_t *st = - (util_ldap_state_t *)ap_get_module_config(s->module_config, - &ldap_module); - - apr_status_t result = util_ldap_cache_init(pool, st->cache_bytes); - char buf[MAX_STRING_LEN]; - - apr_strerror(result, buf, sizeof(buf)); - ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, - "[%d] ldap cache init: %s", - getpid(), buf); -} - - -command_rec util_ldap_cmds[] = { - AP_INIT_TAKE1("LDAPSharedCacheSize", util_ldap_set_cache_bytes, NULL, RSRC_CONF, - "Sets the size of the shared memory cache in bytes. " - "Zero means disable the shared memory cache. Defaults to 100KB."), - - AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries, NULL, RSRC_CONF, - "Sets the maximum number of entries that are possible in the LDAP " - "search cache. " - "Zero means no limit; -1 disables the cache. Defaults to 1024 entries."), - - AP_INIT_TAKE1("LDAPCacheTTL", util_ldap_set_cache_ttl, NULL, RSRC_CONF, - "Sets the maximum time (in seconds) that an item can be cached in the LDAP " - "search cache. Zero means no limit. Defaults to 600 seconds (10 minutes)."), - - AP_INIT_TAKE1("LDAPOpCacheEntries", util_ldap_set_opcache_entries, NULL, RSRC_CONF, - "Sets the maximum number of entries that are possible in the LDAP " - "compare cache. " - "Zero means no limit; -1 disables the cache. Defaults to 1024 entries."), - - AP_INIT_TAKE1("LDAPOpCacheTTL", util_ldap_set_opcache_ttl, NULL, RSRC_CONF, - "Sets the maximum time (in seconds) that an item is cached in the LDAP " - "operation cache. Zero means no limit. Defaults to 600 seconds (10 minutes)."), - -#ifdef APU_HAS_LDAPSSL_CLIENT_INIT - AP_INIT_TAKE1("LDAPCertDBPath", util_ldap_set_certdbpath, NULL, RSRC_CONF, - "Specifies the file containing Certificate Authority certificates " - "for validating secure LDAP server certificates. This file must be the " - "cert7.db database used by Netscape Communicator"), -#endif - - {NULL} -}; - -static void util_ldap_register_hooks(apr_pool_t *p) -{ - ap_hook_child_init(util_ldap_init_module, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE); -} - -module ldap_module = { - STANDARD20_MODULE_STUFF, - NULL, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - util_ldap_create_config, /* server config */ - NULL, /* merge server config */ - util_ldap_cmds, /* command table */ - util_ldap_register_hooks, /* set up request processing hooks */ -}; diff --git a/modules/experimental/util_ldap.def b/modules/experimental/util_ldap.def deleted file mode 100644 index d1fac89b354..00000000000 --- a/modules/experimental/util_ldap.def +++ /dev/null @@ -1,6 +0,0 @@ -EXPORT ldap_module -EXPORT util_ldap_connection_find -EXPORT util_ldap_connection_close -EXPORT util_ldap_cache_checkuserid -EXPORT util_ldap_cache_compare -EXPORT util_ldap_cache_comparedn diff --git a/modules/experimental/util_ldap_cache.c b/modules/experimental/util_ldap_cache.c deleted file mode 100644 index 0414f4d4e7b..00000000000 --- a/modules/experimental/util_ldap_cache.c +++ /dev/null @@ -1,321 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/* - * util_ldap_cache.c: LDAP cache things - * - * Original code from auth_ldap module for Apache v1.3: - * Copyright 1998, 1999 Enbridge Pipelines Inc. - * Copyright 1999-2001 Dave Carrigan - */ - -#include -#include "util_ldap.h" -#include "util_ldap_cache.h" - -#ifdef APU_HAS_LDAP - - - - -/* ------------------------------------------------------------------ */ - -unsigned long util_ldap_url_node_hash(void *n) -{ - util_url_node_t *node = (util_url_node_t *)n; - return util_ald_hash_string(1, node->url); -} - -int util_ldap_url_node_compare(void *a, void *b) -{ - util_url_node_t *na = (util_url_node_t *)a; - util_url_node_t *nb = (util_url_node_t *)b; - - return(strcmp(na->url, nb->url) == 0); -} - -void *util_ldap_url_node_copy(void *c) -{ - util_url_node_t *n = (util_url_node_t *)c; - util_url_node_t *node = (util_url_node_t *)util_ald_alloc(sizeof(util_url_node_t)); - - if (node) { - if (!(node->url = util_ald_strdup(n->url))) { - util_ald_free(node->url); - return NULL; - } - node->search_cache = n->search_cache; - node->compare_cache = n->compare_cache; - node->dn_compare_cache = n->dn_compare_cache; - return node; - } - else { - return NULL; - } -} - -void util_ldap_url_node_free(void *n) -{ - util_url_node_t *node = (util_url_node_t *)n; - - util_ald_free(node->url); - util_ald_destroy_cache(node->search_cache); - util_ald_destroy_cache(node->compare_cache); - util_ald_destroy_cache(node->dn_compare_cache); - util_ald_free(node); -} - -/* ------------------------------------------------------------------ */ - -/* Cache functions for search nodes */ -unsigned long util_ldap_search_node_hash(void *n) -{ - util_search_node_t *node = (util_search_node_t *)n; - return util_ald_hash_string(1, ((util_search_node_t *)(node))->username); -} - -int util_ldap_search_node_compare(void *a, void *b) -{ - return(strcmp(((util_search_node_t *)a)->username, - ((util_search_node_t *)b)->username) == 0); -} - -void *util_ldap_search_node_copy(void *c) -{ - util_search_node_t *node = (util_search_node_t *)c; - util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t)); - - /* safety check */ - if (newnode) { - - /* copy vals */ - if (node->vals) { - int k = 0; - int i = 0; - while (node->vals[k++]); - if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) { - util_ldap_search_node_free(newnode); - return NULL; - } - while (node->vals[i]) { - if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) { - util_ldap_search_node_free(newnode); - return NULL; - } - i++; - } - } - else { - newnode->vals = NULL; - } - if (!(newnode->username = util_ald_strdup(node->username)) || - !(newnode->dn = util_ald_strdup(node->dn)) || - !(newnode->bindpw = util_ald_strdup(node->bindpw)) ) { - util_ldap_search_node_free(newnode); - return NULL; - } - newnode->lastbind = node->lastbind; - - } - return (void *)newnode; -} - -void util_ldap_search_node_free(void *n) -{ - int i = 0; - util_search_node_t *node = (util_search_node_t *)n; - if (node->vals) { - while (node->vals[i]) { - util_ald_free(node->vals[i++]); - } - util_ald_free(node->vals); - } - util_ald_free(node->username); - util_ald_free(node->dn); - util_ald_free(node->bindpw); - util_ald_free(node); -} - -/* ------------------------------------------------------------------ */ - -unsigned long util_ldap_compare_node_hash(void *n) -{ - util_compare_node_t *node = (util_compare_node_t *)n; - return util_ald_hash_string(3, node->dn, node->attrib, node->value); -} - -int util_ldap_compare_node_compare(void *a, void *b) -{ - util_compare_node_t *na = (util_compare_node_t *)a; - util_compare_node_t *nb = (util_compare_node_t *)b; - return (strcmp(na->dn, nb->dn) == 0 && - strcmp(na->attrib, nb->attrib) == 0 && - strcmp(na->value, nb->value) == 0); -} - -void *util_ldap_compare_node_copy(void *c) -{ - util_compare_node_t *n = (util_compare_node_t *)c; - util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(sizeof(util_compare_node_t)); - - if (node) { - if (!(node->dn = util_ald_strdup(n->dn)) || - !(node->attrib = util_ald_strdup(n->attrib)) || - !(node->value = util_ald_strdup(n->value))) { - util_ldap_compare_node_free(node); - return NULL; - } - node->lastcompare = n->lastcompare; - node->result = n->result; - return node; - } - else { - return NULL; - } -} - -void util_ldap_compare_node_free(void *n) -{ - util_compare_node_t *node = (util_compare_node_t *)n; - util_ald_free(node->dn); - util_ald_free(node->attrib); - util_ald_free(node->value); - util_ald_free(node); -} - -/* ------------------------------------------------------------------ */ - -unsigned long util_ldap_dn_compare_node_hash(void *n) -{ - return util_ald_hash_string(1, ((util_dn_compare_node_t *)n)->reqdn); -} - -int util_ldap_dn_compare_node_compare(void *a, void *b) -{ - return (strcmp(((util_dn_compare_node_t *)a)->reqdn, - ((util_dn_compare_node_t *)b)->reqdn) == 0); -} - -void *util_ldap_dn_compare_node_copy(void *c) -{ - util_dn_compare_node_t *n = (util_dn_compare_node_t *)c; - util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(sizeof(util_dn_compare_node_t)); - if (node) { - if (!(node->reqdn = util_ald_strdup(n->reqdn)) || - !(node->dn = util_ald_strdup(n->dn))) { - util_ldap_dn_compare_node_free(node); - return NULL; - } - return node; - } - else { - return NULL; - } -} - -void util_ldap_dn_compare_node_free(void *n) -{ - util_dn_compare_node_t *node = (util_dn_compare_node_t *)n; - util_ald_free(node->reqdn); - util_ald_free(node->dn); - util_ald_free(node); -} - - -/* ------------------------------------------------------------------ */ -apr_status_t util_ldap_cache_child_kill(void *data); -apr_status_t util_ldap_cache_module_kill(void *data); - -apr_status_t util_ldap_cache_module_kill(void *data) -{ -#if APR_HAS_SHARED_MEMORY - if (util_ldap_shm != NULL) { - apr_status_t result = apr_shm_destroy(util_ldap_shm); - util_ldap_shm = NULL; - return result; - } -#endif - util_ald_destroy_cache(util_ldap_cache); - return APR_SUCCESS; -} - -apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize) -{ - apr_anylock_t rmm_lock; - -#if APR_HAS_SHARED_MEMORY - apr_status_t result; - - result = apr_shm_create(&util_ldap_shm, reqsize, "/tmp/ldap_cache", pool); - if (result != APR_SUCCESS) { - return result; - } - - /* This will create a rmm "handler" to get into the shared memory area */ - apr_rmm_init(&util_ldap_rmm, &rmm_lock, - (void *)apr_shm_baseaddr_get(util_ldap_shm), reqsize, pool); -#endif - - apr_pool_cleanup_register(pool, NULL, util_ldap_cache_module_kill, apr_pool_cleanup_null); - - util_ldap_cache = util_ald_create_cache(50, - util_ldap_url_node_hash, - util_ldap_url_node_compare, - util_ldap_url_node_copy, - util_ldap_url_node_free); - return APR_SUCCESS; -} - - -#endif /* APU_HAS_LDAP */ diff --git a/modules/experimental/util_ldap_cache.h b/modules/experimental/util_ldap_cache.h deleted file mode 100644 index f2be43d0244..00000000000 --- a/modules/experimental/util_ldap_cache.h +++ /dev/null @@ -1,216 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - - -#ifndef APU_LDAP_CACHE_H -#define APU_LDAP_CACHE_H - -/* - * This switches LDAP support on or off. - */ - -/* this whole thing disappears if LDAP is not enabled */ -#ifdef APU_HAS_LDAP - - -/* - * LDAP Cache Manager - */ - -#include -#include /* EDD */ - -typedef struct util_cache_node_t { - void *payload; /* Pointer to the payload */ - time_t add_time; /* Time node was added to cache */ - struct util_cache_node_t *next; -} util_cache_node_t; - -typedef struct util_ald_cache_t { - unsigned long size; /* Size of cache array */ - unsigned long maxentries; /* Maximum number of cache entries */ - unsigned long numentries; /* Current number of cache entries */ - unsigned long fullmark; /* Used to keep track of when cache becomes 3/4 full */ - time_t marktime; /* Time that the cache became 3/4 full */ - unsigned long (*hash)(void *); /* Func to hash the payload */ - int (*compare)(void *, void *); /* Func to compare two payloads */ - void * (*copy)(void *); /* Func to alloc mem and copy payload to new mem */ - void (*free)(void *); /* Func to free mem used by the payload */ - util_cache_node_t **nodes; - - unsigned long numpurges; /* No. of times the cache has been purged */ - double avg_purgetime; /* Average time to purge the cache */ - time_t last_purge; /* Time of the last purge */ - unsigned long npurged; /* Number of elements purged in last purge. This is not - obvious: it won't be 3/4 the size of the cache if - there were a lot of expired entries. */ - - unsigned long fetches; /* Number of fetches */ - unsigned long hits; /* Number of cache hits */ - unsigned long inserts; /* Number of inserts */ - unsigned long removes; /* Number of removes */ -} util_ald_cache_t; - -#if APR_HAS_SHARED_MEMORY -apr_shm_t *util_ldap_shm; -apr_rmm_t *util_ldap_rmm; -#endif -util_ald_cache_t *util_ldap_cache; -apr_thread_rwlock_t *util_ldap_cache_lock; - -#ifndef WIN32 -#define ALD_MM_FILE_MODE ( S_IRUSR|S_IWUSR ) -#else -#define ALD_MM_FILE_MODE ( _S_IREAD|_S_IWRITE ) -#endif - - -/* - * LDAP Cache - */ - -/* - * Maintain a cache of LDAP URLs that the server handles. Each node in - * the cache contains the search cache for that URL, and a compare cache - * for the URL. The compare cash is populated when doing require group - * compares. - */ -typedef struct util_url_node_t { - const char *url; - util_ald_cache_t *search_cache; - util_ald_cache_t *compare_cache; - util_ald_cache_t *dn_compare_cache; -} util_url_node_t; - -/* - * We cache every successful search and bind operation, using the username - * as the key. Each node in the cache contains the returned DN, plus the - * password used to bind. - */ -typedef struct util_search_node_t { - const char *username; /* Cache key */ - const char *dn; /* DN returned from search */ - const char *bindpw; /* The most recently used bind password; - NULL if the bind failed */ - apr_time_t lastbind; /* Time of last successful bind */ - const char **vals; /* Values of queried attributes */ -} util_search_node_t; - -/* - * We cache every successful compare operation, using the DN, attrib, and - * value as the key. - */ -typedef struct util_compare_node_t { - const char *dn; /* DN, attrib and value combine to be the key */ - const char *attrib; - const char *value; - apr_time_t lastcompare; - int result; -} util_compare_node_t; - -/* - * We cache every successful compare dn operation, using the dn in the require - * statement and the dn fetched based on the client-provided username. - */ -typedef struct util_dn_compare_node_t { - const char *reqdn; /* The DN in the require dn statement */ - const char *dn; /* The DN found in the search */ -} util_dn_compare_node_t; - - -/* - * Function prototypes for LDAP cache - */ - -/* util_ldap_cache.c */ -unsigned long util_ldap_url_node_hash(void *n); -int util_ldap_url_node_compare(void *a, void *b); -void *util_ldap_url_node_copy(void *c); -void util_ldap_url_node_free(void *n); -unsigned long util_ldap_search_node_hash(void *n); -int util_ldap_search_node_compare(void *a, void *b); -void *util_ldap_search_node_copy(void *c); -void util_ldap_search_node_free(void *n); -unsigned long util_ldap_compare_node_hash(void *n); -int util_ldap_compare_node_compare(void *a, void *b); -void *util_ldap_compare_node_copy(void *c); -void util_ldap_compare_node_free(void *n); -unsigned long util_ldap_dn_compare_node_hash(void *n); -int util_ldap_dn_compare_node_compare(void *a, void *b); -void *util_ldap_dn_compare_node_copy(void *c); -void util_ldap_dn_compare_node_free(void *n); - - -/* util_ldap_cache_mgr.c */ - -void util_ald_free(const void *ptr); -void *util_ald_alloc(unsigned long size); -const char *util_ald_strdup(const char *s); -unsigned long util_ald_hash_string(int nstr, ...); -void util_ald_cache_purge(util_ald_cache_t *cache); -util_url_node_t *util_ald_create_caches(util_ldap_state_t *s, const char *url); -util_ald_cache_t *util_ald_create_cache(unsigned long maxentries, - unsigned long (*hashfunc)(void *), - int (*comparefunc)(void *, void *), - void * (*copyfunc)(void *), - void (*freefunc)(void *)); -void util_ald_destroy_cache(util_ald_cache_t *cache); -void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload); -void util_ald_cache_insert(util_ald_cache_t *cache, void *payload); -void util_ald_cache_remove(util_ald_cache_t *cache, void *payload); -char *util_ald_cache_display_stats(apr_pool_t *p, util_ald_cache_t *cache, - char *name); - -#endif /* APU_HAS_LDAP */ -#endif /* APU_LDAP_CACHE_H */ diff --git a/modules/experimental/util_ldap_cache_mgr.c b/modules/experimental/util_ldap_cache_mgr.c deleted file mode 100644 index f2a65d91326..00000000000 --- a/modules/experimental/util_ldap_cache_mgr.c +++ /dev/null @@ -1,538 +0,0 @@ -/* ==================================================================== - * The Apache Software License, Version 1.1 - * - * Copyright (c) 2000-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - */ - -/* - * util_ldap_cache_mgr.c: LDAP cache manager things - * - * Original code from auth_ldap module for Apache v1.3: - * Copyright 1998, 1999 Enbridge Pipelines Inc. - * Copyright 1999-2001 Dave Carrigan - */ - -#include -#include "util_ldap.h" -#include "util_ldap_cache.h" -#include - -#ifdef APU_HAS_LDAP - -/* only here until strdup is gone */ -#include - -/* here till malloc is gone */ -#include - -static const int primes[] = -{ - 11, - 19, - 37, - 73, - 109, - 163, - 251, - 367, - 557, - 823, - 1237, - 1861, - 2777, - 4177, - 6247, - 9371, - 14057, - 21089, - 31627, - 47431, - 71143, - 106721, - 160073, - 240101, - 360163, - 540217, - 810343, - 1215497, - 1823231, - 2734867, - 4102283, - 6153409, - 9230113, - 13845163, - 0 -}; - -void util_ald_free(const void *ptr) -{ -#if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { - if (ptr) - apr_rmm_free(util_ldap_rmm, apr_rmm_offset_get(util_ldap_rmm, (void *)ptr)); - } else { - if (ptr) - free((void *)ptr); - } -#else - if (ptr) - free((void *)ptr); -#endif -} - -void *util_ald_alloc(unsigned long size) -{ - if (0 == size) - return NULL; -#if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { - return (void *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, size)); - } else { - return (void *)calloc(sizeof(char), size); - } -#else - return (void *)calloc(sizeof(char), size); -#endif -} - -const char *util_ald_strdup(const char *s) -{ -#if APR_HAS_SHARED_MEMORY - if (util_ldap_shm) { - char *buf = (char *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, strlen(s)+1)); - if (buf) { - strcpy(buf, s); - return buf; - } - else { - return NULL; - } - } else { - return strdup(s); - } -#else - return strdup(s); -#endif -} - - -/* - * Computes the hash on a set of strings. The first argument is the number - * of strings to hash, the rest of the args are strings. - * Algorithm taken from glibc. - */ -unsigned long util_ald_hash_string(int nstr, ...) -{ - int i; - va_list args; - unsigned long h=0, g; - char *str, *p; - - va_start(args, nstr); - for (i=0; i < nstr; ++i) { - str = va_arg(args, char *); - for (p = str; *p; ++p) { - h = ( h << 4 ) + *p; - if ( ( g = h & 0xf0000000 ) ) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - } - va_end(args); - - return h; -} - - -/* - Purges a cache that has gotten full. We keep track of the time that we - added the entry that made the cache 3/4 full, then delete all entries - that were added before that time. It's pretty simplistic, but time to - purge is only O(n), which is more important. -*/ -void util_ald_cache_purge(util_ald_cache_t *cache) -{ - int i; - util_cache_node_t *p, *q; - apr_time_t t; - - if (!cache) - return; - - cache->last_purge = apr_time_now(); - cache->npurged = 0; - cache->numpurges++; - - for (i=0; i < cache->size; ++i) { - p = cache->nodes[i]; - while (p != NULL) { - if (p->add_time < cache->marktime) { - q = p->next; - (*cache->free)(p->payload); - util_ald_free(p); - cache->numentries--; - cache->npurged++; - p = q; - } - else { - p = p->next; - } - } - } - - t = apr_time_now(); - cache->avg_purgetime = - ((t - cache->last_purge) + (cache->avg_purgetime * (cache->numpurges-1))) / - cache->numpurges; -} - - -/* - * create caches - */ -util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url) -{ - util_url_node_t *curl = NULL; - util_ald_cache_t *search_cache; - util_ald_cache_t *compare_cache; - util_ald_cache_t *dn_compare_cache; - - /* create the three caches */ - search_cache = util_ald_create_cache(st->search_cache_size, - util_ldap_search_node_hash, - util_ldap_search_node_compare, - util_ldap_search_node_copy, - util_ldap_search_node_free); - compare_cache = util_ald_create_cache(st->compare_cache_size, - util_ldap_compare_node_hash, - util_ldap_compare_node_compare, - util_ldap_compare_node_copy, - util_ldap_compare_node_free); - dn_compare_cache = util_ald_create_cache(st->compare_cache_size, - util_ldap_dn_compare_node_hash, - util_ldap_dn_compare_node_compare, - util_ldap_dn_compare_node_copy, - util_ldap_dn_compare_node_free); - - /* check that all the caches initialised successfully */ - if (search_cache && compare_cache && dn_compare_cache) { - - curl = (util_url_node_t *)apr_pcalloc(st->pool, sizeof(util_url_node_t)); - curl->url = url; - curl->search_cache = search_cache; - curl->compare_cache = compare_cache; - curl->dn_compare_cache = dn_compare_cache; - - util_ald_cache_insert(util_ldap_cache, curl); - - } - - return curl; -} - - -util_ald_cache_t *util_ald_create_cache(unsigned long maxentries, - unsigned long (*hashfunc)(void *), - int (*comparefunc)(void *, void *), - void * (*copyfunc)(void *), - void (*freefunc)(void *)) -{ - util_ald_cache_t *cache; - int i; - - if (maxentries <= 0) - return NULL; - - cache = (util_ald_cache_t *)util_ald_alloc(sizeof(util_ald_cache_t)); - if (!cache) - return NULL; - - cache->maxentries = maxentries; - cache->numentries = 0; - cache->size = maxentries / 3; - if (cache->size < 64) cache->size = 64; - for (i = 0; primes[i] && primes[i] < cache->size; ++i) ; - cache->size = primes[i]? primes[i] : primes[i-1]; - - cache->nodes = (util_cache_node_t **)util_ald_alloc(cache->size * sizeof(util_cache_node_t *)); - if (!cache->nodes) { - util_ald_free(cache); - return NULL; - } - - for (i=0; i < cache->size; ++i) - cache->nodes[i] = NULL; - - cache->hash = hashfunc; - cache->compare = comparefunc; - cache->copy = copyfunc; - cache->free = freefunc; - - cache->fullmark = cache->maxentries / 4 * 3; - cache->marktime = 0; - cache->avg_purgetime = 0.0; - cache->numpurges = 0; - cache->last_purge = 0; - cache->npurged = 0; - - cache->fetches = 0; - cache->hits = 0; - cache->inserts = 0; - cache->removes = 0; - - return cache; -} - -void util_ald_destroy_cache(util_ald_cache_t *cache) -{ - int i; - util_cache_node_t *p, *q; - - if (cache == NULL) - return; - - for (i = 0; i < cache->size; ++i) { - p = cache->nodes[i]; - q = NULL; - while (p != NULL) { - q = p->next; - (*cache->free)(p->payload); - util_ald_free(p); - p = q; - } - } - util_ald_free(cache->nodes); - util_ald_free(cache); -} - -void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload) -{ - int hashval; - util_cache_node_t *p; - - if (cache == NULL) - return NULL; - - cache->fetches++; - - hashval = (*cache->hash)(payload) % cache->size; - for (p = cache->nodes[hashval]; - p && !(*cache->compare)(p->payload, payload); - p = p->next) ; - - if (p != NULL) { - cache->hits++; - return p->payload; - } - else { - return NULL; - } -} - -/* - * Insert an item into the cache. - * *** Does not catch duplicates!!! *** - */ -void util_ald_cache_insert(util_ald_cache_t *cache, void *payload) -{ - int hashval; - util_cache_node_t *node; - - if (cache == NULL || payload == NULL) - return; - - cache->inserts++; - hashval = (*cache->hash)(payload) % cache->size; - node = (util_cache_node_t *)util_ald_alloc(sizeof(util_cache_node_t)); - node->add_time = apr_time_now(); - node->payload = (*cache->copy)(payload); - node->next = cache->nodes[hashval]; - cache->nodes[hashval] = node; - if (++cache->numentries == cache->fullmark) - cache->marktime=apr_time_now(); - if (cache->numentries >= cache->maxentries) - util_ald_cache_purge(cache); -} - -void util_ald_cache_remove(util_ald_cache_t *cache, void *payload) -{ - int hashval; - util_cache_node_t *p, *q; - - if (cache == NULL) - return; - - cache->removes++; - hashval = (*cache->hash)(payload) % cache->size; - for (p = cache->nodes[hashval], q=NULL; - p && !(*cache->compare)(p->payload, payload); - p = p->next) { - q = p; - } - - /* If p is null, it means that we couldn't find the node, so just return */ - if (p == NULL) - return; - - if (q == NULL) { - /* We found the node, and it's the first in the list */ - cache->nodes[hashval] = p->next; - } - else { - /* We found the node and it's not the first in the list */ - q->next = p->next; - } - (*cache->free)(p->payload); - util_ald_free(p); - cache->numentries--; -} - -char *util_ald_cache_display_stats(apr_pool_t *p, util_ald_cache_t *cache, char *name) -{ - int i; - int totchainlen = 0; - int nchains = 0; - double chainlen; - util_cache_node_t *n; - char *buf; - - if (cache == NULL) { - return ""; - } - - for (i=0; i < cache->size; ++i) { - if (cache->nodes[i] != NULL) { - nchains++; - for (n = cache->nodes[i]; n != NULL; n = n->next) - totchainlen++; - } - } - chainlen = nchains? (double)totchainlen / (double)nchains : 0; - - buf = apr_psprintf(p, - "" - "%s" - "%lu (%.0f%% full)" - "%.1f" - "%lu/%lu" - "%.0f%%" - "%lu/%lu", - name, - cache->numentries, - (double)cache->numentries / (double)cache->maxentries * 100.0, - chainlen, - cache->hits, - cache->fetches, - (cache->fetches > 0 ? (double)(cache->hits) / (double)(cache->fetches) * 100.0 : 100.0), - cache->inserts, - cache->removes); - - if (cache->numpurges) { - char str_ctime[APR_CTIME_LEN]; - - apr_ctime(str_ctime, cache->last_purge); - buf = apr_psprintf(p, - "%s" - "%lu\n" - "%s\n", - buf, - cache->numpurges, - str_ctime); - } - else { - buf = apr_psprintf(p, - "%s(none)\n", - buf); - } - - buf = apr_psprintf(p, "%s%.2g\n", buf, cache->avg_purgetime); - - return buf; -} - -char *util_ald_cache_display(apr_pool_t *pool) -{ - int i; - char *buf, *t1, *t2, *t3; - - if (!util_ldap_cache) { - return "Cache has not been enabled/initialised."; - } - - buf = util_ald_cache_display_stats(pool, util_ldap_cache, "LDAP URL Cache"); - - for (i=0; i < util_ldap_cache->size; ++i) { - util_cache_node_t *p; - for (p = util_ldap_cache->nodes[i]; p != NULL; p = p->next) { - util_url_node_t *n; - - n = (util_url_node_t *)p->payload; - - t1 = apr_psprintf(pool, "%s (Searches)", n->url); - t2 = apr_psprintf(pool, "%s (Compares)", n->url); - t3 = apr_psprintf(pool, "%s (DNCompares)", n->url); - - buf = apr_psprintf(pool, "%s\n\n" - "%s\n\n" - "%s\n\n" - "%s\n\n", - buf, - util_ald_cache_display_stats(pool, n->search_cache, t1), - util_ald_cache_display_stats(pool, n->compare_cache, t2), - util_ald_cache_display_stats(pool, n->dn_compare_cache, t3) - ); - } - } - return buf; -} - -#endif /* APU_HAS_LDAP */ diff --git a/support/dbmmanage b/support/dbmmanage deleted file mode 100644 index ad9a4aca761..00000000000 --- a/support/dbmmanage +++ /dev/null @@ -1,350 +0,0 @@ -#!/usr/bin/perl -# ==================================================================== -# The Apache Software License, Version 1.1 -# -# Copyright (c) 2000-2001 The Apache Software Foundation. All rights -# reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. The end-user documentation included with the redistribution, -# if any, must include the following acknowledgment: -# "This product includes software developed by the -# Apache Software Foundation (http://www.apache.org/)." -# Alternately, this acknowledgment may appear in the software itself, -# if and wherever such third-party acknowledgments normally appear. -# -# 4. The names "Apache" and "Apache Software Foundation" must -# not be used to endorse or promote products derived from this -# software without prior written permission. For written -# permission, please contact apache@apache.org. -# -# 5. Products derived from this software may not be called "Apache", -# nor may "Apache" appear in their name, without prior written -# permission of the Apache Software Foundation. -# -# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# ==================================================================== -# -# This software consists of voluntary contributions made by many -# individuals on behalf of the Apache Software Foundation. For more -# information on the Apache Software Foundation, please see -# . -# - -#for more functionality see the HTTPD::UserAdmin module: -# http://www.perl.com/CPAN/modules/by-module/HTTPD/HTTPD-Tools-x.xx.tar.gz -# -# usage: dbmmanage - -package dbmmanage; -# -ldb -lndbm -lgdbm -lsdbm -BEGIN { @AnyDBM_File::ISA = qw(DB_File NDBM_File GDBM_File SDBM_File) } -use strict; -use Fcntl; -use AnyDBM_File (); - -sub usage { - my $cmds = join "|", sort keys %dbmc::; - die <$command(); -untie %DB; - - -my $x; -sub genseed { - my $psf; - if ($not_unix) { - srand (time ^ $$ or time ^ ($$ + ($$ << 15))); - } - else { - for (qw(-xlwwa -le)) { - `ps $_ 2>/dev/null`; - $psf = $_, last unless $?; - } - srand (time ^ $$ ^ unpack("%L*", `ps $psf | gzip -f`)); - } - @range = (qw(. /), '0'..'9','a'..'z','A'..'Z'); - $x = int scalar @range; -} - -sub randchar { - join '', map $range[rand $x], 1..shift||1; -} - -sub saltpw_crypt { - genseed() unless @range; - return $newstyle_salt ? - join '', "_", randchar, "a..", randchar(4) : - randchar(2); -} - -sub cryptpw_crypt { - my ($pw, $salt) = @_; - $salt = saltpw_crypt unless $salt; - crypt $pw, $salt; -} - -sub saltpw_md5 { - genseed() unless @range; - randchar(8); -} - -sub cryptpw_md5 { - my($pw, $salt) = @_; - $salt = saltpw_md5 unless $salt; - Crypt::PasswdMD5::apache_md5_crypt($pw, $salt); -} - -sub cryptpw_sha1 { - my($pw, $salt) = @_; - '{SHA}' . Digest::SHA1::sha1_base64($pw) . "="; -} - -sub cryptpw { - if ($crypt_method eq "md5") { - return cryptpw_md5(@_); - } elsif ($crypt_method eq "sha1") { - return cryptpw_sha1(@_); - } elsif ($crypt_method eq "crypt") { - return cryptpw_crypt(@_); - } - @_[0]; # otherwise return plaintext -} - -sub getpass { - my $prompt = shift || "Enter password:"; - - unless($not_unix) { - open STDIN, "/dev/tty" or warn "couldn't open /dev/tty $!\n"; - system "stty -echo;"; - } - - my($c,$pwd); - print STDERR $prompt; - while (($c = getc(STDIN)) ne '' and $c ne "\n" and $c ne "\r") { - $pwd .= $c; - } - - system "stty echo" unless $not_unix; - print STDERR "\n"; - die "Can't use empty password!\n" unless length $pwd; - return $pwd; -} - -sub dbmc::update { - die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; - $crypted_pwd = (split /:/, $DB{$key}, 3)[0] if $crypted_pwd eq '.'; - $groups = (split /:/, $DB{$key}, 3)[1] if !$groups || $groups eq '.'; - $comment = (split /:/, $DB{$key}, 3)[2] if !$comment || $comment eq '.'; - if (!$crypted_pwd || $crypted_pwd eq '-') { - dbmc->adduser; - } - else { - dbmc->add; - } -} - -sub dbmc::add { - die "Can't use empty password!\n" unless $crypted_pwd; - unless($is_update) { - die "Sorry, user `$key' already exists!\n" if $DB{$key}; - } - $groups = '' if $groups eq '-'; - $comment = '' if $comment eq '-'; - $groups .= ":" . $comment if $comment; - $crypted_pwd .= ":" . $groups if $groups; - $DB{$key} = $crypted_pwd; - my $action = $is_update ? "updated" : "added"; - print "User $key $action with password encrypted to $DB{$key} using $crypt_method\n"; -} - -sub dbmc::adduser { - my $value = getpass "New password:"; - die "They don't match, sorry.\n" unless getpass("Re-type new password:") eq $value; - $crypted_pwd = cryptpw $value; - dbmc->add; -} - -sub dbmc::delete { - die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; - delete $DB{$key}, print "`$key' deleted\n"; -} - -sub dbmc::view { - print $key ? "$key:$DB{$key}\n" : map { "$_:$DB{$_}\n" if $DB{$_} } keys %DB; -} - -sub dbmc::check { - die "Sorry, user `$key' doesn't exist!\n" unless $DB{$key}; - my $chkpass = (split /:/, $DB{$key}, 3)[0]; - my $testpass = getpass(); - if (substr($chkpass, 0, 6) eq '$apr1$') { - need_md5_crypt; - $crypt_method = "md5"; - } elsif (substr($chkpass, 0, 5) eq '{SHA}') { - need_sha1_crypt; - $crypt_method = "sha1"; - } elsif (length($chkpass) == 13 && $chkpass ne $testpass) { - $crypt_method = "crypt"; - } else { - $crypt_method = "plain"; - } - print $crypt_method . (cryptpw($testpass, $chkpass) eq $chkpass - ? " password ok\n" : " password mismatch\n"); -} - -sub dbmc::import { - while(defined($_ = ) and chomp) { - ($key,$crypted_pwd,$groups,$comment) = split /:/, $_, 4; - dbmc->add; - } -} - diff --git a/support/log_server_status b/support/log_server_status deleted file mode 100644 index e32280c9127..00000000000 --- a/support/log_server_status +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl -# ==================================================================== -# The Apache Software License, Version 1.1 -# -# Copyright (c) 2000-2001 The Apache Software Foundation. All rights -# reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. The end-user documentation included with the redistribution, -# if any, must include the following acknowledgment: -# "This product includes software developed by the -# Apache Software Foundation (http://www.apache.org/)." -# Alternately, this acknowledgment may appear in the software itself, -# if and wherever such third-party acknowledgments normally appear. -# -# 4. The names "Apache" and "Apache Software Foundation" must -# not be used to endorse or promote products derived from this -# software without prior written permission. For written -# permission, please contact apache@apache.org. -# -# 5. Products derived from this software may not be called "Apache", -# nor may "Apache" appear in their name, without prior written -# permission of the Apache Software Foundation. -# -# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# ==================================================================== -# -# This software consists of voluntary contributions made by many -# individuals on behalf of the Apache Software Foundation. For more -# information on the Apache Software Foundation, please see -# . -# -# Log Server Status -# Mark J Cox, UK Web Ltd 1996, mark@ukweb.com -# -# This script is designed to be run at a frequent interval by something -# like cron. It connects to the server and downloads the status -# information. It reformats the information to a single line and logs -# it to a file. Make sure the directory $wherelog is writable by the -# user who runs this script. -# -require 'sys/socket.ph'; - -$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/19960312" -$server = "localhost"; # Name of server, could be "www.foo.com" -$port = "80"; # Port on server -$request = "/status/?auto"; # Request to send - -sub tcp_connect -{ - local($host,$port) =@_; - $sockaddr='S n a4 x8'; - chop($hostname=`hostname`); - $port=(getservbyname($port, 'tcp'))[2] unless $port =~ /^\d+$/; - $me=pack($sockaddr,&AF_INET,0,(gethostbyname($hostname))[4]); - $them=pack($sockaddr,&AF_INET,$port,(gethostbyname($host))[4]); - socket(S,&PF_INET,&SOCK_STREAM,(getprotobyname('tcp'))[2]) || - die "socket: $!"; - bind(S,$me) || return "bind: $!"; - connect(S,$them) || return "connect: $!"; - select(S); - $| = 1; - select(stdout); - return ""; -} - -### Main - -{ - $year=`date +%y`; - chomp($year); - $year += ($year < 70) ? 2000 : 1900; - $date = $year . `date +%m%d:%H%M%S`; - chomp($date); - ($day,$time)=split(/:/,$date); - $res=&tcp_connect($server,$port); - open(OUT,">>$wherelog$day"); - if ($res) { - print OUT "$time:-1:-1:-1:-1:$res\n"; - exit 1; - } - print S "GET $request\n"; - while () { - $requests=$1 if ( m|^BusyServers:\ (\S+)|); - $idle=$1 if ( m|^IdleServers:\ (\S+)|); - $number=$1 if ( m|sses:\ (\S+)|); - $cpu=$1 if (m|^CPULoad:\ (\S+)|); - } - print OUT "$time:$requests:$idle:$number:$cpu\n"; -} - - diff --git a/support/logresolve.pl b/support/logresolve.pl deleted file mode 100644 index ab5a7322ab2..00000000000 --- a/support/logresolve.pl +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/perl -# ==================================================================== -# The Apache Software License, Version 1.1 -# -# Copyright (c) 2000-2001 The Apache Software Foundation. All rights -# reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. The end-user documentation included with the redistribution, -# if any, must include the following acknowledgment: -# "This product includes software developed by the -# Apache Software Foundation (http://www.apache.org/)." -# Alternately, this acknowledgment may appear in the software itself, -# if and wherever such third-party acknowledgments normally appear. -# -# 4. The names "Apache" and "Apache Software Foundation" must -# not be used to endorse or promote products derived from this -# software without prior written permission. For written -# permission, please contact apache@apache.org. -# -# 5. Products derived from this software may not be called "Apache", -# nor may "Apache" appear in their name, without prior written -# permission of the Apache Software Foundation. -# -# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# ==================================================================== -# -# This software consists of voluntary contributions made by many -# individuals on behalf of the Apache Software Foundation. For more -# information on the Apache Software Foundation, please see -# . -# -# logresolve.pl -# -# v 1.2 by robh @ imdb.com -# -# usage: logresolve.pl outfile -# -# input = Apache/NCSA/.. logfile with IP numbers at start of lines -# output = same logfile with IP addresses resolved to hostnames where -# name lookups succeeded. -# -# this differs from the C based 'logresolve' in that this script -# spawns a number ($CHILDREN) of subprocesses to resolve addresses -# concurrently and sets a short timeout ($TIMEOUT) for each lookup in -# order to keep things moving quickly. -# -# the parent process handles caching of IP->hostnames using a Perl hash -# it also avoids sending the same IP to multiple child processes to be -# resolved multiple times concurrently. -# -# Depending on the settings of $CHILDREN and $TIMEOUT you should see -# significant reductions in the overall time taken to resolve your -# logfiles. With $CHILDREN=40 and $TIMEOUT=5 I've seen 200,000 - 300,000 -# logfile lines processed per hour compared to ~45,000 per hour -# with 'logresolve'. -# -# I haven't yet seen any noticable reduction in the percentage of IPs -# that fail to get resolved. Your mileage will no doubt vary. 5s is long -# enough to wait IMO. -# -# Known to work with FreeBSD 2.2 -# Known to have problems with Solaris -# -# 980417 - use 'sockaddr_un' for bind/connect to make the script work -# with linux. Fix from Luuk de Boer - -require 5.004; - -$|=1; - -use FileHandle; -use Socket; - -use strict; -no strict 'refs'; - -use vars qw($PROTOCOL); -$PROTOCOL = 0; - -my $CHILDREN = 40; -my $TIMEOUT = 5; - -my $filename; -my %hash = (); -my $parent = $$; - -my @children = (); -for (my $child = 1; $child <=$CHILDREN; $child++) { - my $f = fork(); - if (!$f) { - $filename = "./.socket.$parent.$child"; - if (-e $filename) { unlink($filename) || warn "$filename .. $!\n";} - &child($child); - exit(0); - } - push(@children, $f); -} - -&parent; -&cleanup; - -## remove all temporary files before shutting down -sub cleanup { - # die kiddies, die - kill(15, @children); - for (my $child = 1; $child <=$CHILDREN; $child++) { - if (-e "./.socket.$parent.$child") { - unlink("./.socket.$parent.$child") - || warn ".socket.$parent.$child $!"; - } - } -} - -sub parent { - # Trap some possible signals to trigger temp file cleanup - $SIG{'KILL'} = $SIG{'INT'} = $SIG{'PIPE'} = \&cleanup; - - my %CHILDSOCK; - my $filename; - - ## fork child processes. Each child will create a socket connection - ## to this parent and use an unique temp filename to do so. - for (my $child = 1; $child <=$CHILDREN; $child++) { - $CHILDSOCK{$child}= FileHandle->new; - - if (!socket($CHILDSOCK{$child}, AF_UNIX, SOCK_STREAM, $PROTOCOL)) { - warn "parent socket to child failed $!"; - } - $filename = "./.socket.$parent.$child"; - my $response; - do { - $response = connect($CHILDSOCK{$child}, sockaddr_un($filename)); - if ($response != 1) { - sleep(1); - } - } while ($response != 1); - $CHILDSOCK{$child}->autoflush; - } - ## All child processes should now be ready or at worst warming up - - my (@buffer, $child, $ip, $rest, $hostname, $response); - ## read the logfile lines from STDIN - while() { - @buffer = (); # empty the logfile line buffer array. - $child = 1; # children are numbered 1..N, start with #1 - - # while we have a child to talk to and data to give it.. - do { - push(@buffer, $_); # buffer the line - ($ip, $rest) = split(/ /, $_, 2); # separate IP form rest - - unless ($hash{$ip}) { # resolve if unseen IP - $CHILDSOCK{$child}->print("$ip\n"); # pass IP to next child - $hash{$ip} = $ip; # don't look it up again. - $child++; - } - } while (($child < ($CHILDREN-1)) and ($_ = )); - - ## now poll each child for a response - while (--$child > 0) { - $response = $CHILDSOCK{$child}->getline; - chomp($response); - # child sends us back both the IP and HOSTNAME, no need for us - # to remember what child received any given IP, and no worries - # what order we talk to the children - ($ip, $hostname) = split(/\|/, $response, 2); - $hash{$ip} = $hostname; - } - - # resolve all the logfiles lines held in the log buffer array.. - for (my $line = 0; $line <=$#buffer; $line++) { - # get next buffered line - ($ip, $rest) = split(/ /, $buffer[$line], 2); - # separate IP from rest and replace with cached hostname - printf STDOUT ("%s %s", $hash{$ip}, $rest); - } - } -} - -######################################## - -sub child { - # arg = numeric ID - how the parent refers to me - my $me = shift; - - # add trap for alarm signals. - $SIG{'ALRM'} = sub { die "alarmed"; }; - - # create a socket to communicate with parent - socket(INBOUND, AF_UNIX, SOCK_STREAM, $PROTOCOL) - || die "Error with Socket: !$\n"; - $filename = "./.socket.$parent.$me"; - bind(INBOUND, sockaddr_un($filename)) - || die "Error Binding $filename: $!\n"; - listen(INBOUND, 5) || die "Error Listening: $!\n"; - - my ($ip, $send_back); - my $talk = FileHandle->new; - - # accept a connection from the parent process. We only ever have - # have one connection where we exchange 1 line of info with the - # parent.. 1 line in (IP address), 1 line out (IP + hostname). - accept($talk, INBOUND) || die "Error Accepting: $!\n"; - # disable I/O buffering just in case - $talk->autoflush; - # while the parent keeps sending data, we keep responding.. - while(($ip = $talk->getline)) { - chomp($ip); - # resolve the IP if time permits and send back what we found.. - $send_back = sprintf("%s|%s", $ip, &nslookup($ip)); - $talk->print($send_back."\n"); - } -} - -# perform a time restricted hostname lookup. -sub nslookup { - # get the IP as an arg - my $ip = shift; - my $hostname = undef; - - # do the hostname lookup inside an eval. The eval will use the - # already configured SIGnal handler and drop out of the {} block - # regardless of whether the alarm occured or not. - eval { - alarm($TIMEOUT); - $hostname = gethostbyaddr(gethostbyname($ip), AF_INET); - alarm(0); - }; - if ($@ =~ /alarm/) { - # useful for debugging perhaps.. - # print "alarming, isn't it? ($ip)"; - } - - # return the hostname or the IP address itself if there is no hostname - $hostname ne "" ? $hostname : $ip; -} - - diff --git a/support/phf_abuse_log.cgi b/support/phf_abuse_log.cgi deleted file mode 100644 index 87543ce5f48..00000000000 --- a/support/phf_abuse_log.cgi +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/perl - -# This script is used to detect people trying to abuse the security hole which -# existed in A CGI script direstributed with Apache 1.0.3 and earlier versions. -# You can redirect them to here using the "" suggestion -# in httpd.conf. -# -# The format logged to is -# "[date] remote_addr remote_host [date] referrer user_agent". - -$LOG = "/var/log/phf_log"; - -require "ctime.pl"; -$when = &ctime(time); -$when =~ s/\n//go; -$ENV{HTTP_USER_AGENT} .= " via $ENV{HTTP_VIA}" if($ENV{HTTP_VIA}); - -open(LOG, ">>$LOG") || die "boo hoo, phf_log $!"; -print LOG "[$when] $ENV{REMOTE_ADDR} $ENV{REMOTE_HOST} $ENV{$HTTP_REFERER} $ENV{HTTP_USER_AGENT}\n"; -close(LOG); - -print "Content-type: text/html\r\n\r\nSmile, you're on Candid Camera.\n"; diff --git a/support/split-logfile b/support/split-logfile deleted file mode 100644 index c0f34861aab..00000000000 --- a/support/split-logfile +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/perl -# ==================================================================== -# The Apache Software License, Version 1.1 -# -# Copyright (c) 2000-2001 The Apache Software Foundation. All rights -# reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# -# 3. The end-user documentation included with the redistribution, -# if any, must include the following acknowledgment: -# "This product includes software developed by the -# Apache Software Foundation (http://www.apache.org/)." -# Alternately, this acknowledgment may appear in the software itself, -# if and wherever such third-party acknowledgments normally appear. -# -# 4. The names "Apache" and "Apache Software Foundation" must -# not be used to endorse or promote products derived from this -# software without prior written permission. For written -# permission, please contact apache@apache.org. -# -# 5. Products derived from this software may not be called "Apache", -# nor may "Apache" appear in their name, without prior written -# permission of the Apache Software Foundation. -# -# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# ==================================================================== -# -# This software consists of voluntary contributions made by many -# individuals on behalf of the Apache Software Foundation. For more -# information on the Apache Software Foundation, please see -# . - -# This script will take a combined Web server access -# log file and break its contents into separate files. -# It assumes that the first field of each line is the -# virtual host identity (put there by "%v"), and that -# the logfiles should be named that+".log" in the current -# directory. -# -# The combined log file is read from stdin. Records read -# will be appended to any existing log files. -# -%is_open = (); - -while ($log_line = ) { - # - # Get the first token from the log record; it's the - # identity of the virtual host to which the record - # applies. - # - ($vhost) = split (/\s/, $log_line); - # - # Normalize the virtual host name to all lowercase. - # If it's blank, the request was handled by the default - # server, so supply a default name. This shouldn't - # happen, but caution rocks. - # - $vhost = lc ($vhost) or "access"; - # - # If the log file for this virtual host isn't opened - # yet, do it now. - # - if (! $is_open{$vhost}) { - open $vhost, ">>${vhost}.log" - or die ("Can't open ${vhost}.log"); - $is_open{$vhost} = 1; - } - # - # Strip off the first token (which may be null in the - # case of the default server), and write the edited - # record to the current log file. - # - $log_line =~ s/^\S*\s+//; - printf $vhost "%s", $log_line; -} -exit 0; -- 2.47.3