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 (i.e., a
*.var
- file) which names the files containing the variants
- explicitly, or
-
- - Using a 'MultiViews' search, where the server does an
- implicit filename pattern match and chooses from among the
- results.
-
-
- 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:
-
-
- - 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.
-
- - 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.
-
-
- Dimensions of Negotiation
-
-
-
- | Dimension |
-
- Notes |
-
-
-
- | Media Type |
-
- Browser 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). |
-
-
-
- | Language |
-
- Browser 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. |
-
-
-
- | Encoding |
-
- Browser indicates preference with the Accept-Encoding
- header field. Each item can have a quality factor. |
-
-
-
- | Charset |
-
- Browser 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:
-
-
- - 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.
-
- -
- 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.
-
-
- - 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.
-
- - Select the variants with the highest language quality
- factor.
-
- - 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).
-
- - Select the variants with the highest 'level' media
- parameter (used to give the version of text/html media
- types).
-
- - 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.
-
- - 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.
-
- - 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.
-
- - Select the variants with the smallest content
- length.
-
- - 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.
-
-
-
- - 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.
-
- - 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.
-
-
-
-
- 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:
-
-
- - foo.en.html
-
- - foo.html.en
-
- - foo.en.html.gz
-
-
- Here some more examples of filenames together with valid and
- invalid hyperlinks:
-
-
-
- | Filename |
-
- Valid hyperlink |
-
- Invalid hyperlink |
-
-
-
- | foo.html.en |
-
- foo
- foo.html |
-
- - |
-
-
-
- | foo.en.html |
-
- foo |
-
- foo.html |
-
-
-
- | foo.html.en.gz |
-
- foo
- foo.html |
-
- foo.gz
- foo.html.gz |
-
-
-
- | foo.en.html.gz |
-
- foo |
-
- foo.html
- foo.html.gz
- foo.gz |
-
-
-
- | foo.gz.html.en |
-
- foo
- foo.gz
- foo.gz.html |
-
- foo.html |
-
-
-
- | foo.html.gz.en |
-
- foo
- 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
-
-
- - apr_pool_t *p,
-
- - apr_pool_t *plog,
-
- - apr_pool_t *ptemp,
-
- - server_rec *s
-
-
- 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.
-
-
- - pool becomes apr_pool_t
-
- - table becomes apr_table_t
-
-
-
- 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...
-
-
- - HOOK_FIRST
-
- - HOOK_MIDDLE
-
- - HOOK_LAST
-
-
- 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 :
-
-
- - /* dir config creater */ ==> /* create per-directory
- config structures */
-
- - /* server config */ ==> /* create per-server config
- structures */
-
- - /* dir merger */ ==> /* merge per-directory config
- structures */
-
- - /* merge server config */ ==> /* merge per-server
- config structures */
-
- - /* command table */ ==> /* command apr_table_t */
-
- - /* handlers */ ==> /* handlers */
-
-
- The remainder of the old functions should be registered as
- hooks. There are the following hook stages defined so
- far...
-
-
- - ap_hook_post_config (this is where the old _init
- routines get registered)
-
- - ap_hook_http_method (retrieve the http method from a
- request. (legacy))
-
- - ap_hook_open_logs (open any specified logs)
-
- - ap_hook_auth_checker (check if the resource requires
- authorization)
-
- - ap_hook_access_checker (check for module-specific
- restrictions)
-
- - ap_hook_check_user_id (check the user-id and
- password)
-
- - ap_hook_default_port (retrieve the default port for
- the server)
-
- - ap_hook_pre_connection (do any setup required just
- before processing, but after accepting)
-
- - ap_hook_process_connection (run the correct
- protocol)
-
- - ap_hook_child_init (call as soon as the child is
- started)
-
- - ap_hook_create_request (??)
-
- - ap_hook_fixups (last chance to modify things before
- generating content)
-
- - ap_hook_handler (generate the content)
-
- - ap_hook_header_parser (let's modules look at the
- headers, not used by most modules, because they use
- post_read_request for this.)
-
- - ap_hook_insert_filter (to insert filters into the
- filter chain)
-
- - ap_hook_log_transaction (log information about the
- request)
-
- - ap_hook_optional_fn_retrieve (retrieve any functions
- registered as optional)
-
- - ap_hook_post_read_request (called after reading the
- request, before any other phase)
-
- - ap_hook_quick_handler (??)
-
- - ap_hook_translate_name (translate the URI into a
- filename)
-
- - ap_hook_type_checker (determine and/or set the doc
- type)
-
-
-
-
-
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.
-
-
-
-
-
-
-
-
- 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.
-
-
-
- To give you an overview of the DSO features of Apache 2.0,
- here is a short and concise summary:
-
-
- -
- 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
-
- |
-
-
-
-
- -
- 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
-
- |
-
-
-
-
- -
- Configure Apache for later installation of shared
- modules:
-
-
-
-
-
-$ ./configure --enable-so
-$ make install
-
- |
-
-
-
-
- -
- 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
-
- |
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
-
- The above DSO based features have the following
- advantages:
-
-
- - The server package is more flexible at run-time because
- the actual server process can be assembled at run-time via
LoadModule
- httpd.conf configuration commands instead of
- configure options at build-time. For instance
- this way one is able to run different server instances
- (standard & SSL version, minimalistic & powered up
- version [mod_perl, PHP3], etc.) with only one Apache
- installation.
-
- - The server package can be easily extended with
- third-party modules even after installation. This is at least
- a great benefit for vendor package maintainers who can create
- a Apache core package and additional packages containing
- extensions like PHP3, mod_perl, mod_fastcgi,
- etc.
-
- - Easier Apache module prototyping because with the
- DSO/
apxs pair you can both work outside the
- Apache source tree and only need an apxs -i
- command followed by an apachectl restart to
- bring a new version of your currently developed module into
- the running Apache server.
-
-
- DSO has the following disadvantages:
-
-
- - The DSO mechanism cannot be used on every platform
- because not all operating systems support dynamic loading of
- code into the address space of a program.
-
- - The server is approximately 20% slower at startup time
- because of the symbol resolving overhead the Unix loader now
- has to do.
-
- - The server is approximately 5% slower at execution time
- under some platforms because position independent code (PIC)
- sometimes needs complicated assembler tricks for relative
- addressing which are not necessarily as fast as absolute
- addressing.
-
- - Because DSO modules cannot be linked against other
- DSO-based libraries (
ld -lfoo) on all platforms
- (for instance a.out-based platforms usually don't provide
- this functionality while ELF-based platforms do) you cannot
- use the DSO mechanism for all types of modules. Or in other
- words, modules compiled as DSO files are restricted to only
- use symbols from the Apache core, from the C library
- (libc) and all other dynamic or static libraries
- used by the Apache core, or from static library archives
- (libfoo.a) containing position independent code.
- The only chances to use other code is to either make sure the
- Apache core itself already contains a reference to it or
- loading the code yourself via dlopen().
-
-
-
-
-
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
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
-
- 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:
-
-
- - Trying to start the server on a privileged port when not
- logged in as the root user; or
-
- - Trying to start the server when there is another instance
- of Apache or some other web server already bound to the same
- Port.
-
-
- For further trouble-shooting instructions, consult the
- Apache FAQ.
-
-
-
- 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 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.
-
-
-
-
-
-
- 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.
-
-
-
-
-
-
- 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
-
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
-
-
- 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 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.
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
-
- 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
-
-
-
-
-
-
- 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.
-
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
-
- This quite simply lists the name of the source module which
- defines the directive.
-
-
-
-
- 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."
-
-
-
-
- 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
-
-
-
-
-
-
- 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.
-
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
-
- 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
-
-
-
-
- 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
-
-
-
-
- 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.
-
-
-
- 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:
-
-
- - Your system does not provide the setrlimit() system
- call.
-
- - The setrlimit(RLIMIT_NOFILE) call does not function on
- your system (such as Solaris 2.3)
-
- - The number of file descriptors required exceeds the hard
- limit.
-
- - Your system imposes other limits on file descriptors,
- such as a limit on stdio streams only using file descriptors
- below 256. (Solaris 2)
-
- In the event of problems you can:
-
-
- - Reduce the number of log files; don't specify log files
- in the VirtualHost sections, but only log to the main log
- files.
-
- -
- If you system falls into 1 or 2 (above), then increase the
- file descriptor limit before starting Apache, using a
- script like
-
-
- #!/bin/sh
- ulimit -S -n 100
- exec httpd
-
-
-
-
- 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.
-
-
-
-
-
-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:
-
-
-
-- Some ancient clients are not compatible with name-based virtual
-hosting. For name-based virtual hosting to work, the client must send
-the HTTP Host header. This is required by HTTP/1.1, and is
-implemented by all modern HTTP/1.0 browsers as an extension. If you
-need to support obsolete clients and still use name-based virtual
-hosting, a possible technique is discussed at the end of this
-document.
-
-- Name-based virtual hosting cannot be used with SSL secure servers
-because of the nature of the SSL protocol.
-
-- Some operating systems and network equipment implement bandwidth
-management techniques that cannot differentiate between hosts unless
-they are on separate IP addresses.
-
-
-
-
-
-
-
-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.
-
-
-
- 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"
- "| Cache Name | "
- "Entries | "
- "Avg. Chain Len. | "
- "Hits | "
- "Ins/Rem | "
- "Purges | "
- "Avg Purge Time | "
- "
\n", r
- );
-
- ap_rputs(util_ald_cache_display(r->pool), r);
-
- ap_rputs("
\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\n\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