summaryrefslogtreecommitdiffstats
path: root/modules/aaa
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
commit5dff2d61cc1c27747ee398e04d8e02843aabb1f8 (patch)
treea67c336b406c8227bac912beb74a1ad3cdc55100 /modules/aaa
parentInitial commit. (diff)
downloadapache2-upstream.tar.xz
apache2-upstream.zip
Adding upstream version 2.4.38.upstream/2.4.38upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules/aaa')
-rw-r--r--modules/aaa/.indent.pro54
-rw-r--r--modules/aaa/Makefile.in3
-rw-r--r--modules/aaa/NWGNUaccesscompat248
-rw-r--r--modules/aaa/NWGNUallowmethods248
-rw-r--r--modules/aaa/NWGNUauthbasc248
-rw-r--r--modules/aaa/NWGNUauthdigt248
-rw-r--r--modules/aaa/NWGNUauthform250
-rw-r--r--modules/aaa/NWGNUauthnano248
-rw-r--r--modules/aaa/NWGNUauthndbd249
-rw-r--r--modules/aaa/NWGNUauthndbm248
-rw-r--r--modules/aaa/NWGNUauthnfil248
-rw-r--r--modules/aaa/NWGNUauthnsocache248
-rw-r--r--modules/aaa/NWGNUauthnzldap264
-rw-r--r--modules/aaa/NWGNUauthzdbd249
-rw-r--r--modules/aaa/NWGNUauthzdbm248
-rw-r--r--modules/aaa/NWGNUauthzgrp247
-rw-r--r--modules/aaa/NWGNUauthzusr247
-rw-r--r--modules/aaa/NWGNUmakefile270
-rw-r--r--modules/aaa/config.m484
-rw-r--r--modules/aaa/mod_access_compat.c377
-rw-r--r--modules/aaa/mod_access_compat.dep59
-rw-r--r--modules/aaa/mod_access_compat.dsp111
-rw-r--r--modules/aaa/mod_access_compat.mak353
-rw-r--r--modules/aaa/mod_allowmethods.c158
-rw-r--r--modules/aaa/mod_allowmethods.dep56
-rw-r--r--modules/aaa/mod_allowmethods.dsp111
-rw-r--r--modules/aaa/mod_allowmethods.mak353
-rw-r--r--modules/aaa/mod_auth_basic.c508
-rw-r--r--modules/aaa/mod_auth_basic.dep63
-rw-r--r--modules/aaa/mod_auth_basic.dsp111
-rw-r--r--modules/aaa/mod_auth_basic.mak353
-rw-r--r--modules/aaa/mod_auth_digest.c1976
-rw-r--r--modules/aaa/mod_auth_digest.dep68
-rw-r--r--modules/aaa/mod_auth_digest.dsp111
-rw-r--r--modules/aaa/mod_auth_digest.mak353
-rw-r--r--modules/aaa/mod_auth_form.c1333
-rw-r--r--modules/aaa/mod_auth_form.dep66
-rw-r--r--modules/aaa/mod_auth_form.dsp111
-rw-r--r--modules/aaa/mod_auth_form.mak353
-rw-r--r--modules/aaa/mod_authn_anon.c215
-rw-r--r--modules/aaa/mod_authn_anon.dep58
-rw-r--r--modules/aaa/mod_authn_anon.dsp111
-rw-r--r--modules/aaa/mod_authn_anon.mak381
-rw-r--r--modules/aaa/mod_authn_core.c386
-rw-r--r--modules/aaa/mod_authn_core.dep58
-rw-r--r--modules/aaa/mod_authn_core.dsp111
-rw-r--r--modules/aaa/mod_authn_core.mak381
-rw-r--r--modules/aaa/mod_authn_dbd.c309
-rw-r--r--modules/aaa/mod_authn_dbd.dep56
-rw-r--r--modules/aaa/mod_authn_dbd.dsp115
-rw-r--r--modules/aaa/mod_authn_dbd.mak409
-rw-r--r--modules/aaa/mod_authn_dbm.c208
-rw-r--r--modules/aaa/mod_authn_dbm.dep61
-rw-r--r--modules/aaa/mod_authn_dbm.dsp111
-rw-r--r--modules/aaa/mod_authn_dbm.mak381
-rw-r--r--modules/aaa/mod_authn_file.c194
-rw-r--r--modules/aaa/mod_authn_file.dep60
-rw-r--r--modules/aaa/mod_authn_file.dsp111
-rw-r--r--modules/aaa/mod_authn_file.mak381
-rw-r--r--modules/aaa/mod_authn_socache.c475
-rw-r--r--modules/aaa/mod_authn_socache.dep62
-rw-r--r--modules/aaa/mod_authn_socache.dsp111
-rw-r--r--modules/aaa/mod_authn_socache.mak353
-rw-r--r--modules/aaa/mod_authnz_fcgi.c1363
-rw-r--r--modules/aaa/mod_authnz_fcgi.dep61
-rw-r--r--modules/aaa/mod_authnz_fcgi.dsp119
-rw-r--r--modules/aaa/mod_authnz_fcgi.mak353
-rw-r--r--modules/aaa/mod_authnz_ldap.c1962
-rw-r--r--modules/aaa/mod_authnz_ldap.dep70
-rw-r--r--modules/aaa/mod_authnz_ldap.dsp111
-rw-r--r--modules/aaa/mod_authnz_ldap.mak381
-rw-r--r--modules/aaa/mod_authz_core.c1175
-rw-r--r--modules/aaa/mod_authz_core.dep60
-rw-r--r--modules/aaa/mod_authz_core.dsp111
-rw-r--r--modules/aaa/mod_authz_core.mak381
-rw-r--r--modules/aaa/mod_authz_dbd.c409
-rw-r--r--modules/aaa/mod_authz_dbd.dep61
-rw-r--r--modules/aaa/mod_authz_dbd.dsp119
-rw-r--r--modules/aaa/mod_authz_dbd.h44
-rw-r--r--modules/aaa/mod_authz_dbd.mak409
-rw-r--r--modules/aaa/mod_authz_dbm.c336
-rw-r--r--modules/aaa/mod_authz_dbm.dep62
-rw-r--r--modules/aaa/mod_authz_dbm.dsp111
-rw-r--r--modules/aaa/mod_authz_dbm.mak381
-rw-r--r--modules/aaa/mod_authz_groupfile.c331
-rw-r--r--modules/aaa/mod_authz_groupfile.dep61
-rw-r--r--modules/aaa/mod_authz_groupfile.dsp111
-rw-r--r--modules/aaa/mod_authz_groupfile.mak381
-rw-r--r--modules/aaa/mod_authz_host.c410
-rw-r--r--modules/aaa/mod_authz_host.dep60
-rw-r--r--modules/aaa/mod_authz_host.dsp111
-rw-r--r--modules/aaa/mod_authz_host.mak381
-rw-r--r--modules/aaa/mod_authz_owner.c189
-rw-r--r--modules/aaa/mod_authz_owner.dep59
-rw-r--r--modules/aaa/mod_authz_owner.dsp111
-rw-r--r--modules/aaa/mod_authz_owner.h27
-rw-r--r--modules/aaa/mod_authz_owner.mak381
-rw-r--r--modules/aaa/mod_authz_user.c146
-rw-r--r--modules/aaa/mod_authz_user.dep58
-rw-r--r--modules/aaa/mod_authz_user.dsp111
-rw-r--r--modules/aaa/mod_authz_user.mak381
101 files changed, 27619 insertions, 0 deletions
diff --git a/modules/aaa/.indent.pro b/modules/aaa/.indent.pro
new file mode 100644
index 0000000..a9fbe9f
--- /dev/null
+++ b/modules/aaa/.indent.pro
@@ -0,0 +1,54 @@
+-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1
+-TBUFF
+-TFILE
+-TTRANS
+-TUINT4
+-T_trans
+-Tallow_options_t
+-Tapache_sfio
+-Tarray_header
+-Tbool_int
+-Tbuf_area
+-Tbuff_struct
+-Tbuffy
+-Tcmd_how
+-Tcmd_parms
+-Tcommand_rec
+-Tcommand_struct
+-Tconn_rec
+-Tcore_dir_config
+-Tcore_server_config
+-Tdir_maker_func
+-Tevent
+-Tglobals_s
+-Thandler_func
+-Thandler_rec
+-Tjoblist_s
+-Tlisten_rec
+-Tmerger_func
+-Tmode_t
+-Tmodule
+-Tmodule_struct
+-Tmutex
+-Tn_long
+-Tother_child_rec
+-Toverrides_t
+-Tparent_score
+-Tpid_t
+-Tpiped_log
+-Tpool
+-Trequest_rec
+-Trequire_line
+-Trlim_t
+-Tscoreboard
+-Tsemaphore
+-Tserver_addr_rec
+-Tserver_rec
+-Tserver_rec_chain
+-Tshort_score
+-Ttable
+-Ttable_entry
+-Tthread
+-Tu_wide_int
+-Tvtime_t
+-Twide_int
diff --git a/modules/aaa/Makefile.in b/modules/aaa/Makefile.in
new file mode 100644
index 0000000..167b343
--- /dev/null
+++ b/modules/aaa/Makefile.in
@@ -0,0 +1,3 @@
+
+include $(top_srcdir)/build/special.mk
+
diff --git a/modules/aaa/NWGNUaccesscompat b/modules/aaa/NWGNUaccesscompat
new file mode 100644
index 0000000..bfa7b20
--- /dev/null
+++ b/modules/aaa/NWGNUaccesscompat
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = accesscompat
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) host access control compatibility Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AccessCompModule
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/accesscompat.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_access_compat.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ access_compat_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUallowmethods b/modules/aaa/NWGNUallowmethods
new file mode 100644
index 0000000..c2373f5
--- /dev/null
+++ b/modules/aaa/NWGNUallowmethods
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = allowmethods
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Method Restriction Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = Allowmethods Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/allowmethods.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_allowmethods.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ allowmethods_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthbasc b/modules/aaa/NWGNUauthbasc
new file mode 100644
index 0000000..1f43464
--- /dev/null
+++ b/modules/aaa/NWGNUauthbasc
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authbasc
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Basic Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthBasic Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authbasc.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_auth_basic.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ auth_basic_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthdigt b/modules/aaa/NWGNUauthdigt
new file mode 100644
index 0000000..39738f2
--- /dev/null
+++ b/modules/aaa/NWGNUauthdigt
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authdigt
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Digest Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = Digest Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authdigt.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_auth_digest.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ auth_digest_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthform b/modules/aaa/NWGNUauthform
new file mode 100644
index 0000000..5b42ab5
--- /dev/null
+++ b/modules/aaa/NWGNUauthform
@@ -0,0 +1,250 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(STDMOD)/session \
+ $(STDMOD)/filters \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authform
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Basic Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthBasic Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/$(NLM_NAME).nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_auth_form.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ auth_form_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthnano b/modules/aaa/NWGNUauthnano
new file mode 100644
index 0000000..b115314
--- /dev/null
+++ b/modules/aaa/NWGNUauthnano
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authnano
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Anonymous Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthAnon Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authnano.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authn_anon.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authn_anon_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthndbd b/modules/aaa/NWGNUauthndbd
new file mode 100644
index 0000000..151bc1c
--- /dev/null
+++ b/modules/aaa/NWGNUauthndbd
@@ -0,0 +1,249 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(AP_WORK)/modules/database \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authndbd
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) SQL Database Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthnDBD Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authndbd.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authn_dbd.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authn_dbd_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthndbm b/modules/aaa/NWGNUauthndbm
new file mode 100644
index 0000000..1f9880e
--- /dev/null
+++ b/modules/aaa/NWGNUauthndbm
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authndbm
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Database Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthnDBM Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authndbm.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authn_dbm.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authn_dbm_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthnfil b/modules/aaa/NWGNUauthnfil
new file mode 100644
index 0000000..cfab287
--- /dev/null
+++ b/modules/aaa/NWGNUauthnfil
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authnfil
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) File Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthnFile Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authnfil.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authn_file.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authn_file_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthnsocache b/modules/aaa/NWGNUauthnsocache
new file mode 100644
index 0000000..8d1b347
--- /dev/null
+++ b/modules/aaa/NWGNUauthnsocache
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authnsocache
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Authentication Cache Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthnSOCache Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authnsocache.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authn_socache.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authn_socache_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthnzldap b/modules/aaa/NWGNUauthnzldap
new file mode 100644
index 0000000..bfe21db
--- /dev/null
+++ b/modules/aaa/NWGNUauthnzldap
@@ -0,0 +1,264 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+#LDAP client requires the use of Winsock
+#
+ifdef USE_STDSOCKETS
+XDEFINES += -DUSE_WINSOCK \
+ $(EOLIST)
+endif
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authnzldap
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) LDAP Authentication Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthnzLDAP Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authnzldap.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authnz_ldap.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ lldapsdk \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ util_ldap_connection_find \
+ util_ldap_connection_close \
+ util_ldap_cache_checkuserid \
+ util_ldap_cache_getuserdn \
+ util_ldap_cache_compare \
+ util_ldap_cache_comparedn \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ @lldapsdk.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authnz_ldap_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthzdbd b/modules/aaa/NWGNUauthzdbd
new file mode 100644
index 0000000..3ea2ba7
--- /dev/null
+++ b/modules/aaa/NWGNUauthzdbd
@@ -0,0 +1,249 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(STDMOD)/database \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authzdbd
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) DBD Database Authorization Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthzDBD Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authzdbd.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authz_dbd.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authz_dbd_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthzdbm b/modules/aaa/NWGNUauthzdbm
new file mode 100644
index 0000000..3d0ed8f
--- /dev/null
+++ b/modules/aaa/NWGNUauthzdbm
@@ -0,0 +1,248 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authzdbm
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Database Authorization Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthzDBM Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authzdbm.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authz_dbm.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authz_dbm_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/NWGNUauthzgrp b/modules/aaa/NWGNUauthzgrp
new file mode 100644
index 0000000..4a8df2c
--- /dev/null
+++ b/modules/aaa/NWGNUauthzgrp
@@ -0,0 +1,247 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authzgrp
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) Group File Authorization Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthzGrp Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authzgrp.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authz_groupfile.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authz_groupfile_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
diff --git a/modules/aaa/NWGNUauthzusr b/modules/aaa/NWGNUauthzusr
new file mode 100644
index 0000000..aa79053
--- /dev/null
+++ b/modules/aaa/NWGNUauthzusr
@@ -0,0 +1,247 @@
+#
+# Make sure all needed macro's are defined
+#
+
+#
+# Get the 'head' of the build environment if necessary. This includes default
+# targets and paths to tools
+#
+
+ifndef EnvironmentDefined
+include $(AP_WORK)/build/NWGNUhead.inc
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(APR)/include \
+ $(APRUTIL)/include \
+ $(AP_WORK)/include \
+ $(NWOS) \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME = authzusr
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION = Apache $(VERSION_STR) User Authorization Module
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME = AuthzUser Module
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE = 8192
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authzusr.nlm \
+ $(EOLIST)
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(OBJDIR)/mod_authz_user.o \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(PRELUDE) \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ aprlib \
+ libc \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ @aprlib.imp \
+ @httpd.imp \
+ @libc.imp \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ authz_user_module \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
diff --git a/modules/aaa/NWGNUmakefile b/modules/aaa/NWGNUmakefile
new file mode 100644
index 0000000..fdb23f6
--- /dev/null
+++ b/modules/aaa/NWGNUmakefile
@@ -0,0 +1,270 @@
+#
+# Declare the sub-directories to be built here
+#
+
+SUBDIRS = \
+ $(EOLIST)
+
+#
+# Get the 'head' of the build environment. This includes default targets and
+# paths to tools
+#
+
+include $(AP_WORK)/build/NWGNUhead.inc
+
+#
+# build this level's files
+
+#
+# Make sure all needed macro's are defined
+#
+ifeq "$(wildcard $(APRUTIL)/include/apr_ldap.h)" "$(APRUTIL)/include/apr_ldap.h"
+WITH_LDAP = $(shell $(AWK) '/^\#define APR_HAS_LDAP /{print $$3}' $(APRUTIL)/include/apr_ldap.h)
+else
+WITH_LDAP = 0
+endif
+
+#
+# These directories will be at the beginning of the include list, followed by
+# INCDIRS
+#
+XINCDIRS += \
+ $(EOLIST)
+
+#
+# These flags will come after CFLAGS
+#
+XCFLAGS += \
+ $(EOLIST)
+
+#
+# These defines will come after DEFINES
+#
+XDEFINES += \
+ $(EOLIST)
+
+#
+# These flags will be added to the link.opt file
+#
+XLFLAGS += \
+ $(EOLIST)
+
+#
+# These values will be appended to the correct variables based on the value of
+# RELEASE
+#
+ifeq "$(RELEASE)" "debug"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "noopt"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+ifeq "$(RELEASE)" "release"
+XINCDIRS += \
+ $(EOLIST)
+
+XCFLAGS += \
+ $(EOLIST)
+
+XDEFINES += \
+ $(EOLIST)
+
+XLFLAGS += \
+ $(EOLIST)
+endif
+
+#
+# These are used by the link target if an NLM is being generated
+# This is used by the link 'name' directive to name the nlm. If left blank
+# TARGET_nlm (see below) will be used.
+#
+NLM_NAME =
+
+#
+# This is used by the link '-desc ' directive.
+# If left blank, NLM_NAME will be used.
+#
+NLM_DESCRIPTION =
+
+#
+# This is used by the '-threadname' directive. If left blank,
+# NLM_NAME Thread will be used.
+#
+NLM_THREAD_NAME =
+
+#
+# If this is specified, it will override VERSION value in
+# $(AP_WORK)/build/NWGNUenvironment.inc
+#
+NLM_VERSION =
+
+#
+# If this is specified, it will override the default of 64K
+#
+NLM_STACK_SIZE =
+
+
+#
+# If this is specified it will be used by the link '-entry' directive
+#
+NLM_ENTRY_SYM =
+
+#
+# If this is specified it will be used by the link '-exit' directive
+#
+NLM_EXIT_SYM =
+
+#
+# If this is specified it will be used by the link '-check' directive
+#
+NLM_CHECK_SYM =
+
+#
+# If these are specified it will be used by the link '-flags' directive
+#
+NLM_FLAGS =
+
+#
+# If this is specified it will be linked in with the XDCData option in the def
+# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
+# by setting APACHE_UNIPROC in the environment
+#
+XDCDATA =
+
+#
+# If there is an NLM target, put it here
+#
+TARGET_nlm = \
+ $(OBJDIR)/authbasc.nlm \
+ $(OBJDIR)/authdigt.nlm \
+ $(OBJDIR)/authform.nlm \
+ $(OBJDIR)/authnano.nlm \
+ $(OBJDIR)/authndbd.nlm \
+ $(OBJDIR)/authndbm.nlm \
+ $(OBJDIR)/authnfil.nlm \
+ $(OBJDIR)/authnsocache.nlm \
+ $(OBJDIR)/authzdbd.nlm \
+ $(OBJDIR)/authzdbm.nlm \
+ $(OBJDIR)/authzgrp.nlm \
+ $(OBJDIR)/authzusr.nlm \
+ $(OBJDIR)/allowmethods.nlm \
+ $(OBJDIR)/accesscompat.nlm \
+ $(EOLIST)
+
+# If WITH_LDAP and LDAPSDK have been defined then build the authnz_ldap module
+ifeq "$(WITH_LDAP)" "1"
+ifneq "$(LDAPSDK)" ""
+TARGET_nlm += $(OBJDIR)/authnzldap.nlm
+endif
+endif
+
+#
+# If there is an LIB target, put it here
+#
+TARGET_lib = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the NLM target above.
+# Paths must all use the '/' character
+#
+FILES_nlm_objs = \
+ $(EOLIST)
+
+#
+# These are the LIB files needed to create the NLM target above.
+# These will be added as a library command in the link.opt file.
+#
+FILES_nlm_libs = \
+ $(EOLIST)
+
+#
+# These are the modules that the above NLM target depends on to load.
+# These will be added as a module command in the link.opt file.
+#
+FILES_nlm_modules = \
+ $(EOLIST)
+
+#
+# If the nlm has a msg file, put it's path here
+#
+FILE_nlm_msg =
+
+#
+# If the nlm has a hlp file put it's path here
+#
+FILE_nlm_hlp =
+
+#
+# If this is specified, it will override $(NWOS)\copyright.txt.
+#
+FILE_nlm_copyright =
+
+#
+# Any additional imports go here
+#
+FILES_nlm_Ximports = \
+ $(EOLIST)
+
+#
+# Any symbols exported to here
+#
+FILES_nlm_exports = \
+ $(EOLIST)
+
+#
+# These are the OBJ files needed to create the LIB target above.
+# Paths must all use the '/' character
+#
+FILES_lib_objs = \
+ $(EOLIST)
+
+#
+# implement targets and dependancies (leave this section alone)
+#
+
+libs :: $(OBJDIR) $(TARGET_lib)
+
+nlms :: libs $(TARGET_nlm)
+
+#
+# Updated this target to create necessary directories and copy files to the
+# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
+#
+install :: nlms FORCE
+ $(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
+
+#
+# Any specialized rules here
+#
+
+#
+# Include the 'tail' makefile that has targets that depend on variables defined
+# in this makefile
+#
+
+include $(APBUILD)/NWGNUtail.inc
+
+
diff --git a/modules/aaa/config.m4 b/modules/aaa/config.m4
new file mode 100644
index 0000000..b443761
--- /dev/null
+++ b/modules/aaa/config.m4
@@ -0,0 +1,84 @@
+dnl modules enabled in this directory by default
+
+dnl Authentication (authn), Access, and Authorization (authz)
+
+dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
+
+APACHE_MODPATH_INIT(aaa)
+
+dnl Authentication modules; modules checking a username and password against a
+dnl file, database, or other similar magic.
+dnl
+APACHE_MODULE(authn_file, file-based authentication control, , , yes)
+APACHE_MODULE(authn_dbm, DBM-based authentication control, , , most)
+APACHE_MODULE(authn_anon, anonymous user authentication control, , , most)
+APACHE_MODULE(authn_dbd, SQL-based authentication control, , , most)
+APACHE_MODULE(authn_socache, Cached authentication control, , , most)
+
+dnl General Authentication modules; module which implements the
+dnl non-authn module specific directives.
+dnl
+APACHE_MODULE(authn_core, core authentication module, , , yes)
+
+dnl Authorization modules: modules which verify a certain property such as
+dnl membership of a group, value of the IP address against a list of pre
+dnl configured directives (e.g. require, allow) or against an external file
+dnl or database.
+dnl
+APACHE_MODULE(authz_host, host-based authorization control, , , yes)
+APACHE_MODULE(authz_groupfile, 'require group' authorization control, , , yes)
+APACHE_MODULE(authz_user, 'require user' authorization control, , , yes)
+APACHE_MODULE(authz_dbm, DBM-based authorization control, , , most)
+APACHE_MODULE(authz_owner, 'require file-owner' authorization control, , , most)
+APACHE_MODULE(authz_dbd, SQL based authorization and Login/Session support, , , most)
+
+dnl General Authorization modules; provider module which implements the
+dnl non-authz module specific directives.
+dnl
+APACHE_MODULE(authz_core, core authorization provider vector module, , , yes)
+
+dnl LDAP authentication module. This module has both the authn and authz
+dnl modules in one, so as to share the LDAP server config directives.
+APACHE_MODULE(authnz_ldap, LDAP based authentication, , , most, [
+ APACHE_CHECK_APR_HAS_LDAP
+ if test "$ac_cv_APR_HAS_LDAP" = "yes" ; then
+ if test -z "$apu_config" ; then
+ LDAP_LIBS="`$apr_config --ldap-libs`"
+ else
+ LDAP_LIBS="`$apu_config --ldap-libs`"
+ fi
+ APR_ADDTO(MOD_AUTHNZ_LDAP_LDADD, [$LDAP_LIBS])
+ AC_SUBST(MOD_AUTHNZ_LDAP_LDADD)
+ else
+ AC_MSG_WARN([apr/apr-util is compiled without ldap support])
+ enable_authnz_ldap=no
+ fi
+])
+
+dnl FastCGI authorizer interface, supporting authn and authz.
+APACHE_MODULE(authnz_fcgi,
+ FastCGI authorizer-based authentication and authorization, , , no)
+
+dnl - host access control compatibility modules. Implements Order, Allow,
+dnl Deny, Satisfy for backward compatibility. These directives have been
+dnl deprecated in 2.4.
+APACHE_MODULE(access_compat, mod_access compatibility, , , yes)
+
+dnl these are the front-end authentication modules
+
+APACHE_MODULE(auth_basic, basic authentication, , , yes)
+APACHE_MODULE(auth_form, form authentication, , , most)
+APACHE_MODULE(auth_digest, RFC2617 Digest authentication, , , most, [
+ APR_CHECK_APR_DEFINE(APR_HAS_RANDOM)
+ if test $ac_cv_define_APR_HAS_RANDOM = "no"; then
+ echo "You need APR random support to use mod_auth_digest."
+ echo "Look at APR configure options --with-egd and --with-devrandom."
+ enable_auth_digest="no"
+ fi
+])
+
+APACHE_MODULE(allowmethods, restrict allowed HTTP methods, , , most)
+
+APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
+
+APACHE_MODPATH_FINISH
diff --git a/modules/aaa/mod_access_compat.c b/modules/aaa/mod_access_compat.c
new file mode 100644
index 0000000..e9f1abe
--- /dev/null
+++ b/modules/aaa/mod_access_compat.c
@@ -0,0 +1,377 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Security options etc.
+ *
+ * Module derived from code originally written by Rob McCool
+ *
+ */
+
+#include "apr_strings.h"
+#include "apr_network_io.h"
+#include "apr_md5.h"
+
+#define APR_WANT_STRFUNC
+#define APR_WANT_BYTEFUNC
+#include "apr_want.h"
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_core.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h"
+
+#include "mod_auth.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+enum allowdeny_type {
+ T_ENV,
+ T_NENV,
+ T_ALL,
+ T_IP,
+ T_HOST,
+ T_FAIL
+};
+
+typedef struct {
+ apr_int64_t limited;
+ union {
+ char *from;
+ apr_ipsubnet_t *ip;
+ } x;
+ enum allowdeny_type type;
+} allowdeny;
+
+/* things in the 'order' array */
+#define DENY_THEN_ALLOW 0
+#define ALLOW_THEN_DENY 1
+#define MUTUAL_FAILURE 2
+
+typedef struct {
+ int order[METHODS];
+ apr_array_header_t *allows;
+ apr_array_header_t *denys;
+ int *satisfy; /* for every method one */
+} access_compat_dir_conf;
+
+module AP_MODULE_DECLARE_DATA access_compat_module;
+
+static void *create_access_compat_dir_config(apr_pool_t *p, char *dummy)
+{
+ int i;
+ access_compat_dir_conf *conf =
+ (access_compat_dir_conf *)apr_pcalloc(p, sizeof(access_compat_dir_conf));
+
+ for (i = 0; i < METHODS; ++i) {
+ conf->order[i] = DENY_THEN_ALLOW;
+ }
+ conf->allows = apr_array_make(p, 1, sizeof(allowdeny));
+ conf->denys = apr_array_make(p, 1, sizeof(allowdeny));
+ conf->satisfy = apr_palloc(p, sizeof(*conf->satisfy) * METHODS);
+ for (i = 0; i < METHODS; ++i) {
+ conf->satisfy[i] = SATISFY_NOSPEC;
+ }
+
+ return (void *)conf;
+}
+
+static const char *order(cmd_parms *cmd, void *dv, const char *arg)
+{
+ access_compat_dir_conf *d = (access_compat_dir_conf *) dv;
+ int i, o;
+
+ if (!strcasecmp(arg, "allow,deny"))
+ o = ALLOW_THEN_DENY;
+ else if (!strcasecmp(arg, "deny,allow"))
+ o = DENY_THEN_ALLOW;
+ else if (!strcasecmp(arg, "mutual-failure"))
+ o = MUTUAL_FAILURE;
+ else
+ return "unknown order";
+
+ for (i = 0; i < METHODS; ++i)
+ if (cmd->limited & (AP_METHOD_BIT << i))
+ d->order[i] = o;
+
+ return NULL;
+}
+
+static const char *satisfy(cmd_parms *cmd, void *dv, const char *arg)
+{
+ access_compat_dir_conf *d = (access_compat_dir_conf *) dv;
+ int satisfy = SATISFY_NOSPEC;
+ int i;
+
+ if (!strcasecmp(arg, "all")) {
+ satisfy = SATISFY_ALL;
+ }
+ else if (!strcasecmp(arg, "any")) {
+ satisfy = SATISFY_ANY;
+ }
+ else {
+ return "Satisfy either 'any' or 'all'.";
+ }
+
+ for (i = 0; i < METHODS; ++i) {
+ if (cmd->limited & (AP_METHOD_BIT << i)) {
+ d->satisfy[i] = satisfy;
+ }
+ }
+
+ return NULL;
+}
+
+static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from,
+ const char *where_c)
+{
+ access_compat_dir_conf *d = (access_compat_dir_conf *) dv;
+ allowdeny *a;
+ char *where = apr_pstrdup(cmd->pool, where_c);
+ char *s;
+ apr_status_t rv;
+
+ if (strcasecmp(from, "from"))
+ return "allow and deny must be followed by 'from'";
+
+ a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys);
+ a->x.from = where;
+ a->limited = cmd->limited;
+
+ if (!strncasecmp(where, "env=!", 5)) {
+ a->type = T_NENV;
+ a->x.from += 5;
+
+ }
+ else if (!strncasecmp(where, "env=", 4)) {
+ a->type = T_ENV;
+ a->x.from += 4;
+
+ }
+ else if (!strcasecmp(where, "all")) {
+ a->type = T_ALL;
+ }
+ else if ((s = ap_strchr(where, '/'))) {
+ *s++ = '\0';
+ rv = apr_ipsubnet_create(&a->x.ip, where, s, cmd->pool);
+ if(APR_STATUS_IS_EINVAL(rv)) {
+ /* looked nothing like an IP address */
+ return "An IP address was expected";
+ }
+ else if (rv != APR_SUCCESS) {
+ return apr_psprintf(cmd->pool, "%pm", &rv);
+ }
+ a->type = T_IP;
+ }
+ else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&a->x.ip, where,
+ NULL, cmd->pool))) {
+ if (rv != APR_SUCCESS)
+ return apr_psprintf(cmd->pool, "%pm", &rv);
+ a->type = T_IP;
+ }
+ else if (ap_strchr(where, '#')) {
+ return "No comments are allowed here";
+ }
+ else { /* no slash, didn't look like an IP address => must be a host */
+ a->type = T_HOST;
+ }
+
+ return NULL;
+}
+
+static char its_an_allow;
+
+static const command_rec access_compat_cmds[] =
+{
+ AP_INIT_TAKE1("order", order, NULL, OR_LIMIT,
+ "'allow,deny', 'deny,allow', or 'mutual-failure'"),
+ AP_INIT_ITERATE2("allow", allow_cmd, &its_an_allow, OR_LIMIT,
+ "'from' followed by hostnames or IP-address wildcards"),
+ AP_INIT_ITERATE2("deny", allow_cmd, NULL, OR_LIMIT,
+ "'from' followed by hostnames or IP-address wildcards"),
+ AP_INIT_TAKE1("Satisfy", satisfy, NULL, OR_AUTHCFG,
+ "access policy if both allow and require used ('all' or 'any')"),
+ {NULL}
+};
+
+static int in_domain(const char *domain, const char *what)
+{
+ int dl = strlen(domain);
+ int wl = strlen(what);
+
+ if ((wl - dl) >= 0) {
+ if (strcasecmp(domain, &what[wl - dl]) != 0) {
+ return 0;
+ }
+
+ /* Make sure we matched an *entire* subdomain --- if the user
+ * said 'allow from good.com', we don't want people from nogood.com
+ * to be able to get in.
+ */
+
+ if (wl == dl) {
+ return 1; /* matched whole thing */
+ }
+ else {
+ return (domain[0] == '.' || what[wl - dl - 1] == '.');
+ }
+ }
+ else {
+ return 0;
+ }
+}
+
+static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
+{
+
+ allowdeny *ap = (allowdeny *) a->elts;
+ apr_int64_t mmask = (AP_METHOD_BIT << method);
+ int i;
+ int gothost = 0;
+ const char *remotehost = NULL;
+
+ for (i = 0; i < a->nelts; ++i) {
+ if (!(mmask & ap[i].limited)) {
+ continue;
+ }
+
+ switch (ap[i].type) {
+ case T_ENV:
+ if (apr_table_get(r->subprocess_env, ap[i].x.from)) {
+ return 1;
+ }
+ break;
+
+ case T_NENV:
+ if (!apr_table_get(r->subprocess_env, ap[i].x.from)) {
+ return 1;
+ }
+ break;
+
+ case T_ALL:
+ return 1;
+
+ case T_IP:
+ if (apr_ipsubnet_test(ap[i].x.ip, r->useragent_addr)) {
+ return 1;
+ }
+ break;
+
+ case T_HOST:
+ if (!gothost) {
+ int remotehost_is_ip;
+
+ remotehost = ap_get_useragent_host(r, REMOTE_DOUBLE_REV,
+ &remotehost_is_ip);
+
+ if ((remotehost == NULL) || remotehost_is_ip) {
+ gothost = 1;
+ }
+ else {
+ gothost = 2;
+ }
+ }
+
+ if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) {
+ return 1;
+ }
+ break;
+
+ case T_FAIL:
+ /* do nothing? */
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int access_compat_ap_satisfies(request_rec *r)
+{
+ access_compat_dir_conf *conf = (access_compat_dir_conf *)
+ ap_get_module_config(r->per_dir_config, &access_compat_module);
+
+ return conf->satisfy[r->method_number];
+}
+
+static int check_dir_access(request_rec *r)
+{
+ int method = r->method_number;
+ int ret = OK;
+ access_compat_dir_conf *a = (access_compat_dir_conf *)
+ ap_get_module_config(r->per_dir_config, &access_compat_module);
+
+ if (a->order[method] == ALLOW_THEN_DENY) {
+ ret = HTTP_FORBIDDEN;
+ if (find_allowdeny(r, a->allows, method)) {
+ ret = OK;
+ }
+ if (find_allowdeny(r, a->denys, method)) {
+ ret = HTTP_FORBIDDEN;
+ }
+ }
+ else if (a->order[method] == DENY_THEN_ALLOW) {
+ if (find_allowdeny(r, a->denys, method)) {
+ ret = HTTP_FORBIDDEN;
+ }
+ if (find_allowdeny(r, a->allows, method)) {
+ ret = OK;
+ }
+ }
+ else {
+ if (find_allowdeny(r, a->allows, method)
+ && !find_allowdeny(r, a->denys, method)) {
+ ret = OK;
+ }
+ else {
+ ret = HTTP_FORBIDDEN;
+ }
+ }
+
+ if (ret == HTTP_FORBIDDEN) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01797)
+ "client denied by server configuration: %s%s",
+ r->filename ? "" : "uri ",
+ r->filename ? r->filename : r->uri);
+ }
+
+ return ret;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ APR_REGISTER_OPTIONAL_FN(access_compat_ap_satisfies);
+
+ /* This can be access checker since we don't require r->user to be set. */
+ ap_hook_check_access(check_dir_access, NULL, NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(access_compat) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_access_compat_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ access_compat_cmds,
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_access_compat.dep b/modules/aaa/mod_access_compat.dep
new file mode 100644
index 0000000..e3f5e97
--- /dev/null
+++ b/modules/aaa/mod_access_compat.dep
@@ -0,0 +1,59 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_access_compat.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_access_compat.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_access_compat.dsp b/modules/aaa/mod_access_compat.dsp
new file mode 100644
index 0000000..c0cef15
--- /dev/null
+++ b/modules/aaa/mod_access_compat.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_access_compat" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_access_compat - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_access_compat.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_access_compat.mak" CFG="mod_access_compat - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_access_compat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_access_compat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Release\mod_access_compat_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_access_compat.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Debug\mod_access_compat_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_access_compat.so" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_access_compat.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_access_compat - Win32 Release"
+# Name "mod_access_compat - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_access_compat.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_access_compat.mak b/modules/aaa/mod_access_compat.mak
new file mode 100644
index 0000000..4d80704
--- /dev/null
+++ b/modules/aaa/mod_access_compat.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_access_compat.dsp
+!IF "$(CFG)" == ""
+CFG=mod_access_compat - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_access_compat - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_access_compat - Win32 Release" && "$(CFG)" != "mod_access_compat - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_access_compat.mak" CFG="mod_access_compat - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_access_compat - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_access_compat - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_access_compat.obj"
+ -@erase "$(INTDIR)\mod_access_compat.res"
+ -@erase "$(INTDIR)\mod_access_compat_src.idb"
+ -@erase "$(INTDIR)\mod_access_compat_src.pdb"
+ -@erase "$(OUTDIR)\mod_access_compat.exp"
+ -@erase "$(OUTDIR)\mod_access_compat.lib"
+ -@erase "$(OUTDIR)\mod_access_compat.pdb"
+ -@erase "$(OUTDIR)\mod_access_compat.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_access_compat_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_access_compat.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_access_compat.pdb" /debug /out:"$(OUTDIR)\mod_access_compat.so" /implib:"$(OUTDIR)\mod_access_compat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_access_compat.obj" \
+ "$(INTDIR)\mod_access_compat.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_access_compat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_access_compat.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_access_compat.so"
+ if exist .\Release\mod_access_compat.so.manifest mt.exe -manifest .\Release\mod_access_compat.so.manifest -outputresource:.\Release\mod_access_compat.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_access_compat.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_access_compat.obj"
+ -@erase "$(INTDIR)\mod_access_compat.res"
+ -@erase "$(INTDIR)\mod_access_compat_src.idb"
+ -@erase "$(INTDIR)\mod_access_compat_src.pdb"
+ -@erase "$(OUTDIR)\mod_access_compat.exp"
+ -@erase "$(OUTDIR)\mod_access_compat.lib"
+ -@erase "$(OUTDIR)\mod_access_compat.pdb"
+ -@erase "$(OUTDIR)\mod_access_compat.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_access_compat_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_access_compat.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_access_compat.pdb" /debug /out:"$(OUTDIR)\mod_access_compat.so" /implib:"$(OUTDIR)\mod_access_compat.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_access_compat.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_access_compat.obj" \
+ "$(INTDIR)\mod_access_compat.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_access_compat.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_access_compat.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_access_compat.so"
+ if exist .\Debug\mod_access_compat.so.manifest mt.exe -manifest .\Debug\mod_access_compat.so.manifest -outputresource:.\Debug\mod_access_compat.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_access_compat.dep")
+!INCLUDE "mod_access_compat.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_access_compat.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release" || "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_access_compat - Win32 Release"
+
+
+"$(INTDIR)\mod_access_compat.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_access_compat - Win32 Debug"
+
+
+"$(INTDIR)\mod_access_compat.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_access_compat.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_access_compat.so" /d LONG_NAME="access_compat_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_access_compat.c
+
+"$(INTDIR)\mod_access_compat.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_allowmethods.c b/modules/aaa/mod_allowmethods.c
new file mode 100644
index 0000000..dd41196
--- /dev/null
+++ b/modules/aaa/mod_allowmethods.c
@@ -0,0 +1,158 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "httpd.h"
+#include "http_core.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "apr_strings.h"
+
+/**
+ * This module makes it easy to restrict what HTTP methods can be ran against
+ * a server.
+ *
+ * It provides one command:
+ * AllowMethods
+ * This command takes a list of HTTP methods to allow.
+ *
+ * The most common configuration should be like this:
+ * <Directory />
+ * AllowMethods GET HEAD OPTIONS
+ * </Directory>
+ * <Directory /special/cgi-bin>
+ * AllowMethods GET HEAD OPTIONS POST
+ * </Directory>
+ * Non-matching methods will be returned a status 405 (method not allowed)
+ *
+ * To allow all methods, and effectively turn off mod_allowmethods, use:
+ * AllowMethods reset
+ */
+
+typedef struct am_conf_t {
+ int allowed_set;
+ apr_int64_t allowed;
+} am_conf_t;
+
+module AP_MODULE_DECLARE_DATA allowmethods_module;
+
+static int am_check_access(request_rec *r)
+{
+ int method = r->method_number;
+ am_conf_t *conf;
+
+ conf = (am_conf_t *) ap_get_module_config(r->per_dir_config,
+ &allowmethods_module);
+ if (!conf || conf->allowed == 0) {
+ return DECLINED;
+ }
+
+ r->allowed = conf->allowed;
+
+ if (conf->allowed & (AP_METHOD_BIT << method)) {
+ return DECLINED;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01623)
+ "client method denied by server configuration: '%s' to %s%s",
+ r->method,
+ r->filename ? "" : "uri ",
+ r->filename ? r->filename : r->uri);
+
+ return HTTP_METHOD_NOT_ALLOWED;
+}
+
+static void *am_create_conf(apr_pool_t *p, char *dummy)
+{
+ am_conf_t *conf = apr_pcalloc(p, sizeof(am_conf_t));
+
+ conf->allowed = 0;
+ conf->allowed_set = 0;
+ return conf;
+}
+
+static void *am_merge_conf(apr_pool_t *pool, void *a, void *b)
+{
+ am_conf_t *base = (am_conf_t *)a;
+ am_conf_t *add = (am_conf_t *)b;
+ am_conf_t *conf = apr_palloc(pool, sizeof(am_conf_t));
+
+ if (add->allowed_set) {
+ conf->allowed = add->allowed;
+ conf->allowed_set = add->allowed_set;
+ }
+ else {
+ conf->allowed = base->allowed;
+ conf->allowed_set = base->allowed_set;
+ }
+
+ return conf;
+}
+
+static const char *am_allowmethods(cmd_parms *cmd, void *d, int argc,
+ char *const argv[])
+{
+ int i;
+ am_conf_t *conf = (am_conf_t *)d;
+
+ if (argc == 0) {
+ return "AllowMethods: No method or 'reset' keyword given";
+ }
+ if (argc == 1) {
+ if (strcasecmp("reset", argv[0]) == 0) {
+ conf->allowed = 0;
+ conf->allowed_set = 1;
+ return NULL;
+ }
+ }
+
+ for (i = 0; i < argc; i++) {
+ int m;
+
+ m = ap_method_number_of(argv[i]);
+ if (m == M_INVALID) {
+ return apr_pstrcat(cmd->pool, "AllowMethods: Invalid Method '",
+ argv[i], "'", NULL);
+ }
+
+ conf->allowed |= (AP_METHOD_BIT << m);
+ }
+ conf->allowed_set = 1;
+ return NULL;
+}
+
+static void am_register_hooks(apr_pool_t * p)
+{
+ ap_hook_access_checker(am_check_access, NULL, NULL, APR_HOOK_REALLY_FIRST);
+}
+
+static const command_rec am_cmds[] = {
+ AP_INIT_TAKE_ARGV("AllowMethods", am_allowmethods, NULL,
+ ACCESS_CONF,
+ "only allow specific methods"),
+ {NULL}
+};
+
+AP_DECLARE_MODULE(allowmethods) = {
+ STANDARD20_MODULE_STUFF,
+ am_create_conf,
+ am_merge_conf,
+ NULL,
+ NULL,
+ am_cmds,
+ am_register_hooks,
+};
diff --git a/modules/aaa/mod_allowmethods.dep b/modules/aaa/mod_allowmethods.dep
new file mode 100644
index 0000000..04db445
--- /dev/null
+++ b/modules/aaa/mod_allowmethods.dep
@@ -0,0 +1,56 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_allowmethods.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_allowmethods.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_allowmethods.dsp b/modules/aaa/mod_allowmethods.dsp
new file mode 100644
index 0000000..446f8dc
--- /dev/null
+++ b/modules/aaa/mod_allowmethods.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_allowmethods" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_allowmethods - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_allowmethods.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_allowmethods.mak" CFG="mod_allowmethods - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_allowmethods - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_allowmethods - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_allowmethods_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_allowmethods.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_allowmethods_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_allowmethods.so" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_allowmethods.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_allowmethods - Win32 Release"
+# Name "mod_allowmethods - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_allowmethods.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_allowmethods.mak b/modules/aaa/mod_allowmethods.mak
new file mode 100644
index 0000000..1049515
--- /dev/null
+++ b/modules/aaa/mod_allowmethods.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_allowmethods.dsp
+!IF "$(CFG)" == ""
+CFG=mod_allowmethods - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_allowmethods - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_allowmethods - Win32 Release" && "$(CFG)" != "mod_allowmethods - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_allowmethods.mak" CFG="mod_allowmethods - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_allowmethods - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_allowmethods - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_allowmethods.obj"
+ -@erase "$(INTDIR)\mod_allowmethods.res"
+ -@erase "$(INTDIR)\mod_allowmethods_src.idb"
+ -@erase "$(INTDIR)\mod_allowmethods_src.pdb"
+ -@erase "$(OUTDIR)\mod_allowmethods.exp"
+ -@erase "$(OUTDIR)\mod_allowmethods.lib"
+ -@erase "$(OUTDIR)\mod_allowmethods.pdb"
+ -@erase "$(OUTDIR)\mod_allowmethods.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_allowmethods_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_allowmethods.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_allowmethods.pdb" /debug /out:"$(OUTDIR)\mod_allowmethods.so" /implib:"$(OUTDIR)\mod_allowmethods.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_allowmethods.obj" \
+ "$(INTDIR)\mod_allowmethods.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_allowmethods.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_allowmethods.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_allowmethods.so"
+ if exist .\Release\mod_allowmethods.so.manifest mt.exe -manifest .\Release\mod_allowmethods.so.manifest -outputresource:.\Release\mod_allowmethods.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_allowmethods.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_allowmethods.obj"
+ -@erase "$(INTDIR)\mod_allowmethods.res"
+ -@erase "$(INTDIR)\mod_allowmethods_src.idb"
+ -@erase "$(INTDIR)\mod_allowmethods_src.pdb"
+ -@erase "$(OUTDIR)\mod_allowmethods.exp"
+ -@erase "$(OUTDIR)\mod_allowmethods.lib"
+ -@erase "$(OUTDIR)\mod_allowmethods.pdb"
+ -@erase "$(OUTDIR)\mod_allowmethods.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_allowmethods_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_allowmethods.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_allowmethods.pdb" /debug /out:"$(OUTDIR)\mod_allowmethods.so" /implib:"$(OUTDIR)\mod_allowmethods.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_allowmethods.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_allowmethods.obj" \
+ "$(INTDIR)\mod_allowmethods.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_allowmethods.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_allowmethods.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_allowmethods.so"
+ if exist .\Debug\mod_allowmethods.so.manifest mt.exe -manifest .\Debug\mod_allowmethods.so.manifest -outputresource:.\Debug\mod_allowmethods.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_allowmethods.dep")
+!INCLUDE "mod_allowmethods.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_allowmethods.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release" || "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_allowmethods - Win32 Release"
+
+
+"$(INTDIR)\mod_allowmethods.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_allowmethods - Win32 Debug"
+
+
+"$(INTDIR)\mod_allowmethods.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_allowmethods.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_allowmethods.so" /d LONG_NAME="allowmethods_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_allowmethods.c
+
+"$(INTDIR)\mod_allowmethods.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_auth_basic.c b/modules/aaa/mod_auth_basic.c
new file mode 100644
index 0000000..e8163d0
--- /dev/null
+++ b/modules/aaa/mod_auth_basic.c
@@ -0,0 +1,508 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_lib.h" /* for apr_isspace */
+#include "apr_base64.h" /* for apr_base64_decode et al */
+#define APR_WANT_STRFUNC /* for strcasecmp */
+#include "apr_want.h"
+
+#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_md5.h"
+#include "ap_provider.h"
+#include "ap_expr.h"
+
+#include "mod_auth.h"
+
+typedef struct {
+ authn_provider_list *providers;
+ char *dir; /* unused variable */
+ int authoritative;
+ ap_expr_info_t *fakeuser;
+ ap_expr_info_t *fakepass;
+ const char *use_digest_algorithm;
+ int fake_set:1;
+ int use_digest_algorithm_set:1;
+ int authoritative_set:1;
+} auth_basic_config_rec;
+
+static void *create_auth_basic_dir_config(apr_pool_t *p, char *d)
+{
+ auth_basic_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
+
+ /* Any failures are fatal. */
+ conf->authoritative = 1;
+
+ return conf;
+}
+
+static void *merge_auth_basic_dir_config(apr_pool_t *p, void *basev, void *overridesv)
+{
+ auth_basic_config_rec *newconf = apr_pcalloc(p, sizeof(*newconf));
+ auth_basic_config_rec *base = basev;
+ auth_basic_config_rec *overrides = overridesv;
+
+ newconf->authoritative =
+ overrides->authoritative_set ? overrides->authoritative :
+ base->authoritative;
+ newconf->authoritative_set = overrides->authoritative_set
+ || base->authoritative_set;
+
+ newconf->fakeuser =
+ overrides->fake_set ? overrides->fakeuser : base->fakeuser;
+ newconf->fakepass =
+ overrides->fake_set ? overrides->fakepass : base->fakepass;
+ newconf->fake_set = overrides->fake_set || base->fake_set;
+
+ newconf->use_digest_algorithm =
+ overrides->use_digest_algorithm_set ? overrides->use_digest_algorithm
+ : base->use_digest_algorithm;
+ newconf->use_digest_algorithm_set =
+ overrides->use_digest_algorithm_set || base->use_digest_algorithm_set;
+
+ newconf->providers = overrides->providers ? overrides->providers : base->providers;
+
+ return newconf;
+}
+
+static const char *add_authn_provider(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec*)config;
+ authn_provider_list *newp;
+
+ newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
+ newp->provider_name = arg;
+
+ /* lookup and cache the actual provider now */
+ newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ newp->provider_name,
+ AUTHN_PROVIDER_VERSION);
+
+ if (newp->provider == NULL) {
+ /* by the time they use it, the provider should be loaded and
+ registered with us. */
+ return apr_psprintf(cmd->pool,
+ "Unknown Authn provider: %s",
+ newp->provider_name);
+ }
+
+ if (!newp->provider->check_password) {
+ /* if it doesn't provide the appropriate function, reject it */
+ return apr_psprintf(cmd->pool,
+ "The '%s' Authn provider doesn't support "
+ "Basic Authentication", newp->provider_name);
+ }
+
+ /* Add it to the list now. */
+ if (!conf->providers) {
+ conf->providers = newp;
+ }
+ else {
+ authn_provider_list *last = conf->providers;
+
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = newp;
+ }
+
+ return NULL;
+}
+
+static const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+
+ conf->authoritative = flag;
+ conf->authoritative_set = 1;
+
+ return NULL;
+}
+
+static const char *add_basic_fake(cmd_parms * cmd, void *config,
+ const char *user, const char *pass)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec *) config;
+ const char *err;
+
+ if (!strcasecmp(user, "off")) {
+ conf->fakeuser = NULL;
+ conf->fakepass = NULL;
+ conf->fake_set = 1;
+ }
+ else {
+ /* if password is unspecified, set it to the fixed string "password" to
+ * be compatible with the behaviour of mod_ssl.
+ */
+ if (!pass) {
+ pass = "password";
+ }
+
+ conf->fakeuser =
+ ap_expr_parse_cmd(cmd, user, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse fake username expression '%s': %s", user,
+ err);
+ }
+ conf->fakepass =
+ ap_expr_parse_cmd(cmd, pass, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse fake password expression associated to user '%s': %s",
+ user, err);
+ }
+ conf->fake_set = 1;
+ }
+
+ return NULL;
+}
+
+static const char *set_use_digest_algorithm(cmd_parms *cmd, void *config,
+ const char *alg)
+{
+ auth_basic_config_rec *conf = (auth_basic_config_rec *)config;
+
+ if (strcasecmp(alg, "Off") && strcasecmp(alg, "MD5")) {
+ return apr_pstrcat(cmd->pool,
+ "Invalid algorithm in "
+ "AuthBasicUseDigestAlgorithm: ", alg, NULL);
+ }
+
+ conf->use_digest_algorithm = alg;
+ conf->use_digest_algorithm_set = 1;
+
+ return NULL;
+}
+
+static const command_rec auth_basic_cmds[] =
+{
+ AP_INIT_ITERATE("AuthBasicProvider", add_authn_provider, NULL, OR_AUTHCFG,
+ "specify the auth providers for a directory or location"),
+ AP_INIT_FLAG("AuthBasicAuthoritative", set_authoritative, NULL, OR_AUTHCFG,
+ "Set to 'Off' to allow access control to be passed along to "
+ "lower modules if the UserID is not known to this module"),
+ AP_INIT_TAKE12("AuthBasicFake", add_basic_fake, NULL, OR_AUTHCFG,
+ "Fake basic authentication using the given expressions for "
+ "username and password, 'off' to disable. Password defaults "
+ "to 'password' if missing."),
+ AP_INIT_TAKE1("AuthBasicUseDigestAlgorithm", set_use_digest_algorithm,
+ NULL, OR_AUTHCFG,
+ "Set to 'MD5' to use the auth provider's authentication "
+ "check for digest auth, using a hash of 'user:realm:pass'"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA auth_basic_module;
+
+/* These functions return 0 if client is OK, and proper error status
+ * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
+ * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
+ * couldn't figure out how to tell if the client is authorized or not.
+ *
+ * If they return DECLINED, and all other modules also decline, that's
+ * treated by the server core as a configuration error, logged and
+ * reported as such.
+ */
+
+static void note_basic_auth_failure(request_rec *r)
+{
+ apr_table_setn(r->err_headers_out,
+ (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authenticate"
+ : "WWW-Authenticate",
+ apr_pstrcat(r->pool, "Basic realm=\"", ap_auth_name(r),
+ "\"", NULL));
+}
+
+static int hook_note_basic_auth_failure(request_rec *r, const char *auth_type)
+{
+ if (strcasecmp(auth_type, "Basic"))
+ return DECLINED;
+
+ note_basic_auth_failure(r);
+ return OK;
+}
+
+static int get_basic_auth(request_rec *r, const char **user,
+ const char **pw)
+{
+ const char *auth_line;
+ char *decoded_line;
+
+ /* Get the appropriate header */
+ auth_line = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq)
+ ? "Proxy-Authorization"
+ : "Authorization");
+
+ if (!auth_line) {
+ note_basic_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ if (strcasecmp(ap_getword(r->pool, &auth_line, ' '), "Basic")) {
+ /* Client tried to authenticate using wrong auth scheme */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01614)
+ "client used wrong authentication scheme: %s", r->uri);
+ note_basic_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ /* Skip leading spaces. */
+ while (*auth_line == ' ' || *auth_line == '\t') {
+ auth_line++;
+ }
+
+ decoded_line = ap_pbase64decode(r->pool, auth_line);
+
+ *user = ap_getword_nulls(r->pool, (const char**)&decoded_line, ':');
+ *pw = decoded_line;
+
+ /* set the user, even though the user is unauthenticated at this point */
+ r->user = (char *) *user;
+
+ return OK;
+}
+
+/* Determine user ID, and check if it really is that user, for HTTP
+ * basic authentication...
+ */
+static int authenticate_basic_user(request_rec *r)
+{
+ auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_basic_module);
+ const char *sent_user, *sent_pw, *current_auth;
+ const char *realm = NULL;
+ const char *digest = NULL;
+ int res;
+ authn_status auth_result;
+ authn_provider_list *current_provider;
+
+ /* Are we configured to be Basic auth? */
+ current_auth = ap_auth_type(r);
+ if (!current_auth || strcasecmp(current_auth, "Basic")) {
+ return DECLINED;
+ }
+
+ /* We need an authentication realm. */
+ if (!ap_auth_name(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01615)
+ "need AuthName: %s", r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ r->ap_auth_type = (char*)current_auth;
+
+ res = get_basic_auth(r, &sent_user, &sent_pw);
+ if (res) {
+ return res;
+ }
+
+ if (conf->use_digest_algorithm
+ && !strcasecmp(conf->use_digest_algorithm, "MD5")) {
+ realm = ap_auth_name(r);
+ digest = ap_md5(r->pool,
+ (unsigned char *)apr_pstrcat(r->pool, sent_user, ":",
+ realm, ":",
+ sent_pw, NULL));
+ }
+
+ current_provider = conf->providers;
+ do {
+ const authn_provider *provider;
+
+ /* For now, if a provider isn't set, we'll be nice and use the file
+ * provider.
+ */
+ if (!current_provider) {
+ provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ AUTHN_DEFAULT_PROVIDER,
+ AUTHN_PROVIDER_VERSION);
+
+ if (!provider || !provider->check_password) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01616)
+ "No Authn provider configured");
+ auth_result = AUTH_GENERAL_ERROR;
+ break;
+ }
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, AUTHN_DEFAULT_PROVIDER);
+ }
+ else {
+ provider = current_provider->provider;
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, current_provider->provider_name);
+ }
+
+ if (digest) {
+ char *password;
+
+ if (!provider->get_realm_hash) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02493)
+ "Authn provider does not support "
+ "AuthBasicUseDigestAlgorithm");
+ auth_result = AUTH_GENERAL_ERROR;
+ break;
+ }
+ /* We expect the password to be hash of user:realm:password */
+ auth_result = provider->get_realm_hash(r, sent_user, realm,
+ &password);
+ if (auth_result == AUTH_USER_FOUND) {
+ auth_result = strcmp(digest, password) ? AUTH_DENIED
+ : AUTH_GRANTED;
+ }
+ }
+ else {
+ auth_result = provider->check_password(r, sent_user, sent_pw);
+ }
+
+ apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+
+ /* Something occurred. Stop checking. */
+ if (auth_result != AUTH_USER_NOT_FOUND) {
+ break;
+ }
+
+ /* If we're not really configured for providers, stop now. */
+ if (!conf->providers) {
+ break;
+ }
+
+ current_provider = current_provider->next;
+ } while (current_provider);
+
+ if (auth_result != AUTH_GRANTED) {
+ int return_code;
+
+ /* If we're not authoritative, then any error is ignored. */
+ if (!(conf->authoritative) && auth_result != AUTH_DENIED) {
+ return DECLINED;
+ }
+
+ switch (auth_result) {
+ case AUTH_DENIED:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01617)
+ "user %s: authentication failure for \"%s\": "
+ "Password Mismatch",
+ sent_user, r->uri);
+ return_code = HTTP_UNAUTHORIZED;
+ break;
+ case AUTH_USER_NOT_FOUND:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01618)
+ "user %s not found: %s", sent_user, r->uri);
+ return_code = HTTP_UNAUTHORIZED;
+ break;
+ case AUTH_GENERAL_ERROR:
+ default:
+ /* We'll assume that the module has already said what its error
+ * was in the logs.
+ */
+ return_code = HTTP_INTERNAL_SERVER_ERROR;
+ break;
+ }
+
+ /* If we're returning 401, tell them to try again. */
+ if (return_code == HTTP_UNAUTHORIZED) {
+ note_basic_auth_failure(r);
+ }
+ return return_code;
+ }
+
+ return OK;
+}
+
+/* If requested, create a fake basic authentication header for the benefit
+ * of a proxy or application running behind this server.
+ */
+static int authenticate_basic_fake(request_rec *r)
+{
+ const char *auth_line, *user, *pass, *err;
+ auth_basic_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_basic_module);
+
+ if (!conf->fakeuser) {
+ return DECLINED;
+ }
+
+ user = ap_expr_str_exec(r, conf->fakeuser, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02455)
+ "AuthBasicFake: could not evaluate user expression for URI '%s': %s", r->uri, err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if (!user || !*user) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02458)
+ "AuthBasicFake: empty username expression for URI '%s', ignoring", r->uri);
+
+ apr_table_unset(r->headers_in, "Authorization");
+
+ return DECLINED;
+ }
+
+ pass = ap_expr_str_exec(r, conf->fakepass, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02456)
+ "AuthBasicFake: could not evaluate password expression for URI '%s': %s", r->uri, err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if (!pass || !*pass) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02459)
+ "AuthBasicFake: empty password expression for URI '%s', ignoring", r->uri);
+
+ apr_table_unset(r->headers_in, "Authorization");
+
+ return DECLINED;
+ }
+
+ auth_line = apr_pstrcat(r->pool, "Basic ",
+ ap_pbase64encode(r->pool,
+ apr_pstrcat(r->pool, user,
+ ":", pass, NULL)),
+ NULL);
+ apr_table_setn(r->headers_in, "Authorization", auth_line);
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02457)
+ "AuthBasicFake: \"Authorization: %s\"",
+ auth_line);
+
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_hook_check_authn(authenticate_basic_user, NULL, NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_fixups(authenticate_basic_fake, NULL, NULL, APR_HOOK_LAST);
+ ap_hook_note_auth_failure(hook_note_basic_auth_failure, NULL, NULL,
+ APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(auth_basic) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_auth_basic_dir_config, /* dir config creater */
+ merge_auth_basic_dir_config, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ auth_basic_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_auth_basic.dep b/modules/aaa/mod_auth_basic.dep
new file mode 100644
index 0000000..6c1291c
--- /dev/null
+++ b/modules/aaa/mod_auth_basic.dep
@@ -0,0 +1,63 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_auth_basic.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_auth_basic.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_md5.h"\
+ "..\..\srclib\apr-util\include\apr_base64.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_auth_basic.dsp b/modules/aaa/mod_auth_basic.dsp
new file mode 100644
index 0000000..b45264e
--- /dev/null
+++ b/modules/aaa/mod_auth_basic.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_auth_basic" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_auth_basic - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_basic.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_basic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_basic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Release\mod_auth_basic_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_auth_basic.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Debug\mod_auth_basic_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_basic.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_auth_basic.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_auth_basic - Win32 Release"
+# Name "mod_auth_basic - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_auth_basic.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_auth_basic.mak b/modules/aaa/mod_auth_basic.mak
new file mode 100644
index 0000000..ddd5198
--- /dev/null
+++ b/modules/aaa/mod_auth_basic.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_basic.dsp
+!IF "$(CFG)" == ""
+CFG=mod_auth_basic - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_auth_basic - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_auth_basic - Win32 Release" && "$(CFG)" != "mod_auth_basic - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_basic - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_basic - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_basic.obj"
+ -@erase "$(INTDIR)\mod_auth_basic.res"
+ -@erase "$(INTDIR)\mod_auth_basic_src.idb"
+ -@erase "$(INTDIR)\mod_auth_basic_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_basic.exp"
+ -@erase "$(OUTDIR)\mod_auth_basic.lib"
+ -@erase "$(OUTDIR)\mod_auth_basic.pdb"
+ -@erase "$(OUTDIR)\mod_auth_basic.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_basic_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_basic.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_basic.pdb" /debug /out:"$(OUTDIR)\mod_auth_basic.so" /implib:"$(OUTDIR)\mod_auth_basic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_basic.obj" \
+ "$(INTDIR)\mod_auth_basic.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_basic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_auth_basic.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_basic.so"
+ if exist .\Release\mod_auth_basic.so.manifest mt.exe -manifest .\Release\mod_auth_basic.so.manifest -outputresource:.\Release\mod_auth_basic.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_basic.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_basic.obj"
+ -@erase "$(INTDIR)\mod_auth_basic.res"
+ -@erase "$(INTDIR)\mod_auth_basic_src.idb"
+ -@erase "$(INTDIR)\mod_auth_basic_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_basic.exp"
+ -@erase "$(OUTDIR)\mod_auth_basic.lib"
+ -@erase "$(OUTDIR)\mod_auth_basic.pdb"
+ -@erase "$(OUTDIR)\mod_auth_basic.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_basic_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_basic.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_basic.pdb" /debug /out:"$(OUTDIR)\mod_auth_basic.so" /implib:"$(OUTDIR)\mod_auth_basic.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_basic.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_basic.obj" \
+ "$(INTDIR)\mod_auth_basic.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_basic.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_auth_basic.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_basic.so"
+ if exist .\Debug\mod_auth_basic.so.manifest mt.exe -manifest .\Debug\mod_auth_basic.so.manifest -outputresource:.\Debug\mod_auth_basic.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_auth_basic.dep")
+!INCLUDE "mod_auth_basic.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_auth_basic.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release" || "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_auth_basic - Win32 Release"
+
+
+"$(INTDIR)\mod_auth_basic.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_auth_basic - Win32 Debug"
+
+
+"$(INTDIR)\mod_auth_basic.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_basic.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_basic.so" /d LONG_NAME="auth_basic_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_auth_basic.c
+
+"$(INTDIR)\mod_auth_basic.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c
new file mode 100644
index 0000000..a67f069
--- /dev/null
+++ b/modules/aaa/mod_auth_digest.c
@@ -0,0 +1,1976 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * mod_auth_digest: MD5 digest authentication
+ *
+ * Originally by Alexei Kosut <akosut@nueva.pvt.k12.ca.us>
+ * Updated to RFC-2617 by Ronald Tschal�r <ronald@innovation.ch>
+ * based on mod_auth, by Rob McCool and Robert S. Thau
+ *
+ * This module an updated version of modules/standard/mod_digest.c
+ * It is still fairly new and problems may turn up - submit problem
+ * reports to the Apache bug-database, or send them directly to me
+ * at ronald@innovation.ch.
+ *
+ * Open Issues:
+ * - qop=auth-int (when streams and trailer support available)
+ * - nonce-format configurability
+ * - Proxy-Authorization-Info header is set by this module, but is
+ * currently ignored by mod_proxy (needs patch to mod_proxy)
+ * - The source of the secret should be run-time directive (with server
+ * scope: RSRC_CONF)
+ * - shared-mem not completely tested yet. Seems to work ok for me,
+ * but... (definitely won't work on Windoze)
+ * - Sharing a realm among multiple servers has following problems:
+ * o Server name and port can't be included in nonce-hash
+ * (we need two nonce formats, which must be configured explicitly)
+ * o Nonce-count check can't be for equal, or then nonce-count checking
+ * must be disabled. What we could do is the following:
+ * (expected < received) ? set expected = received : issue error
+ * The only problem is that it allows replay attacks when somebody
+ * captures a packet sent to one server and sends it to another
+ * one. Should we add "AuthDigestNcCheck Strict"?
+ * - expired nonces give amaya fits.
+ * - MD5-sess and auth-int are not yet implemented. An incomplete
+ * implementation has been removed and can be retrieved from svn history.
+ */
+
+#include "apr_sha1.h"
+#include "apr_base64.h"
+#include "apr_lib.h"
+#include "apr_time.h"
+#include "apr_errno.h"
+#include "apr_global_mutex.h"
+#include "apr_strings.h"
+
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "apr_uri.h"
+#include "util_md5.h"
+#include "util_mutex.h"
+#include "apr_shm.h"
+#include "apr_rmm.h"
+#include "ap_provider.h"
+
+#include "mod_auth.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* struct to hold the configuration info */
+
+typedef struct digest_config_struct {
+ const char *dir_name;
+ authn_provider_list *providers;
+ const char *realm;
+ apr_array_header_t *qop_list;
+ apr_sha1_ctx_t nonce_ctx;
+ apr_time_t nonce_lifetime;
+ int check_nc;
+ const char *algorithm;
+ char *uri_list;
+ const char *ha1;
+} digest_config_rec;
+
+
+#define DFLT_ALGORITHM "MD5"
+
+#define DFLT_NONCE_LIFE apr_time_from_sec(300)
+#define NEXTNONCE_DELTA apr_time_from_sec(30)
+
+
+#define NONCE_TIME_LEN (((sizeof(apr_time_t)+2)/3)*4)
+#define NONCE_HASH_LEN (2*APR_SHA1_DIGESTSIZE)
+#define NONCE_LEN (int )(NONCE_TIME_LEN + NONCE_HASH_LEN)
+
+#define SECRET_LEN 20
+#define RETAINED_DATA_ID "mod_auth_digest"
+
+
+/* client list definitions */
+
+typedef struct hash_entry {
+ unsigned long key; /* the key for this entry */
+ struct hash_entry *next; /* next entry in the bucket */
+ unsigned long nonce_count; /* for nonce-count checking */
+ char last_nonce[NONCE_LEN+1]; /* for one-time nonce's */
+} client_entry;
+
+static struct hash_table {
+ client_entry **table;
+ unsigned long tbl_len;
+ unsigned long num_entries;
+ unsigned long num_created;
+ unsigned long num_removed;
+ unsigned long num_renewed;
+} *client_list;
+
+
+/* struct to hold a parsed Authorization header */
+
+enum hdr_sts { NO_HEADER, NOT_DIGEST, INVALID, VALID };
+
+typedef struct digest_header_struct {
+ const char *scheme;
+ const char *realm;
+ const char *username;
+ char *nonce;
+ const char *uri;
+ const char *method;
+ const char *digest;
+ const char *algorithm;
+ const char *cnonce;
+ const char *opaque;
+ unsigned long opaque_num;
+ const char *message_qop;
+ const char *nonce_count;
+ /* the following fields are not (directly) from the header */
+ const char *raw_request_uri;
+ apr_uri_t *psd_request_uri;
+ apr_time_t nonce_time;
+ enum hdr_sts auth_hdr_sts;
+ int needed_auth;
+ client_entry *client;
+} digest_header_rec;
+
+
+/* (mostly) nonce stuff */
+
+typedef union time_union {
+ apr_time_t time;
+ unsigned char arr[sizeof(apr_time_t)];
+} time_rec;
+
+static unsigned char *secret;
+
+/* client-list, opaque, and one-time-nonce stuff */
+
+static apr_shm_t *client_shm = NULL;
+static apr_rmm_t *client_rmm = NULL;
+static unsigned long *opaque_cntr;
+static apr_time_t *otn_counter; /* one-time-nonce counter */
+static apr_global_mutex_t *client_lock = NULL;
+static apr_global_mutex_t *opaque_lock = NULL;
+static const char *client_mutex_type = "authdigest-client";
+static const char *opaque_mutex_type = "authdigest-opaque";
+static const char *client_shm_filename;
+
+#define DEF_SHMEM_SIZE 1000L /* ~ 12 entries */
+#define DEF_NUM_BUCKETS 15L
+#define HASH_DEPTH 5
+
+static apr_size_t shmem_size = DEF_SHMEM_SIZE;
+static unsigned long num_buckets = DEF_NUM_BUCKETS;
+
+
+module AP_MODULE_DECLARE_DATA auth_digest_module;
+
+/*
+ * initialization code
+ */
+
+static apr_status_t cleanup_tables(void *not_used)
+{
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(01756)
+ "cleaning up shared memory");
+
+ if (client_rmm) {
+ apr_rmm_destroy(client_rmm);
+ client_rmm = NULL;
+ }
+
+ if (client_shm) {
+ apr_shm_destroy(client_shm);
+ client_shm = NULL;
+ }
+
+ if (client_lock) {
+ apr_global_mutex_destroy(client_lock);
+ client_lock = NULL;
+ }
+
+ if (opaque_lock) {
+ apr_global_mutex_destroy(opaque_lock);
+ opaque_lock = NULL;
+ }
+
+ client_list = NULL;
+
+ return APR_SUCCESS;
+}
+
+static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s)
+{
+ ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01760)
+ "%s - all nonce-count checking and one-time nonces "
+ "disabled", msg);
+
+ cleanup_tables(NULL);
+}
+
+/* RMM helper functions that behave like single-step malloc/free. */
+
+static void *rmm_malloc(apr_rmm_t *rmm, apr_size_t size)
+{
+ apr_rmm_off_t offset = apr_rmm_malloc(rmm, size);
+
+ if (!offset) {
+ return NULL;
+ }
+
+ return apr_rmm_addr_get(rmm, offset);
+}
+
+static apr_status_t rmm_free(apr_rmm_t *rmm, void *alloc)
+{
+ apr_rmm_off_t offset = apr_rmm_offset_get(rmm, alloc);
+
+ return apr_rmm_free(rmm, offset);
+}
+
+#if APR_HAS_SHARED_MEMORY
+
+static int initialize_tables(server_rec *s, apr_pool_t *ctx)
+{
+ unsigned long idx;
+ apr_status_t sts;
+
+ /* set up client list */
+
+ /* Create the shared memory segment */
+
+ /*
+ * Create a unique filename using our pid. This information is
+ * stashed in the global variable so the children inherit it.
+ */
+ client_shm_filename = ap_runtime_dir_relative(ctx, "authdigest_shm");
+ client_shm_filename = ap_append_pid(ctx, client_shm_filename, ".");
+
+ /* Use anonymous shm by default, fall back on name-based. */
+ sts = apr_shm_create(&client_shm, shmem_size, NULL, ctx);
+ if (APR_STATUS_IS_ENOTIMPL(sts)) {
+ /* For a name-based segment, remove it first in case of a
+ * previous unclean shutdown. */
+ apr_shm_remove(client_shm_filename, ctx);
+
+ /* Now create that segment */
+ sts = apr_shm_create(&client_shm, shmem_size,
+ client_shm_filename, ctx);
+ }
+
+ if (APR_SUCCESS != sts) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, sts, s, APLOGNO(01762)
+ "Failed to create shared memory segment on file %s",
+ client_shm_filename);
+ log_error_and_cleanup("failed to initialize shm", sts, s);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ sts = apr_rmm_init(&client_rmm,
+ NULL, /* no lock, we'll do the locking ourselves */
+ apr_shm_baseaddr_get(client_shm),
+ shmem_size, ctx);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to initialize rmm", sts, s);
+ return !OK;
+ }
+
+ client_list = rmm_malloc(client_rmm, sizeof(*client_list) +
+ sizeof(client_entry *) * num_buckets);
+ if (!client_list) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+ }
+ client_list->table = (client_entry**) (client_list + 1);
+ for (idx = 0; idx < num_buckets; idx++) {
+ client_list->table[idx] = NULL;
+ }
+ client_list->tbl_len = num_buckets;
+ client_list->num_entries = 0;
+
+ sts = ap_global_mutex_create(&client_lock, NULL, client_mutex_type, NULL,
+ s, ctx, 0);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to create lock (client_lock)", sts, s);
+ return !OK;
+ }
+
+
+ /* setup opaque */
+
+ opaque_cntr = rmm_malloc(client_rmm, sizeof(*opaque_cntr));
+ if (opaque_cntr == NULL) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+ }
+ *opaque_cntr = 1UL;
+
+ sts = ap_global_mutex_create(&opaque_lock, NULL, opaque_mutex_type, NULL,
+ s, ctx, 0);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s);
+ return !OK;
+ }
+
+
+ /* setup one-time-nonce counter */
+
+ otn_counter = rmm_malloc(client_rmm, sizeof(*otn_counter));
+ if (otn_counter == NULL) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+ }
+ *otn_counter = 0;
+ /* no lock here */
+
+
+ /* success */
+ return OK;
+}
+
+#endif /* APR_HAS_SHARED_MEMORY */
+
+static int pre_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
+{
+ apr_status_t rv;
+ void *retained;
+
+ rv = ap_mutex_register(pconf, client_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
+ if (rv != APR_SUCCESS)
+ return !OK;
+ rv = ap_mutex_register(pconf, opaque_mutex_type, NULL, APR_LOCK_DEFAULT, 0);
+ if (rv != APR_SUCCESS)
+ return !OK;
+
+ retained = ap_retained_data_get(RETAINED_DATA_ID);
+ if (retained == NULL) {
+ retained = ap_retained_data_create(RETAINED_DATA_ID, SECRET_LEN);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(01757)
+ "generating secret for digest authentication");
+#if APR_HAS_RANDOM
+ rv = apr_generate_random_bytes(retained, SECRET_LEN);
+#else
+#error APR random number support is missing
+#endif
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(01758)
+ "error generating secret");
+ return !OK;
+ }
+ }
+ secret = retained;
+ return OK;
+}
+
+static int initialize_module(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ /* initialize_module() will be called twice, and if it's a DSO
+ * then all static data from the first call will be lost. Only
+ * set up our static data on the second call. */
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
+ return OK;
+
+#if APR_HAS_SHARED_MEMORY
+ /* Note: this stuff is currently fixed for the lifetime of the server,
+ * i.e. even across restarts. This means that A) any shmem-size
+ * configuration changes are ignored, and B) certain optimizations,
+ * such as only allocating the smallest necessary entry for each
+ * client, can't be done. However, the alternative is a nightmare:
+ * we can't call apr_shm_destroy on a graceful restart because there
+ * will be children using the tables, and we also don't know when the
+ * last child dies. Therefore we can never clean up the old stuff,
+ * creating a creeping memory leak.
+ */
+ if (initialize_tables(s, p) != OK) {
+ return !OK;
+ }
+ /* Call cleanup_tables on exit or restart */
+ apr_pool_cleanup_register(p, NULL, cleanup_tables, apr_pool_cleanup_null);
+#endif /* APR_HAS_SHARED_MEMORY */
+ return OK;
+}
+
+static void initialize_child(apr_pool_t *p, server_rec *s)
+{
+ apr_status_t sts;
+
+ if (!client_shm) {
+ return;
+ }
+
+ /* Get access to rmm in child */
+ sts = apr_rmm_attach(&client_rmm,
+ NULL,
+ apr_shm_baseaddr_get(client_shm),
+ p);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to attach to rmm", sts, s);
+ return;
+ }
+
+ sts = apr_global_mutex_child_init(&client_lock,
+ apr_global_mutex_lockfile(client_lock),
+ p);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to create lock (client_lock)", sts, s);
+ return;
+ }
+ sts = apr_global_mutex_child_init(&opaque_lock,
+ apr_global_mutex_lockfile(opaque_lock),
+ p);
+ if (sts != APR_SUCCESS) {
+ log_error_and_cleanup("failed to create lock (opaque_lock)", sts, s);
+ return;
+ }
+}
+
+/*
+ * configuration code
+ */
+
+static void *create_digest_dir_config(apr_pool_t *p, char *dir)
+{
+ digest_config_rec *conf;
+
+ if (dir == NULL) {
+ return NULL;
+ }
+
+ conf = (digest_config_rec *) apr_pcalloc(p, sizeof(digest_config_rec));
+ if (conf) {
+ conf->qop_list = apr_array_make(p, 2, sizeof(char *));
+ conf->nonce_lifetime = DFLT_NONCE_LIFE;
+ conf->dir_name = apr_pstrdup(p, dir);
+ conf->algorithm = DFLT_ALGORITHM;
+ }
+
+ return conf;
+}
+
+static const char *set_realm(cmd_parms *cmd, void *config, const char *realm)
+{
+ digest_config_rec *conf = (digest_config_rec *) config;
+#ifdef AP_DEBUG
+ int i;
+
+ /* check that we got random numbers */
+ for (i = 0; i < SECRET_LEN; i++) {
+ if (secret[i] != 0)
+ break;
+ }
+ ap_assert(i < SECRET_LEN);
+#endif
+
+ /* The core already handles the realm, but it's just too convenient to
+ * grab it ourselves too and cache some setups. However, we need to
+ * let the core get at it too, which is why we decline at the end -
+ * this relies on the fact that http_core is last in the list.
+ */
+ conf->realm = realm;
+
+ /* we precompute the part of the nonce hash that is constant (well,
+ * the host:port would be too, but that varies for .htaccess files
+ * and directives outside a virtual host section)
+ */
+ apr_sha1_init(&conf->nonce_ctx);
+ apr_sha1_update_binary(&conf->nonce_ctx, secret, SECRET_LEN);
+ apr_sha1_update_binary(&conf->nonce_ctx, (const unsigned char *) realm,
+ strlen(realm));
+
+ return DECLINE_CMD;
+}
+
+static const char *add_authn_provider(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ digest_config_rec *conf = (digest_config_rec*)config;
+ authn_provider_list *newp;
+
+ newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
+ newp->provider_name = arg;
+
+ /* lookup and cache the actual provider now */
+ newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ newp->provider_name,
+ AUTHN_PROVIDER_VERSION);
+
+ if (newp->provider == NULL) {
+ /* by the time they use it, the provider should be loaded and
+ registered with us. */
+ return apr_psprintf(cmd->pool,
+ "Unknown Authn provider: %s",
+ newp->provider_name);
+ }
+
+ if (!newp->provider->get_realm_hash) {
+ /* if it doesn't provide the appropriate function, reject it */
+ return apr_psprintf(cmd->pool,
+ "The '%s' Authn provider doesn't support "
+ "Digest Authentication", newp->provider_name);
+ }
+
+ /* Add it to the list now. */
+ if (!conf->providers) {
+ conf->providers = newp;
+ }
+ else {
+ authn_provider_list *last = conf->providers;
+
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = newp;
+ }
+
+ return NULL;
+}
+
+static const char *set_qop(cmd_parms *cmd, void *config, const char *op)
+{
+ digest_config_rec *conf = (digest_config_rec *) config;
+
+ if (!strcasecmp(op, "none")) {
+ apr_array_clear(conf->qop_list);
+ *(const char **)apr_array_push(conf->qop_list) = "none";
+ return NULL;
+ }
+
+ if (!strcasecmp(op, "auth-int")) {
+ return "AuthDigestQop auth-int is not implemented";
+ }
+ else if (strcasecmp(op, "auth")) {
+ return apr_pstrcat(cmd->pool, "Unrecognized qop: ", op, NULL);
+ }
+
+ *(const char **)apr_array_push(conf->qop_list) = op;
+
+ return NULL;
+}
+
+static const char *set_nonce_lifetime(cmd_parms *cmd, void *config,
+ const char *t)
+{
+ char *endptr;
+ long lifetime;
+
+ lifetime = strtol(t, &endptr, 10);
+ if (endptr < (t+strlen(t)) && !apr_isspace(*endptr)) {
+ return apr_pstrcat(cmd->pool,
+ "Invalid time in AuthDigestNonceLifetime: ",
+ t, NULL);
+ }
+
+ ((digest_config_rec *) config)->nonce_lifetime = apr_time_from_sec(lifetime);
+ return NULL;
+}
+
+static const char *set_nonce_format(cmd_parms *cmd, void *config,
+ const char *fmt)
+{
+ return "AuthDigestNonceFormat is not implemented";
+}
+
+static const char *set_nc_check(cmd_parms *cmd, void *config, int flag)
+{
+#if !APR_HAS_SHARED_MEMORY
+ if (flag) {
+ return "AuthDigestNcCheck: ERROR: nonce-count checking "
+ "is not supported on platforms without shared-memory "
+ "support";
+ }
+#endif
+
+ ((digest_config_rec *) config)->check_nc = flag;
+ return NULL;
+}
+
+static const char *set_algorithm(cmd_parms *cmd, void *config, const char *alg)
+{
+ if (!strcasecmp(alg, "MD5-sess")) {
+ return "AuthDigestAlgorithm: ERROR: algorithm `MD5-sess' "
+ "is not implemented";
+ }
+ else if (strcasecmp(alg, "MD5")) {
+ return apr_pstrcat(cmd->pool, "Invalid algorithm in AuthDigestAlgorithm: ", alg, NULL);
+ }
+
+ ((digest_config_rec *) config)->algorithm = alg;
+ return NULL;
+}
+
+static const char *set_uri_list(cmd_parms *cmd, void *config, const char *uri)
+{
+ digest_config_rec *c = (digest_config_rec *) config;
+ if (c->uri_list) {
+ c->uri_list[strlen(c->uri_list)-1] = '\0';
+ c->uri_list = apr_pstrcat(cmd->pool, c->uri_list, " ", uri, "\"", NULL);
+ }
+ else {
+ c->uri_list = apr_pstrcat(cmd->pool, ", domain=\"", uri, "\"", NULL);
+ }
+ return NULL;
+}
+
+static const char *set_shmem_size(cmd_parms *cmd, void *config,
+ const char *size_str)
+{
+ char *endptr;
+ long size, min;
+
+ size = strtol(size_str, &endptr, 10);
+ while (apr_isspace(*endptr)) endptr++;
+ if (*endptr == '\0' || *endptr == 'b' || *endptr == 'B') {
+ ;
+ }
+ else if (*endptr == 'k' || *endptr == 'K') {
+ size *= 1024;
+ }
+ else if (*endptr == 'm' || *endptr == 'M') {
+ size *= 1048576;
+ }
+ else {
+ return apr_pstrcat(cmd->pool, "Invalid size in AuthDigestShmemSize: ",
+ size_str, NULL);
+ }
+
+ min = sizeof(*client_list) + sizeof(client_entry*) + sizeof(client_entry);
+ if (size < min) {
+ return apr_psprintf(cmd->pool, "size in AuthDigestShmemSize too small: "
+ "%ld < %ld", size, min);
+ }
+
+ shmem_size = size;
+ num_buckets = (size - sizeof(*client_list)) /
+ (sizeof(client_entry*) + HASH_DEPTH * sizeof(client_entry));
+ if (num_buckets == 0) {
+ num_buckets = 1;
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01763)
+ "Set shmem-size: %" APR_SIZE_T_FMT ", num-buckets: %ld",
+ shmem_size, num_buckets);
+
+ return NULL;
+}
+
+static const command_rec digest_cmds[] =
+{
+ AP_INIT_TAKE1("AuthName", set_realm, NULL, OR_AUTHCFG,
+ "The authentication realm (e.g. \"Members Only\")"),
+ AP_INIT_ITERATE("AuthDigestProvider", add_authn_provider, NULL, OR_AUTHCFG,
+ "specify the auth providers for a directory or location"),
+ AP_INIT_ITERATE("AuthDigestQop", set_qop, NULL, OR_AUTHCFG,
+ "A list of quality-of-protection options"),
+ AP_INIT_TAKE1("AuthDigestNonceLifetime", set_nonce_lifetime, NULL, OR_AUTHCFG,
+ "Maximum lifetime of the server nonce (seconds)"),
+ AP_INIT_TAKE1("AuthDigestNonceFormat", set_nonce_format, NULL, OR_AUTHCFG,
+ "The format to use when generating the server nonce"),
+ AP_INIT_FLAG("AuthDigestNcCheck", set_nc_check, NULL, OR_AUTHCFG,
+ "Whether or not to check the nonce-count sent by the client"),
+ AP_INIT_TAKE1("AuthDigestAlgorithm", set_algorithm, NULL, OR_AUTHCFG,
+ "The algorithm used for the hash calculation"),
+ AP_INIT_ITERATE("AuthDigestDomain", set_uri_list, NULL, OR_AUTHCFG,
+ "A list of URI's which belong to the same protection space as the current URI"),
+ AP_INIT_TAKE1("AuthDigestShmemSize", set_shmem_size, NULL, RSRC_CONF,
+ "The amount of shared memory to allocate for keeping track of clients"),
+ {NULL}
+};
+
+
+/*
+ * client list code
+ *
+ * Each client is assigned a number, which is transferred in the opaque
+ * field of the WWW-Authenticate and Authorization headers. The number
+ * is just a simple counter which is incremented for each new client.
+ * Clients can't forge this number because it is hashed up into the
+ * server nonce, and that is checked.
+ *
+ * The clients are kept in a simple hash table, which consists of an
+ * array of client_entry's, each with a linked list of entries hanging
+ * off it. The client's number modulo the size of the array gives the
+ * bucket number.
+ *
+ * The clients are garbage collected whenever a new client is allocated
+ * but there is not enough space left in the shared memory segment. A
+ * simple semi-LRU is used for this: whenever a client entry is accessed
+ * it is moved to the beginning of the linked list in its bucket (this
+ * also makes for faster lookups for current clients). The garbage
+ * collecter then just removes the oldest entry (i.e. the one at the
+ * end of the list) in each bucket.
+ *
+ * The main advantages of the above scheme are that it's easy to implement
+ * and it keeps the hash table evenly balanced (i.e. same number of entries
+ * in each bucket). The major disadvantage is that you may be throwing
+ * entries out which are in active use. This is not tragic, as these
+ * clients will just be sent a new client id (opaque field) and nonce
+ * with a stale=true (i.e. it will just look like the nonce expired,
+ * thereby forcing an extra round trip). If the shared memory segment
+ * has enough headroom over the current client set size then this should
+ * not occur too often.
+ *
+ * To help tune the size of the shared memory segment (and see if the
+ * above algorithm is really sufficient) a set of counters is kept
+ * indicating the number of clients held, the number of garbage collected
+ * clients, and the number of erroneously purged clients. These are printed
+ * out at each garbage collection run. Note that access to the counters is
+ * not synchronized because they are just indicaters, and whether they are
+ * off by a few doesn't matter; and for the same reason no attempt is made
+ * to guarantee the num_renewed is correct in the face of clients spoofing
+ * the opaque field.
+ */
+
+/*
+ * Get the client given its client number (the key). Returns the entry,
+ * or NULL if it's not found.
+ *
+ * Access to the list itself is synchronized via locks. However, access
+ * to the entry returned by get_client() is NOT synchronized. This means
+ * that there are potentially problems if a client uses multiple,
+ * simultaneous connections to access url's within the same protection
+ * space. However, these problems are not new: when using multiple
+ * connections you have no guarantee of the order the requests are
+ * processed anyway, so you have problems with the nonce-count and
+ * one-time nonces anyway.
+ */
+static client_entry *get_client(unsigned long key, const request_rec *r)
+{
+ int bucket;
+ client_entry *entry, *prev = NULL;
+
+
+ if (!key || !client_shm) return NULL;
+
+ bucket = key % client_list->tbl_len;
+ entry = client_list->table[bucket];
+
+ apr_global_mutex_lock(client_lock);
+
+ while (entry && key != entry->key) {
+ prev = entry;
+ entry = entry->next;
+ }
+
+ if (entry && prev) { /* move entry to front of list */
+ prev->next = entry->next;
+ entry->next = client_list->table[bucket];
+ client_list->table[bucket] = entry;
+ }
+
+ apr_global_mutex_unlock(client_lock);
+
+ if (entry) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01764)
+ "get_client(): client %lu found", key);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01765)
+ "get_client(): client %lu not found", key);
+ }
+
+ return entry;
+}
+
+
+/* A simple garbage-collecter to remove unused clients. It removes the
+ * last entry in each bucket and updates the counters. Returns the
+ * number of removed entries.
+ */
+static long gc(server_rec *s)
+{
+ client_entry *entry, *prev;
+ unsigned long num_removed = 0, idx;
+
+ /* garbage collect all last entries */
+
+ for (idx = 0; idx < client_list->tbl_len; idx++) {
+ entry = client_list->table[idx];
+ prev = NULL;
+
+ if (!entry) {
+ /* This bucket is empty. */
+ continue;
+ }
+
+ while (entry->next) { /* find last entry */
+ prev = entry;
+ entry = entry->next;
+ }
+ if (prev) {
+ prev->next = NULL; /* cut list */
+ }
+ else {
+ client_list->table[idx] = NULL;
+ }
+ if (entry) { /* remove entry */
+ apr_status_t err;
+
+ err = rmm_free(client_rmm, entry);
+ num_removed++;
+
+ if (err) {
+ /* Nothing we can really do but log... */
+ ap_log_error(APLOG_MARK, APLOG_ERR, err, s, APLOGNO(10007)
+ "Failed to free auth_digest client allocation");
+ }
+ }
+ }
+
+ /* update counters and log */
+
+ client_list->num_entries -= num_removed;
+ client_list->num_removed += num_removed;
+
+ return num_removed;
+}
+
+
+/*
+ * Add a new client to the list. Returns the entry if successful, NULL
+ * otherwise. This triggers the garbage collection if memory is low.
+ */
+static client_entry *add_client(unsigned long key, client_entry *info,
+ server_rec *s)
+{
+ int bucket;
+ client_entry *entry;
+
+
+ if (!key || !client_shm) {
+ return NULL;
+ }
+
+ bucket = key % client_list->tbl_len;
+
+ apr_global_mutex_lock(client_lock);
+
+ /* try to allocate a new entry */
+
+ entry = rmm_malloc(client_rmm, sizeof(client_entry));
+ if (!entry) {
+ long num_removed = gc(s);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01766)
+ "gc'd %ld client entries. Total new clients: "
+ "%ld; Total removed clients: %ld; Total renewed clients: "
+ "%ld", num_removed,
+ client_list->num_created - client_list->num_renewed,
+ client_list->num_removed, client_list->num_renewed);
+ entry = rmm_malloc(client_rmm, sizeof(client_entry));
+ if (!entry) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01767)
+ "unable to allocate new auth_digest client");
+ apr_global_mutex_unlock(client_lock);
+ return NULL; /* give up */
+ }
+ }
+
+ /* now add the entry */
+
+ memcpy(entry, info, sizeof(client_entry));
+ entry->key = key;
+ entry->next = client_list->table[bucket];
+ client_list->table[bucket] = entry;
+ client_list->num_created++;
+ client_list->num_entries++;
+
+ apr_global_mutex_unlock(client_lock);
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01768)
+ "allocated new client %lu", key);
+
+ return entry;
+}
+
+
+/*
+ * Authorization header parser code
+ */
+
+/* Parse the Authorization header, if it exists */
+static int get_digest_rec(request_rec *r, digest_header_rec *resp)
+{
+ const char *auth_line;
+ apr_size_t l;
+ int vk = 0, vv = 0;
+ char *key, *value;
+
+ auth_line = apr_table_get(r->headers_in,
+ (PROXYREQ_PROXY == r->proxyreq)
+ ? "Proxy-Authorization"
+ : "Authorization");
+ if (!auth_line) {
+ resp->auth_hdr_sts = NO_HEADER;
+ return !OK;
+ }
+
+ resp->scheme = ap_getword_white(r->pool, &auth_line);
+ if (strcasecmp(resp->scheme, "Digest")) {
+ resp->auth_hdr_sts = NOT_DIGEST;
+ return !OK;
+ }
+
+ l = strlen(auth_line);
+
+ key = apr_palloc(r->pool, l+1);
+ value = apr_palloc(r->pool, l+1);
+
+ while (auth_line[0] != '\0') {
+
+ /* find key */
+
+ while (apr_isspace(auth_line[0])) {
+ auth_line++;
+ }
+ vk = 0;
+ while (auth_line[0] != '=' && auth_line[0] != ','
+ && auth_line[0] != '\0' && !apr_isspace(auth_line[0])) {
+ key[vk++] = *auth_line++;
+ }
+ key[vk] = '\0';
+ while (apr_isspace(auth_line[0])) {
+ auth_line++;
+ }
+
+ /* find value */
+
+ vv = 0;
+ if (auth_line[0] == '=') {
+ auth_line++;
+ while (apr_isspace(auth_line[0])) {
+ auth_line++;
+ }
+
+ if (auth_line[0] == '\"') { /* quoted string */
+ auth_line++;
+ while (auth_line[0] != '\"' && auth_line[0] != '\0') {
+ if (auth_line[0] == '\\' && auth_line[1] != '\0') {
+ auth_line++; /* escaped char */
+ }
+ value[vv++] = *auth_line++;
+ }
+ if (auth_line[0] != '\0') {
+ auth_line++;
+ }
+ }
+ else { /* token */
+ while (auth_line[0] != ',' && auth_line[0] != '\0'
+ && !apr_isspace(auth_line[0])) {
+ value[vv++] = *auth_line++;
+ }
+ }
+ }
+ value[vv] = '\0';
+
+ while (auth_line[0] != ',' && auth_line[0] != '\0') {
+ auth_line++;
+ }
+ if (auth_line[0] != '\0') {
+ auth_line++;
+ }
+
+ if (!strcasecmp(key, "username"))
+ resp->username = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "realm"))
+ resp->realm = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "nonce"))
+ resp->nonce = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "uri"))
+ resp->uri = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "response"))
+ resp->digest = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "algorithm"))
+ resp->algorithm = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "cnonce"))
+ resp->cnonce = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "opaque"))
+ resp->opaque = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "qop"))
+ resp->message_qop = apr_pstrdup(r->pool, value);
+ else if (!strcasecmp(key, "nc"))
+ resp->nonce_count = apr_pstrdup(r->pool, value);
+ }
+
+ if (!resp->username || !resp->realm || !resp->nonce || !resp->uri
+ || !resp->digest
+ || (resp->message_qop && (!resp->cnonce || !resp->nonce_count))) {
+ resp->auth_hdr_sts = INVALID;
+ return !OK;
+ }
+
+ if (resp->opaque) {
+ resp->opaque_num = (unsigned long) strtol(resp->opaque, NULL, 16);
+ }
+
+ resp->auth_hdr_sts = VALID;
+ return OK;
+}
+
+
+/* Because the browser may preemptively send auth info, incrementing the
+ * nonce-count when it does, and because the client does not get notified
+ * if the URI didn't need authentication after all, we need to be sure to
+ * update the nonce-count each time we receive an Authorization header no
+ * matter what the final outcome of the request. Furthermore this is a
+ * convenient place to get the request-uri (before any subrequests etc
+ * are initiated) and to initialize the request_config.
+ *
+ * Note that this must be called after mod_proxy had its go so that
+ * r->proxyreq is set correctly.
+ */
+static int parse_hdr_and_update_nc(request_rec *r)
+{
+ digest_header_rec *resp;
+ int res;
+
+ if (!ap_is_initial_req(r)) {
+ return DECLINED;
+ }
+
+ resp = apr_pcalloc(r->pool, sizeof(digest_header_rec));
+ resp->raw_request_uri = r->unparsed_uri;
+ resp->psd_request_uri = &r->parsed_uri;
+ resp->needed_auth = 0;
+ resp->method = r->method;
+ ap_set_module_config(r->request_config, &auth_digest_module, resp);
+
+ res = get_digest_rec(r, resp);
+ resp->client = get_client(resp->opaque_num, r);
+ if (res == OK && resp->client) {
+ resp->client->nonce_count++;
+ }
+
+ return DECLINED;
+}
+
+
+/*
+ * Nonce generation code
+ */
+
+/* The hash part of the nonce is a SHA-1 hash of the time, realm, server host
+ * and port, opaque, and our secret.
+ */
+static void gen_nonce_hash(char *hash, const char *timestr, const char *opaque,
+ const server_rec *server,
+ const digest_config_rec *conf)
+{
+ unsigned char sha1[APR_SHA1_DIGESTSIZE];
+ apr_sha1_ctx_t ctx;
+
+ memcpy(&ctx, &conf->nonce_ctx, sizeof(ctx));
+ /*
+ apr_sha1_update_binary(&ctx, (const unsigned char *) server->server_hostname,
+ strlen(server->server_hostname));
+ apr_sha1_update_binary(&ctx, (const unsigned char *) &server->port,
+ sizeof(server->port));
+ */
+ apr_sha1_update_binary(&ctx, (const unsigned char *) timestr, strlen(timestr));
+ if (opaque) {
+ apr_sha1_update_binary(&ctx, (const unsigned char *) opaque,
+ strlen(opaque));
+ }
+ apr_sha1_final(sha1, &ctx);
+
+ ap_bin2hex(sha1, APR_SHA1_DIGESTSIZE, hash);
+}
+
+
+/* The nonce has the format b64(time)+hash .
+ */
+static const char *gen_nonce(apr_pool_t *p, apr_time_t now, const char *opaque,
+ const server_rec *server,
+ const digest_config_rec *conf)
+{
+ char *nonce = apr_palloc(p, NONCE_LEN+1);
+ time_rec t;
+
+ if (conf->nonce_lifetime != 0) {
+ t.time = now;
+ }
+ else if (otn_counter) {
+ /* this counter is not synch'd, because it doesn't really matter
+ * if it counts exactly.
+ */
+ t.time = (*otn_counter)++;
+ }
+ else {
+ /* XXX: WHAT IS THIS CONSTANT? */
+ t.time = 42;
+ }
+ apr_base64_encode_binary(nonce, t.arr, sizeof(t.arr));
+ gen_nonce_hash(nonce+NONCE_TIME_LEN, nonce, opaque, server, conf);
+
+ return nonce;
+}
+
+
+/*
+ * Opaque and hash-table management
+ */
+
+/*
+ * Generate a new client entry, add it to the list, and return the
+ * entry. Returns NULL if failed.
+ */
+static client_entry *gen_client(const request_rec *r)
+{
+ unsigned long op;
+ client_entry new_entry = { 0, NULL, 0, "" }, *entry;
+
+ if (!opaque_cntr) {
+ return NULL;
+ }
+
+ apr_global_mutex_lock(opaque_lock);
+ op = (*opaque_cntr)++;
+ apr_global_mutex_unlock(opaque_lock);
+
+ if (!(entry = add_client(op, &new_entry, r->server))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01769)
+ "failed to allocate client entry - ignoring client");
+ return NULL;
+ }
+
+ return entry;
+}
+
+
+/*
+ * Authorization challenge generation code (for WWW-Authenticate)
+ */
+
+static const char *ltox(apr_pool_t *p, unsigned long num)
+{
+ if (num != 0) {
+ return apr_psprintf(p, "%lx", num);
+ }
+ else {
+ return "";
+ }
+}
+
+static void note_digest_auth_failure(request_rec *r,
+ const digest_config_rec *conf,
+ digest_header_rec *resp, int stale)
+{
+ const char *qop, *opaque, *opaque_param, *domain, *nonce;
+
+ /* Setup qop */
+ if (apr_is_empty_array(conf->qop_list)) {
+ qop = ", qop=\"auth\"";
+ }
+ else if (!strcasecmp(*(const char **)(conf->qop_list->elts), "none")) {
+ qop = "";
+ }
+ else {
+ qop = apr_pstrcat(r->pool, ", qop=\"",
+ apr_array_pstrcat(r->pool, conf->qop_list, ','),
+ "\"",
+ NULL);
+ }
+
+ /* Setup opaque */
+
+ if (resp->opaque == NULL) {
+ /* new client */
+ if ((conf->check_nc || conf->nonce_lifetime == 0)
+ && (resp->client = gen_client(r)) != NULL) {
+ opaque = ltox(r->pool, resp->client->key);
+ }
+ else {
+ opaque = ""; /* opaque not needed */
+ }
+ }
+ else if (resp->client == NULL) {
+ /* client info was gc'd */
+ resp->client = gen_client(r);
+ if (resp->client != NULL) {
+ opaque = ltox(r->pool, resp->client->key);
+ stale = 1;
+ client_list->num_renewed++;
+ }
+ else {
+ opaque = ""; /* ??? */
+ }
+ }
+ else {
+ opaque = resp->opaque;
+ /* we're generating a new nonce, so reset the nonce-count */
+ resp->client->nonce_count = 0;
+ }
+
+ if (opaque[0]) {
+ opaque_param = apr_pstrcat(r->pool, ", opaque=\"", opaque, "\"", NULL);
+ }
+ else {
+ opaque_param = NULL;
+ }
+
+ /* Setup nonce */
+
+ nonce = gen_nonce(r->pool, r->request_time, opaque, r->server, conf);
+ if (resp->client && conf->nonce_lifetime == 0) {
+ memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1);
+ }
+
+ /* setup domain attribute. We want to send this attribute wherever
+ * possible so that the client won't send the Authorization header
+ * unnecessarily (it's usually > 200 bytes!).
+ */
+
+
+ /* don't send domain
+ * - for proxy requests
+ * - if it's not specified
+ */
+ if (r->proxyreq || !conf->uri_list) {
+ domain = NULL;
+ }
+ else {
+ domain = conf->uri_list;
+ }
+
+ apr_table_mergen(r->err_headers_out,
+ (PROXYREQ_PROXY == r->proxyreq)
+ ? "Proxy-Authenticate" : "WWW-Authenticate",
+ apr_psprintf(r->pool, "Digest realm=\"%s\", "
+ "nonce=\"%s\", algorithm=%s%s%s%s%s",
+ ap_auth_name(r), nonce, conf->algorithm,
+ opaque_param ? opaque_param : "",
+ domain ? domain : "",
+ stale ? ", stale=true" : "", qop));
+
+}
+
+static int hook_note_digest_auth_failure(request_rec *r, const char *auth_type)
+{
+ request_rec *mainreq;
+ digest_header_rec *resp;
+ digest_config_rec *conf;
+
+ if (strcasecmp(auth_type, "Digest"))
+ return DECLINED;
+
+ /* get the client response and mark */
+
+ mainreq = r;
+ while (mainreq->main != NULL) {
+ mainreq = mainreq->main;
+ }
+ while (mainreq->prev != NULL) {
+ mainreq = mainreq->prev;
+ }
+ resp = (digest_header_rec *) ap_get_module_config(mainreq->request_config,
+ &auth_digest_module);
+ resp->needed_auth = 1;
+
+
+ /* get our conf */
+
+ conf = (digest_config_rec *) ap_get_module_config(r->per_dir_config,
+ &auth_digest_module);
+
+ note_digest_auth_failure(r, conf, resp, 0);
+
+ return OK;
+}
+
+
+/*
+ * Authorization header verification code
+ */
+
+static authn_status get_hash(request_rec *r, const char *user,
+ digest_config_rec *conf)
+{
+ authn_status auth_result;
+ char *password;
+ authn_provider_list *current_provider;
+
+ current_provider = conf->providers;
+ do {
+ const authn_provider *provider;
+
+ /* For now, if a provider isn't set, we'll be nice and use the file
+ * provider.
+ */
+ if (!current_provider) {
+ provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ AUTHN_DEFAULT_PROVIDER,
+ AUTHN_PROVIDER_VERSION);
+
+ if (!provider || !provider->get_realm_hash) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01770)
+ "No Authn provider configured");
+ auth_result = AUTH_GENERAL_ERROR;
+ break;
+ }
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, AUTHN_DEFAULT_PROVIDER);
+ }
+ else {
+ provider = current_provider->provider;
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, current_provider->provider_name);
+ }
+
+
+ /* We expect the password to be md5 hash of user:realm:password */
+ auth_result = provider->get_realm_hash(r, user, conf->realm,
+ &password);
+
+ apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+
+ /* Something occurred. Stop checking. */
+ if (auth_result != AUTH_USER_NOT_FOUND) {
+ break;
+ }
+
+ /* If we're not really configured for providers, stop now. */
+ if (!conf->providers) {
+ break;
+ }
+
+ current_provider = current_provider->next;
+ } while (current_provider);
+
+ if (auth_result == AUTH_USER_FOUND) {
+ conf->ha1 = password;
+ }
+
+ return auth_result;
+}
+
+static int check_nc(const request_rec *r, const digest_header_rec *resp,
+ const digest_config_rec *conf)
+{
+ unsigned long nc;
+ const char *snc = resp->nonce_count;
+ char *endptr;
+
+ if (conf->check_nc && !client_shm) {
+ /* Shouldn't happen, but just in case... */
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01771)
+ "cannot check nonce count without shared memory");
+ return OK;
+ }
+
+ if (!conf->check_nc || !client_shm) {
+ return OK;
+ }
+
+ if (!apr_is_empty_array(conf->qop_list) &&
+ !strcasecmp(*(const char **)(conf->qop_list->elts), "none")) {
+ /* qop is none, client must not send a nonce count */
+ if (snc != NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01772)
+ "invalid nc %s received - no nonce count allowed when qop=none",
+ snc);
+ return !OK;
+ }
+ /* qop is none, cannot check nonce count */
+ return OK;
+ }
+
+ nc = strtol(snc, &endptr, 16);
+ if (endptr < (snc+strlen(snc)) && !apr_isspace(*endptr)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01773)
+ "invalid nc %s received - not a number", snc);
+ return !OK;
+ }
+
+ if (!resp->client) {
+ return !OK;
+ }
+
+ if (nc != resp->client->nonce_count) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01774)
+ "Warning, possible replay attack: nonce-count "
+ "check failed: %lu != %lu", nc,
+ resp->client->nonce_count);
+ return !OK;
+ }
+
+ return OK;
+}
+
+static int check_nonce(request_rec *r, digest_header_rec *resp,
+ const digest_config_rec *conf)
+{
+ apr_time_t dt;
+ time_rec nonce_time;
+ char tmp, hash[NONCE_HASH_LEN+1];
+
+ if (strlen(resp->nonce) != NONCE_LEN) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01775)
+ "invalid nonce %s received - length is not %d",
+ resp->nonce, NONCE_LEN);
+ note_digest_auth_failure(r, conf, resp, 1);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ tmp = resp->nonce[NONCE_TIME_LEN];
+ resp->nonce[NONCE_TIME_LEN] = '\0';
+ apr_base64_decode_binary(nonce_time.arr, resp->nonce);
+ gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf);
+ resp->nonce[NONCE_TIME_LEN] = tmp;
+ resp->nonce_time = nonce_time.time;
+
+ if (strcmp(hash, resp->nonce+NONCE_TIME_LEN)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01776)
+ "invalid nonce %s received - hash is not %s",
+ resp->nonce, hash);
+ note_digest_auth_failure(r, conf, resp, 1);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ dt = r->request_time - nonce_time.time;
+ if (conf->nonce_lifetime > 0 && dt < 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01777)
+ "invalid nonce %s received - user attempted "
+ "time travel", resp->nonce);
+ note_digest_auth_failure(r, conf, resp, 1);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ if (conf->nonce_lifetime > 0) {
+ if (dt > conf->nonce_lifetime) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0,r, APLOGNO(01778)
+ "user %s: nonce expired (%.2f seconds old "
+ "- max lifetime %.2f) - sending new nonce",
+ r->user, (double)apr_time_sec(dt),
+ (double)apr_time_sec(conf->nonce_lifetime));
+ note_digest_auth_failure(r, conf, resp, 1);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+ else if (conf->nonce_lifetime == 0 && resp->client) {
+ if (memcmp(resp->client->last_nonce, resp->nonce, NONCE_LEN)) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01779)
+ "user %s: one-time-nonce mismatch - sending "
+ "new nonce", r->user);
+ note_digest_auth_failure(r, conf, resp, 1);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+ /* else (lifetime < 0) => never expires */
+
+ return OK;
+}
+
+/* The actual MD5 code... whee */
+
+/* RFC-2069 */
+static const char *old_digest(const request_rec *r,
+ const digest_header_rec *resp, const char *ha1)
+{
+ const char *ha2;
+
+ ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":",
+ resp->uri, NULL));
+ return ap_md5(r->pool,
+ (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce,
+ ":", ha2, NULL));
+}
+
+/* RFC-2617 */
+static const char *new_digest(const request_rec *r,
+ digest_header_rec *resp,
+ const digest_config_rec *conf)
+{
+ const char *ha1, *ha2, *a2;
+
+ ha1 = conf->ha1;
+
+ a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL);
+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
+
+ return ap_md5(r->pool,
+ (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce,
+ ":", resp->nonce_count, ":",
+ resp->cnonce, ":",
+ resp->message_qop, ":", ha2,
+ NULL));
+}
+
+
+static void copy_uri_components(apr_uri_t *dst,
+ apr_uri_t *src, request_rec *r) {
+ if (src->scheme && src->scheme[0] != '\0') {
+ dst->scheme = src->scheme;
+ }
+ else {
+ dst->scheme = (char *) "http";
+ }
+
+ if (src->hostname && src->hostname[0] != '\0') {
+ dst->hostname = apr_pstrdup(r->pool, src->hostname);
+ ap_unescape_url(dst->hostname);
+ }
+ else {
+ dst->hostname = (char *) ap_get_server_name(r);
+ }
+
+ if (src->port_str && src->port_str[0] != '\0') {
+ dst->port = src->port;
+ }
+ else {
+ dst->port = ap_get_server_port(r);
+ }
+
+ if (src->path && src->path[0] != '\0') {
+ dst->path = apr_pstrdup(r->pool, src->path);
+ ap_unescape_url(dst->path);
+ }
+ else {
+ dst->path = src->path;
+ }
+
+ if (src->query && src->query[0] != '\0') {
+ dst->query = apr_pstrdup(r->pool, src->query);
+ ap_unescape_url(dst->query);
+ }
+ else {
+ dst->query = src->query;
+ }
+
+ dst->hostinfo = src->hostinfo;
+}
+
+/* These functions return 0 if client is OK, and proper error status
+ * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
+ * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
+ * couldn't figure out how to tell if the client is authorized or not.
+ *
+ * If they return DECLINED, and all other modules also decline, that's
+ * treated by the server core as a configuration error, logged and
+ * reported as such.
+ */
+
+/* Determine user ID, and check if the attributes are correct, if it
+ * really is that user, if the nonce is correct, etc.
+ */
+
+static int authenticate_digest_user(request_rec *r)
+{
+ digest_config_rec *conf;
+ digest_header_rec *resp;
+ request_rec *mainreq;
+ const char *t;
+ int res;
+ authn_status return_code;
+
+ /* do we require Digest auth for this URI? */
+
+ if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest")) {
+ return DECLINED;
+ }
+
+ if (!ap_auth_name(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01780)
+ "need AuthName: %s", r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+
+ /* get the client response and mark */
+
+ mainreq = r;
+ while (mainreq->main != NULL) {
+ mainreq = mainreq->main;
+ }
+ while (mainreq->prev != NULL) {
+ mainreq = mainreq->prev;
+ }
+ resp = (digest_header_rec *) ap_get_module_config(mainreq->request_config,
+ &auth_digest_module);
+ resp->needed_auth = 1;
+
+
+ /* get our conf */
+
+ conf = (digest_config_rec *) ap_get_module_config(r->per_dir_config,
+ &auth_digest_module);
+
+
+ /* check for existence and syntax of Auth header */
+
+ if (resp->auth_hdr_sts != VALID) {
+ if (resp->auth_hdr_sts == NOT_DIGEST) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01781)
+ "client used wrong authentication scheme `%s': %s",
+ resp->scheme, r->uri);
+ }
+ else if (resp->auth_hdr_sts == INVALID) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01782)
+ "missing user, realm, nonce, uri, digest, "
+ "cnonce, or nonce_count in authorization header: %s",
+ r->uri);
+ }
+ /* else (resp->auth_hdr_sts == NO_HEADER) */
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ r->user = (char *) resp->username;
+ r->ap_auth_type = (char *) "Digest";
+
+ /* check the auth attributes */
+
+ if (strcmp(resp->uri, resp->raw_request_uri)) {
+ /* Hmm, the simple match didn't work (probably a proxy modified the
+ * request-uri), so lets do a more sophisticated match
+ */
+ apr_uri_t r_uri, d_uri;
+
+ copy_uri_components(&r_uri, resp->psd_request_uri, r);
+ if (apr_uri_parse(r->pool, resp->uri, &d_uri) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01783)
+ "invalid uri <%s> in Authorization header",
+ resp->uri);
+ return HTTP_BAD_REQUEST;
+ }
+
+ if (d_uri.hostname) {
+ ap_unescape_url(d_uri.hostname);
+ }
+ if (d_uri.path) {
+ ap_unescape_url(d_uri.path);
+ }
+
+ if (d_uri.query) {
+ ap_unescape_url(d_uri.query);
+ }
+ else if (r_uri.query) {
+ /* MSIE compatibility hack. MSIE has some RFC issues - doesn't
+ * include the query string in the uri Authorization component
+ * or when computing the response component. the second part
+ * works out ok, since we can hash the header and get the same
+ * result. however, the uri from the request line won't match
+ * the uri Authorization component since the header lacks the
+ * query string, leaving us incompatible with a (broken) MSIE.
+ *
+ * the workaround is to fake a query string match if in the proper
+ * environment - BrowserMatch MSIE, for example. the cool thing
+ * is that if MSIE ever fixes itself the simple match ought to
+ * work and this code won't be reached anyway, even if the
+ * environment is set.
+ */
+
+ if (apr_table_get(r->subprocess_env,
+ "AuthDigestEnableQueryStringHack")) {
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01784)
+ "applying AuthDigestEnableQueryStringHack "
+ "to uri <%s>", resp->raw_request_uri);
+
+ d_uri.query = r_uri.query;
+ }
+ }
+
+ if (r->method_number == M_CONNECT) {
+ if (!r_uri.hostinfo || strcmp(resp->uri, r_uri.hostinfo)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01785)
+ "uri mismatch - <%s> does not match "
+ "request-uri <%s>", resp->uri, r_uri.hostinfo);
+ return HTTP_BAD_REQUEST;
+ }
+ }
+ else if (
+ /* check hostname matches, if present */
+ (d_uri.hostname && d_uri.hostname[0] != '\0'
+ && strcasecmp(d_uri.hostname, r_uri.hostname))
+ /* check port matches, if present */
+ || (d_uri.port_str && d_uri.port != r_uri.port)
+ /* check that server-port is default port if no port present */
+ || (d_uri.hostname && d_uri.hostname[0] != '\0'
+ && !d_uri.port_str && r_uri.port != ap_default_port(r))
+ /* check that path matches */
+ || (d_uri.path != r_uri.path
+ /* either exact match */
+ && (!d_uri.path || !r_uri.path
+ || strcmp(d_uri.path, r_uri.path))
+ /* or '*' matches empty path in scheme://host */
+ && !(d_uri.path && !r_uri.path && resp->psd_request_uri->hostname
+ && d_uri.path[0] == '*' && d_uri.path[1] == '\0'))
+ /* check that query matches */
+ || (d_uri.query != r_uri.query
+ && (!d_uri.query || !r_uri.query
+ || strcmp(d_uri.query, r_uri.query)))
+ ) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01786)
+ "uri mismatch - <%s> does not match "
+ "request-uri <%s>", resp->uri, resp->raw_request_uri);
+ return HTTP_BAD_REQUEST;
+ }
+ }
+
+ if (resp->opaque && resp->opaque_num == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01787)
+ "received invalid opaque - got `%s'",
+ resp->opaque);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ if (!conf->realm) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02533)
+ "realm mismatch - got `%s' but no realm specified",
+ resp->realm);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ if (!resp->realm || strcmp(resp->realm, conf->realm)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01788)
+ "realm mismatch - got `%s' but expected `%s'",
+ resp->realm, conf->realm);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ if (resp->algorithm != NULL
+ && strcasecmp(resp->algorithm, "MD5")) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01789)
+ "unknown algorithm `%s' received: %s",
+ resp->algorithm, r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ return_code = get_hash(r, r->user, conf);
+
+ if (return_code == AUTH_USER_NOT_FOUND) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790)
+ "user `%s' in realm `%s' not found: %s",
+ r->user, conf->realm, r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+ else if (return_code == AUTH_USER_FOUND) {
+ /* we have a password, so continue */
+ }
+ else if (return_code == AUTH_DENIED) {
+ /* authentication denied in the provider before attempting a match */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01791)
+ "user `%s' in realm `%s' denied by provider: %s",
+ r->user, conf->realm, r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+ else {
+ /* AUTH_GENERAL_ERROR (or worse)
+ * We'll assume that the module has already said what its error
+ * was in the logs.
+ */
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (resp->message_qop == NULL) {
+ /* old (rfc-2069) style digest */
+ if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792)
+ "user %s: password mismatch: %s", r->user,
+ r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+ else {
+ const char *exp_digest;
+ int match = 0, idx;
+ const char **tmp = (const char **)(conf->qop_list->elts);
+ for (idx = 0; idx < conf->qop_list->nelts; idx++) {
+ if (!strcasecmp(*tmp, resp->message_qop)) {
+ match = 1;
+ break;
+ }
+ ++tmp;
+ }
+
+ if (!match
+ && !(apr_is_empty_array(conf->qop_list)
+ && !strcasecmp(resp->message_qop, "auth"))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01793)
+ "invalid qop `%s' received: %s",
+ resp->message_qop, r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ exp_digest = new_digest(r, resp, conf);
+ if (!exp_digest) {
+ /* we failed to allocate a client struct */
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if (strcmp(resp->digest, exp_digest)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01794)
+ "user %s: password mismatch: %s", r->user,
+ r->uri);
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+
+ if (check_nc(r, resp, conf) != OK) {
+ note_digest_auth_failure(r, conf, resp, 0);
+ return HTTP_UNAUTHORIZED;
+ }
+
+ /* Note: this check is done last so that a "stale=true" can be
+ generated if the nonce is old */
+ if ((res = check_nonce(r, resp, conf))) {
+ return res;
+ }
+
+ return OK;
+}
+
+/*
+ * Authorization-Info header code
+ */
+
+static int add_auth_info(request_rec *r)
+{
+ const digest_config_rec *conf =
+ (digest_config_rec *) ap_get_module_config(r->per_dir_config,
+ &auth_digest_module);
+ digest_header_rec *resp =
+ (digest_header_rec *) ap_get_module_config(r->request_config,
+ &auth_digest_module);
+ const char *ai = NULL, *nextnonce = "";
+
+ if (resp == NULL || !resp->needed_auth || conf == NULL) {
+ return OK;
+ }
+
+ /* 2069-style entity-digest is not supported (it's too hard, and
+ * there are no clients which support 2069 but not 2617). */
+
+ /* setup nextnonce
+ */
+ if (conf->nonce_lifetime > 0) {
+ /* send nextnonce if current nonce will expire in less than 30 secs */
+ if ((r->request_time - resp->nonce_time) > (conf->nonce_lifetime-NEXTNONCE_DELTA)) {
+ nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"",
+ gen_nonce(r->pool, r->request_time,
+ resp->opaque, r->server, conf),
+ "\"", NULL);
+ if (resp->client)
+ resp->client->nonce_count = 0;
+ }
+ }
+ else if (conf->nonce_lifetime == 0 && resp->client) {
+ const char *nonce = gen_nonce(r->pool, 0, resp->opaque, r->server,
+ conf);
+ nextnonce = apr_pstrcat(r->pool, ", nextnonce=\"", nonce, "\"", NULL);
+ memcpy(resp->client->last_nonce, nonce, NONCE_LEN+1);
+ }
+ /* else nonce never expires, hence no nextnonce */
+
+
+ /* do rfc-2069 digest
+ */
+ if (!apr_is_empty_array(conf->qop_list) &&
+ !strcasecmp(*(const char **)(conf->qop_list->elts), "none")
+ && resp->message_qop == NULL) {
+ /* use only RFC-2069 format */
+ ai = nextnonce;
+ }
+ else {
+ const char *resp_dig, *ha1, *a2, *ha2;
+
+ /* calculate rspauth attribute
+ */
+ ha1 = conf->ha1;
+
+ a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL);
+ ha2 = ap_md5(r->pool, (const unsigned char *)a2);
+
+ resp_dig = ap_md5(r->pool,
+ (unsigned char *)apr_pstrcat(r->pool, ha1, ":",
+ resp->nonce, ":",
+ resp->nonce_count, ":",
+ resp->cnonce, ":",
+ resp->message_qop ?
+ resp->message_qop : "",
+ ":", ha2, NULL));
+
+ /* assemble Authentication-Info header
+ */
+ ai = apr_pstrcat(r->pool,
+ "rspauth=\"", resp_dig, "\"",
+ nextnonce,
+ resp->cnonce ? ", cnonce=\"" : "",
+ resp->cnonce
+ ? ap_escape_quotes(r->pool, resp->cnonce)
+ : "",
+ resp->cnonce ? "\"" : "",
+ resp->nonce_count ? ", nc=" : "",
+ resp->nonce_count ? resp->nonce_count : "",
+ resp->message_qop ? ", qop=" : "",
+ resp->message_qop ? resp->message_qop : "",
+ NULL);
+ }
+
+ if (ai && ai[0]) {
+ apr_table_mergen(r->headers_out,
+ (PROXYREQ_PROXY == r->proxyreq)
+ ? "Proxy-Authentication-Info"
+ : "Authentication-Info",
+ ai);
+ }
+
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ static const char * const cfgPost[]={ "http_core.c", NULL };
+ static const char * const parsePre[]={ "mod_proxy.c", NULL };
+
+ ap_hook_pre_config(pre_init, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(initialize_module, NULL, cfgPost, APR_HOOK_MIDDLE);
+ ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_read_request(parse_hdr_and_update_nc, parsePre, NULL, APR_HOOK_MIDDLE);
+ ap_hook_check_authn(authenticate_digest_user, NULL, NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
+
+ ap_hook_fixups(add_auth_info, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_note_auth_failure(hook_note_digest_auth_failure, NULL, NULL,
+ APR_HOOK_MIDDLE);
+
+}
+
+AP_DECLARE_MODULE(auth_digest) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_digest_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ digest_cmds, /* command table */
+ register_hooks /* register hooks */
+};
+
diff --git a/modules/aaa/mod_auth_digest.dep b/modules/aaa/mod_auth_digest.dep
new file mode 100644
index 0000000..81451de
--- /dev/null
+++ b/modules/aaa/mod_auth_digest.dep
@@ -0,0 +1,68 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_auth_digest.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_auth_digest.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_md5.h"\
+ "..\..\include\util_mutex.h"\
+ "..\..\srclib\apr-util\include\apr_anylock.h"\
+ "..\..\srclib\apr-util\include\apr_base64.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_rmm.h"\
+ "..\..\srclib\apr-util\include\apr_sha1.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_thread_rwlock.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_auth_digest.dsp b/modules/aaa/mod_auth_digest.dsp
new file mode 100644
index 0000000..9d1bee1
--- /dev/null
+++ b/modules/aaa/mod_auth_digest.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_auth_digest" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_auth_digest - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_digest.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_digest.mak" CFG="mod_auth_digest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_digest - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_digest - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_auth_digest_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_auth_digest.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_auth_digest_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_digest.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_auth_digest.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_auth_digest - Win32 Release"
+# Name "mod_auth_digest - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_auth_digest.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_auth_digest.mak b/modules/aaa/mod_auth_digest.mak
new file mode 100644
index 0000000..4b54375
--- /dev/null
+++ b/modules/aaa/mod_auth_digest.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_digest.dsp
+!IF "$(CFG)" == ""
+CFG=mod_auth_digest - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_auth_digest - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_auth_digest - Win32 Release" && "$(CFG)" != "mod_auth_digest - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_digest.mak" CFG="mod_auth_digest - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_digest - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_digest - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_digest.obj"
+ -@erase "$(INTDIR)\mod_auth_digest.res"
+ -@erase "$(INTDIR)\mod_auth_digest_src.idb"
+ -@erase "$(INTDIR)\mod_auth_digest_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_digest.exp"
+ -@erase "$(OUTDIR)\mod_auth_digest.lib"
+ -@erase "$(OUTDIR)\mod_auth_digest.pdb"
+ -@erase "$(OUTDIR)\mod_auth_digest.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_digest_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_digest.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_digest.pdb" /debug /out:"$(OUTDIR)\mod_auth_digest.so" /implib:"$(OUTDIR)\mod_auth_digest.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_digest.obj" \
+ "$(INTDIR)\mod_auth_digest.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_digest.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_auth_digest.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_digest.so"
+ if exist .\Release\mod_auth_digest.so.manifest mt.exe -manifest .\Release\mod_auth_digest.so.manifest -outputresource:.\Release\mod_auth_digest.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_digest.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_digest.obj"
+ -@erase "$(INTDIR)\mod_auth_digest.res"
+ -@erase "$(INTDIR)\mod_auth_digest_src.idb"
+ -@erase "$(INTDIR)\mod_auth_digest_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_digest.exp"
+ -@erase "$(OUTDIR)\mod_auth_digest.lib"
+ -@erase "$(OUTDIR)\mod_auth_digest.pdb"
+ -@erase "$(OUTDIR)\mod_auth_digest.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_digest_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_digest.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_digest.pdb" /debug /out:"$(OUTDIR)\mod_auth_digest.so" /implib:"$(OUTDIR)\mod_auth_digest.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_digest.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_digest.obj" \
+ "$(INTDIR)\mod_auth_digest.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_digest.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_auth_digest.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_digest.so"
+ if exist .\Debug\mod_auth_digest.so.manifest mt.exe -manifest .\Debug\mod_auth_digest.so.manifest -outputresource:.\Debug\mod_auth_digest.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_auth_digest.dep")
+!INCLUDE "mod_auth_digest.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_auth_digest.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release" || "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_auth_digest - Win32 Release"
+
+
+"$(INTDIR)\mod_auth_digest.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_auth_digest - Win32 Debug"
+
+
+"$(INTDIR)\mod_auth_digest.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_digest.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_digest.so" /d LONG_NAME="auth_digest_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_auth_digest.c
+
+"$(INTDIR)\mod_auth_digest.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_auth_form.c b/modules/aaa/mod_auth_form.c
new file mode 100644
index 0000000..bea7d51
--- /dev/null
+++ b/modules/aaa/mod_auth_form.c
@@ -0,0 +1,1333 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_lib.h" /* for apr_isspace */
+#include "apr_base64.h" /* for apr_base64_decode et al */
+#define APR_WANT_STRFUNC /* for strcasecmp */
+#include "apr_want.h"
+
+#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 "ap_provider.h"
+#include "util_md5.h"
+#include "ap_expr.h"
+
+#include "mod_auth.h"
+#include "mod_session.h"
+#include "mod_request.h"
+
+#define FORM_LOGIN_HANDLER "form-login-handler"
+#define FORM_LOGOUT_HANDLER "form-logout-handler"
+#define FORM_REDIRECT_HANDLER "form-redirect-handler"
+#define MOD_AUTH_FORM_HASH "site"
+
+static int (*ap_session_load_fn) (request_rec * r, session_rec ** z) = NULL;
+static apr_status_t (*ap_session_get_fn)(request_rec * r, session_rec * z,
+ const char *key, const char **value) = NULL;
+static apr_status_t (*ap_session_set_fn)(request_rec * r, session_rec * z,
+ const char *key, const char *value) = NULL;
+static void (*ap_request_insert_filter_fn) (request_rec * r) = NULL;
+static void (*ap_request_remove_filter_fn) (request_rec * r) = NULL;
+
+typedef struct {
+ authn_provider_list *providers;
+ char *dir;
+ int authoritative;
+ int authoritative_set;
+ const char *site;
+ int site_set;
+ const char *username;
+ int username_set;
+ const char *password;
+ int password_set;
+ apr_size_t form_size;
+ int form_size_set;
+ int fakebasicauth;
+ int fakebasicauth_set;
+ const char *location;
+ int location_set;
+ const char *method;
+ int method_set;
+ const char *mimetype;
+ int mimetype_set;
+ const char *body;
+ int body_set;
+ int disable_no_store;
+ int disable_no_store_set;
+ ap_expr_info_t *loginsuccess;
+ int loginsuccess_set;
+ ap_expr_info_t *loginrequired;
+ int loginrequired_set;
+ ap_expr_info_t *logout;
+ int logout_set;
+} auth_form_config_rec;
+
+static void *create_auth_form_dir_config(apr_pool_t * p, char *d)
+{
+ auth_form_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
+
+ conf->dir = d;
+ /* Any failures are fatal. */
+ conf->authoritative = 1;
+
+ /* form size defaults to 8k */
+ conf->form_size = HUGE_STRING_LEN;
+
+ /* default form field names */
+ conf->username = "httpd_username";
+ conf->password = "httpd_password";
+ conf->location = "httpd_location";
+ conf->method = "httpd_method";
+ conf->mimetype = "httpd_mimetype";
+ conf->body = "httpd_body";
+
+ return conf;
+}
+
+static void *merge_auth_form_dir_config(apr_pool_t * p, void *basev, void *addv)
+{
+ auth_form_config_rec *new = (auth_form_config_rec *) apr_pcalloc(p, sizeof(auth_form_config_rec));
+ auth_form_config_rec *add = (auth_form_config_rec *) addv;
+ auth_form_config_rec *base = (auth_form_config_rec *) basev;
+
+ new->providers = !add->providers ? base->providers : add->providers;
+ new->authoritative = (add->authoritative_set == 0) ? base->authoritative : add->authoritative;
+ new->authoritative_set = add->authoritative_set || base->authoritative_set;
+ new->site = (add->site_set == 0) ? base->site : add->site;
+ new->site_set = add->site_set || base->site_set;
+ new->username = (add->username_set == 0) ? base->username : add->username;
+ new->username_set = add->username_set || base->username_set;
+ new->password = (add->password_set == 0) ? base->password : add->password;
+ new->password_set = add->password_set || base->password_set;
+ new->location = (add->location_set == 0) ? base->location : add->location;
+ new->location_set = add->location_set || base->location_set;
+ new->form_size = (add->form_size_set == 0) ? base->form_size : add->form_size;
+ new->form_size_set = add->form_size_set || base->form_size_set;
+ new->fakebasicauth = (add->fakebasicauth_set == 0) ? base->fakebasicauth : add->fakebasicauth;
+ new->fakebasicauth_set = add->fakebasicauth_set || base->fakebasicauth_set;
+ new->method = (add->method_set == 0) ? base->method : add->method;
+ new->method_set = add->method_set || base->method_set;
+ new->mimetype = (add->mimetype_set == 0) ? base->mimetype : add->mimetype;
+ new->mimetype_set = add->mimetype_set || base->mimetype_set;
+ new->body = (add->body_set == 0) ? base->body : add->body;
+ new->body_set = add->body_set || base->body_set;
+ new->disable_no_store = (add->disable_no_store_set == 0) ? base->disable_no_store : add->disable_no_store;
+ new->disable_no_store_set = add->disable_no_store_set || base->disable_no_store_set;
+ new->loginsuccess = (add->loginsuccess_set == 0) ? base->loginsuccess : add->loginsuccess;
+ new->loginsuccess_set = add->loginsuccess_set || base->loginsuccess_set;
+ new->loginrequired = (add->loginrequired_set == 0) ? base->loginrequired : add->loginrequired;
+ new->loginrequired_set = add->loginrequired_set || base->loginrequired_set;
+ new->logout = (add->logout_set == 0) ? base->logout : add->logout;
+ new->logout_set = add->logout_set || base->logout_set;
+
+ return new;
+}
+
+static const char *add_authn_provider(cmd_parms * cmd, void *config,
+ const char *arg)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ authn_provider_list *newp;
+
+ newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
+ newp->provider_name = arg;
+
+ /* lookup and cache the actual provider now */
+ newp->provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ newp->provider_name,
+ AUTHN_PROVIDER_VERSION);
+
+ if (newp->provider == NULL) {
+ /*
+ * by the time they use it, the provider should be loaded and
+ * registered with us.
+ */
+ return apr_psprintf(cmd->pool,
+ "Unknown Authn provider: %s",
+ newp->provider_name);
+ }
+
+ if (!newp->provider->check_password) {
+ /* if it doesn't provide the appropriate function, reject it */
+ return apr_psprintf(cmd->pool,
+ "The '%s' Authn provider doesn't support "
+ "Form Authentication", newp->provider_name);
+ }
+
+ /* Add it to the list now. */
+ if (!conf->providers) {
+ conf->providers = newp;
+ }
+ else {
+ authn_provider_list *last = conf->providers;
+
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = newp;
+ }
+
+ return NULL;
+}
+
+/**
+ * Sanity check a given string that it exists, is not empty,
+ * and does not contain special characters.
+ */
+static const char *check_string(cmd_parms * cmd, const char *string)
+{
+ if (!string || !*string || ap_strchr_c(string, '=') || ap_strchr_c(string, '&')) {
+ return apr_pstrcat(cmd->pool, cmd->directive->directive,
+ " cannot be empty, or contain '=' or '&'.",
+ NULL);
+ }
+ return NULL;
+}
+
+static const char *set_cookie_form_location(cmd_parms * cmd, void *config, const char *location)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->location = location;
+ conf->location_set = 1;
+ return check_string(cmd, location);
+}
+
+static const char *set_cookie_form_username(cmd_parms * cmd, void *config, const char *username)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->username = username;
+ conf->username_set = 1;
+ return check_string(cmd, username);
+}
+
+static const char *set_cookie_form_password(cmd_parms * cmd, void *config, const char *password)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->password = password;
+ conf->password_set = 1;
+ return check_string(cmd, password);
+}
+
+static const char *set_cookie_form_method(cmd_parms * cmd, void *config, const char *method)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->method = method;
+ conf->method_set = 1;
+ return check_string(cmd, method);
+}
+
+static const char *set_cookie_form_mimetype(cmd_parms * cmd, void *config, const char *mimetype)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->mimetype = mimetype;
+ conf->mimetype_set = 1;
+ return check_string(cmd, mimetype);
+}
+
+static const char *set_cookie_form_body(cmd_parms * cmd, void *config, const char *body)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->body = body;
+ conf->body_set = 1;
+ return check_string(cmd, body);
+}
+
+static const char *set_cookie_form_size(cmd_parms * cmd, void *config,
+ const char *arg)
+{
+ auth_form_config_rec *conf = config;
+ apr_off_t size;
+
+ if (APR_SUCCESS != apr_strtoff(&size, arg, NULL, 10)
+ || size < 0 || size > APR_SIZE_MAX) {
+ return "AuthCookieFormSize must be a size in bytes, or zero.";
+ }
+ conf->form_size = (apr_size_t)size;
+ conf->form_size_set = 1;
+
+ return NULL;
+}
+
+static const char *set_login_required_location(cmd_parms * cmd, void *config, const char *loginrequired)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ const char *err;
+
+ conf->loginrequired = ap_expr_parse_cmd(cmd, loginrequired, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse login required expression '%s': %s",
+ loginrequired, err);
+ }
+ conf->loginrequired_set = 1;
+
+ return NULL;
+}
+
+static const char *set_login_success_location(cmd_parms * cmd, void *config, const char *loginsuccess)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ const char *err;
+
+ conf->loginsuccess = ap_expr_parse_cmd(cmd, loginsuccess, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse login success expression '%s': %s",
+ loginsuccess, err);
+ }
+ conf->loginsuccess_set = 1;
+
+ return NULL;
+}
+
+static const char *set_logout_location(cmd_parms * cmd, void *config, const char *logout)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ const char *err;
+
+ conf->logout = ap_expr_parse_cmd(cmd, logout, AP_EXPR_FLAG_STRING_RESULT,
+ &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool,
+ "Could not parse logout required expression '%s': %s",
+ logout, err);
+ }
+ conf->logout_set = 1;
+
+ return NULL;
+}
+
+static const char *set_site_passphrase(cmd_parms * cmd, void *config, const char *site)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->site = site;
+ conf->site_set = 1;
+ return NULL;
+}
+
+static const char *set_authoritative(cmd_parms * cmd, void *config, int flag)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->authoritative = flag;
+ conf->authoritative_set = 1;
+ return NULL;
+}
+
+static const char *set_fake_basic_auth(cmd_parms * cmd, void *config, int flag)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->fakebasicauth = flag;
+ conf->fakebasicauth_set = 1;
+ return NULL;
+}
+
+static const char *set_disable_no_store(cmd_parms * cmd, void *config, int flag)
+{
+ auth_form_config_rec *conf = (auth_form_config_rec *) config;
+ conf->disable_no_store = flag;
+ conf->disable_no_store_set = 1;
+ return NULL;
+}
+
+static const command_rec auth_form_cmds[] =
+{
+ AP_INIT_ITERATE("AuthFormProvider", add_authn_provider, NULL, OR_AUTHCFG,
+ "specify the auth providers for a directory or location"),
+ AP_INIT_TAKE1("AuthFormUsername", set_cookie_form_username, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the username"),
+ AP_INIT_TAKE1("AuthFormPassword", set_cookie_form_password, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the password"),
+ AP_INIT_TAKE1("AuthFormLocation", set_cookie_form_location, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the URL to redirect on "
+ "successful login."),
+ AP_INIT_TAKE1("AuthFormMethod", set_cookie_form_method, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the original request method."),
+ AP_INIT_TAKE1("AuthFormMimetype", set_cookie_form_mimetype, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the original request mimetype."),
+ AP_INIT_TAKE1("AuthFormBody", set_cookie_form_body, NULL, OR_AUTHCFG,
+ "The field of the login form carrying the urlencoded original request "
+ "body."),
+ AP_INIT_TAKE1("AuthFormSize", set_cookie_form_size, NULL, ACCESS_CONF,
+ "Maximum size of body parsed by the form parser"),
+ AP_INIT_TAKE1("AuthFormLoginRequiredLocation", set_login_required_location,
+ NULL, OR_AUTHCFG,
+ "If set, redirect the browser to this URL rather than "
+ "return 401 Not Authorized."),
+ AP_INIT_TAKE1("AuthFormLoginSuccessLocation", set_login_success_location,
+ NULL, OR_AUTHCFG,
+ "If set, redirect the browser to this URL when a login "
+ "processed by the login handler is successful."),
+ AP_INIT_TAKE1("AuthFormLogoutLocation", set_logout_location,
+ NULL, OR_AUTHCFG,
+ "The URL of the logout successful page. An attempt to access an "
+ "URL handled by the handler " FORM_LOGOUT_HANDLER " will result "
+ "in an redirect to this page after logout."),
+ AP_INIT_TAKE1("AuthFormSitePassphrase", set_site_passphrase,
+ NULL, OR_AUTHCFG,
+ "If set, use this passphrase to determine whether the user should "
+ "be authenticated. Bypasses the user authentication check on "
+ "every website hit, and is useful for high traffic sites."),
+ AP_INIT_FLAG("AuthFormAuthoritative", set_authoritative,
+ NULL, OR_AUTHCFG,
+ "Set to 'Off' to allow access control to be passed along to "
+ "lower modules if the UserID is not known to this module"),
+ AP_INIT_FLAG("AuthFormFakeBasicAuth", set_fake_basic_auth,
+ NULL, OR_AUTHCFG,
+ "Set to 'On' to pass through authentication to the rest of the "
+ "server as a basic authentication header."),
+ AP_INIT_FLAG("AuthFormDisableNoStore", set_disable_no_store,
+ NULL, OR_AUTHCFG,
+ "Set to 'on' to stop the sending of a Cache-Control no-store header with "
+ "the login screen. This allows the browser to cache the credentials, but "
+ "at the risk of it being possible for the login form to be resubmitted "
+ "and revealed to the backend server through XSS. Use at own risk."),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA auth_form_module;
+
+static void note_cookie_auth_failure(request_rec * r)
+{
+ auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_form_module);
+
+ if (conf->location && ap_strchr_c(conf->location, ':')) {
+ apr_table_setn(r->err_headers_out, "Location", conf->location);
+ }
+}
+
+static int hook_note_cookie_auth_failure(request_rec * r,
+ const char *auth_type)
+{
+ if (strcasecmp(auth_type, "form"))
+ return DECLINED;
+
+ note_cookie_auth_failure(r);
+ return OK;
+}
+
+/**
+ * Set the auth username and password into the main request
+ * notes table.
+ */
+static void set_notes_auth(request_rec * r,
+ const char *user, const char *pw,
+ const char *method, const char *mimetype)
+{
+ apr_table_t *notes = NULL;
+ const char *authname;
+
+ /* find the main request */
+ while (r->main) {
+ r = r->main;
+ }
+ /* find the first redirect */
+ while (r->prev) {
+ r = r->prev;
+ }
+ notes = r->notes;
+
+ /* have we isolated the user and pw before? */
+ authname = ap_auth_name(r);
+ if (user) {
+ apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-user", NULL), user);
+ }
+ if (pw) {
+ apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-pw", NULL), pw);
+ }
+ if (method) {
+ apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-method", NULL), method);
+ }
+ if (mimetype) {
+ apr_table_setn(notes, apr_pstrcat(r->pool, authname, "-mimetype", NULL), mimetype);
+ }
+
+}
+
+/**
+ * Get the auth username and password from the main request
+ * notes table, if present.
+ */
+static void get_notes_auth(request_rec *r,
+ const char **user, const char **pw,
+ const char **method, const char **mimetype)
+{
+ const char *authname;
+ request_rec *m = r;
+
+ /* find the main request */
+ while (m->main) {
+ m = m->main;
+ }
+ /* find the first redirect */
+ while (m->prev) {
+ m = m->prev;
+ }
+
+ /* have we isolated the user and pw before? */
+ authname = ap_auth_name(m);
+ if (user) {
+ *user = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-user", NULL));
+ }
+ if (pw) {
+ *pw = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-pw", NULL));
+ }
+ if (method) {
+ *method = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-method", NULL));
+ }
+ if (mimetype) {
+ *mimetype = (char *) apr_table_get(m->notes, apr_pstrcat(m->pool, authname, "-mimetype", NULL));
+ }
+
+ /* set the user, even though the user is unauthenticated at this point */
+ if (user && *user) {
+ r->user = (char *) *user;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "from notes: user: %s, pw: %s, method: %s, mimetype: %s",
+ user ? *user : "<null>", pw ? *pw : "<null>",
+ method ? *method : "<null>", mimetype ? *mimetype : "<null>");
+
+}
+
+/**
+ * Set the auth username and password into the session.
+ *
+ * If either the username, or the password are NULL, the username
+ * and/or password will be removed from the session.
+ */
+static apr_status_t set_session_auth(request_rec * r,
+ const char *user, const char *pw, const char *site)
+{
+ const char *hash = NULL;
+ const char *authname = ap_auth_name(r);
+ session_rec *z = NULL;
+
+ if (site) {
+ hash = ap_md5(r->pool,
+ (unsigned char *) apr_pstrcat(r->pool, user, ":", site, NULL));
+ }
+
+ ap_session_load_fn(r, &z);
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_USER, NULL), user);
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Get the auth username and password from the main request
+ * notes table, if present.
+ */
+static apr_status_t get_session_auth(request_rec * r,
+ const char **user, const char **pw, const char **hash)
+{
+ const char *authname = ap_auth_name(r);
+ session_rec *z = NULL;
+
+ ap_session_load_fn(r, &z);
+
+ if (user) {
+ ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_USER, NULL), user);
+ }
+ if (pw) {
+ ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_SESSION_PW, NULL), pw);
+ }
+ if (hash) {
+ ap_session_get_fn(r, z, apr_pstrcat(r->pool, authname, "-" MOD_AUTH_FORM_HASH, NULL), hash);
+ }
+
+ /* set the user, even though the user is unauthenticated at this point */
+ if (user && *user) {
+ r->user = (char *) *user;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "from session: " MOD_SESSION_USER ": %s, " MOD_SESSION_PW
+ ": %s, " MOD_AUTH_FORM_HASH ": %s",
+ user ? *user : "<null>", pw ? *pw : "<null>",
+ hash ? *hash : "<null>");
+
+ return APR_SUCCESS;
+
+}
+
+/**
+ * Isolate the username and password in a POSTed form with the
+ * username in the "username" field, and the password in the
+ * "password" field.
+ *
+ * If either the username or the password is missing, this
+ * function will return HTTP_UNAUTHORIZED.
+ *
+ * The location field is considered optional, and will be returned
+ * if present.
+ */
+static int get_form_auth(request_rec * r,
+ const char *username,
+ const char *password,
+ const char *location,
+ const char *method,
+ const char *mimetype,
+ const char *body,
+ const char **sent_user,
+ const char **sent_pw,
+ const char **sent_loc,
+ const char **sent_method,
+ const char **sent_mimetype,
+ apr_bucket_brigade **sent_body,
+ auth_form_config_rec * conf)
+{
+ /* sanity check - are we a POST request? */
+
+ /* find the username and password in the form */
+ apr_array_header_t *pairs = NULL;
+ apr_off_t len;
+ apr_size_t size;
+ int res;
+ char *buffer;
+
+ /* have we isolated the user and pw before? */
+ get_notes_auth(r, sent_user, sent_pw, sent_method, sent_mimetype);
+ if (sent_user && *sent_user && sent_pw && *sent_pw) {
+ return OK;
+ }
+
+ res = ap_parse_form_data(r, NULL, &pairs, -1, conf->form_size);
+ if (res != OK) {
+ return res;
+ }
+ while (pairs && !apr_is_empty_array(pairs)) {
+ ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
+ if (username && !strcmp(pair->name, username) && sent_user) {
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ *sent_user = buffer;
+ }
+ else if (password && !strcmp(pair->name, password) && sent_pw) {
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ *sent_pw = buffer;
+ }
+ else if (location && !strcmp(pair->name, location) && sent_loc) {
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ *sent_loc = buffer;
+ }
+ else if (method && !strcmp(pair->name, method) && sent_method) {
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ *sent_method = buffer;
+ }
+ else if (mimetype && !strcmp(pair->name, mimetype) && sent_mimetype) {
+ apr_brigade_length(pair->value, 1, &len);
+ size = (apr_size_t) len;
+ buffer = apr_palloc(r->pool, size + 1);
+ apr_brigade_flatten(pair->value, buffer, &size);
+ buffer[len] = 0;
+ *sent_mimetype = buffer;
+ }
+ else if (body && !strcmp(pair->name, body) && sent_body) {
+ *sent_body = pair->value;
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "from form: user: %s, pw: %s, method: %s, mimetype: %s, location: %s",
+ sent_user ? *sent_user : "<null>", sent_pw ? *sent_pw : "<null>",
+ sent_method ? *sent_method : "<null>",
+ sent_mimetype ? *sent_mimetype : "<null>",
+ sent_loc ? *sent_loc : "<null>");
+
+ /* set the user, even though the user is unauthenticated at this point */
+ if (sent_user && *sent_user) {
+ r->user = (char *) *sent_user;
+ }
+
+ /* a missing username or missing password means auth denied */
+ if (!sent_user || !*sent_user) {
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02982)
+ "form parsed, but username field '%s' was missing or empty, unauthorized",
+ username);
+
+ return HTTP_UNAUTHORIZED;
+ }
+ if (!sent_pw || !*sent_pw) {
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02983)
+ "form parsed, but password field '%s' was missing or empty, unauthorized",
+ password);
+
+ return HTTP_UNAUTHORIZED;
+ }
+
+ /*
+ * save away the username, password, mimetype and method, so that they
+ * are available should the auth need to be run again.
+ */
+ set_notes_auth(r, *sent_user, *sent_pw, sent_method ? *sent_method : NULL,
+ sent_mimetype ? *sent_mimetype : NULL);
+
+ return OK;
+}
+
+/* These functions return 0 if client is OK, and proper error status
+ * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
+ * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
+ * couldn't figure out how to tell if the client is authorized or not.
+ *
+ * If they return DECLINED, and all other modules also decline, that's
+ * treated by the server core as a configuration error, logged and
+ * reported as such.
+ */
+
+
+/**
+ * Given a username and site passphrase hash from the session, determine
+ * whether the site passphrase is valid for this session.
+ *
+ * If the site passphrase is NULL, or if the sent_hash is NULL, this
+ * function returns DECLINED.
+ *
+ * If the site passphrase hash does not match the sent hash, this function
+ * returns AUTH_USER_NOT_FOUND.
+ *
+ * On success, returns OK.
+ */
+static int check_site(request_rec * r, const char *site, const char *sent_user, const char *sent_hash)
+{
+
+ if (site && sent_user && sent_hash) {
+ const char *hash = ap_md5(r->pool,
+ (unsigned char *) apr_pstrcat(r->pool, sent_user, ":", site, NULL));
+
+ if (!strcmp(sent_hash, hash)) {
+ return OK;
+ }
+ else {
+ return AUTH_USER_NOT_FOUND;
+ }
+ }
+
+ return DECLINED;
+
+}
+
+/**
+ * Given a username and password (extracted externally from a cookie), run
+ * the authnz hooks to determine whether this request is authorized.
+ *
+ * Return an HTTP code.
+ */
+static int check_authn(request_rec * r, const char *sent_user, const char *sent_pw)
+{
+ authn_status auth_result;
+ authn_provider_list *current_provider;
+ auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_form_module);
+
+ current_provider = conf->providers;
+ do {
+ const authn_provider *provider;
+
+ /*
+ * For now, if a provider isn't set, we'll be nice and use the file
+ * provider.
+ */
+ if (!current_provider) {
+ provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP,
+ AUTHN_DEFAULT_PROVIDER,
+ AUTHN_PROVIDER_VERSION);
+
+ if (!provider || !provider->check_password) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01806)
+ "no authn provider configured");
+ auth_result = AUTH_GENERAL_ERROR;
+ break;
+ }
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, AUTHN_DEFAULT_PROVIDER);
+ }
+ else {
+ provider = current_provider->provider;
+ apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, current_provider->provider_name);
+ }
+
+ if (!sent_user || !sent_pw) {
+ auth_result = AUTH_USER_NOT_FOUND;
+ break;
+ }
+
+ auth_result = provider->check_password(r, sent_user, sent_pw);
+
+ apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+
+ /* Something occurred. Stop checking. */
+ if (auth_result != AUTH_USER_NOT_FOUND) {
+ break;
+ }
+
+ /* If we're not really configured for providers, stop now. */
+ if (!conf->providers) {
+ break;
+ }
+
+ current_provider = current_provider->next;
+ } while (current_provider);
+
+ if (auth_result != AUTH_GRANTED) {
+ int return_code;
+
+ /* If we're not authoritative, then any error is ignored. */
+ if (!(conf->authoritative) && auth_result != AUTH_DENIED) {
+ return DECLINED;
+ }
+
+ switch (auth_result) {
+ case AUTH_DENIED:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01807)
+ "user '%s': authentication failure for \"%s\": "
+ "password Mismatch",
+ sent_user, r->uri);
+ return_code = HTTP_UNAUTHORIZED;
+ break;
+ case AUTH_USER_NOT_FOUND:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01808)
+ "user '%s' not found: %s", sent_user, r->uri);
+ return_code = HTTP_UNAUTHORIZED;
+ break;
+ case AUTH_GENERAL_ERROR:
+ default:
+ /*
+ * We'll assume that the module has already said what its error
+ * was in the logs.
+ */
+ return_code = HTTP_INTERNAL_SERVER_ERROR;
+ break;
+ }
+
+ /* If we're returning 401, tell them to try again. */
+ if (return_code == HTTP_UNAUTHORIZED) {
+ note_cookie_auth_failure(r);
+ }
+
+/* TODO: Flag the user somehow as to the reason for the failure */
+
+ return return_code;
+ }
+
+ return OK;
+
+}
+
+/* fake the basic authentication header if configured to do so */
+static void fake_basic_authentication(request_rec *r, auth_form_config_rec *conf,
+ const char *user, const char *pw)
+{
+ if (conf->fakebasicauth) {
+ char *basic = apr_pstrcat(r->pool, user, ":", pw, NULL);
+ apr_size_t size = (apr_size_t) strlen(basic);
+ char *base64 = apr_palloc(r->pool,
+ apr_base64_encode_len(size + 1) * sizeof(char));
+ apr_base64_encode(base64, basic, size);
+ apr_table_setn(r->headers_in, "Authorization",
+ apr_pstrcat(r->pool, "Basic ", base64, NULL));
+ }
+}
+
+/**
+ * Must we use form authentication? If so, extract the cookie and run
+ * the authnz hooks to determine if the login is valid.
+ *
+ * If the login is not valid, a 401 Not Authorized will be returned. It
+ * is up to the webmaster to ensure this screen displays a suitable login
+ * form to give the user the opportunity to log in.
+ */
+static int authenticate_form_authn(request_rec * r)
+{
+ auth_form_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &auth_form_module);
+ const char *sent_user = NULL, *sent_pw = NULL, *sent_hash = NULL;
+ const char *sent_loc = NULL, *sent_method = "GET", *sent_mimetype = NULL;
+ const char *current_auth = NULL;
+ const char *err;
+ apr_status_t res;
+ int rv = HTTP_UNAUTHORIZED;
+
+ /* Are we configured to be Form auth? */
+ current_auth = ap_auth_type(r);
+ if (!current_auth || strcasecmp(current_auth, "form")) {
+ return DECLINED;
+ }
+
+ /*
+ * XSS security warning: using cookies to store private data only works
+ * when the administrator has full control over the source website. When
+ * in forward-proxy mode, websites are public by definition, and so can
+ * never be secure. Abort the auth attempt in this case.
+ */
+ if (PROXYREQ_PROXY == r->proxyreq) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01809)
+ "form auth cannot be used for proxy "
+ "requests due to XSS risk, access denied: %s", r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ /* We need an authentication realm. */
+ if (!ap_auth_name(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01810)
+ "need AuthName: %s", r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ r->ap_auth_type = (char *) current_auth;
+
+ /* try get the username and password from the notes, if present */
+ get_notes_auth(r, &sent_user, &sent_pw, &sent_method, &sent_mimetype);
+ if (!sent_user || !sent_pw || !*sent_user || !*sent_pw) {
+
+ /* otherwise try get the username and password from a session, if present */
+ res = get_session_auth(r, &sent_user, &sent_pw, &sent_hash);
+
+ }
+ else {
+ res = APR_SUCCESS;
+ }
+
+ /* first test whether the site passphrase matches */
+ if (APR_SUCCESS == res && sent_user && sent_hash && sent_pw) {
+ rv = check_site(r, conf->site, sent_user, sent_hash);
+ if (OK == rv) {
+ fake_basic_authentication(r, conf, sent_user, sent_pw);
+ return OK;
+ }
+ }
+
+ /* otherwise test for a normal password match */
+ if (APR_SUCCESS == res && sent_user && sent_pw) {
+ rv = check_authn(r, sent_user, sent_pw);
+ if (OK == rv) {
+ fake_basic_authentication(r, conf, sent_user, sent_pw);
+ return OK;
+ }
+ }
+
+ /*
+ * If we reach this point, the request should fail with access denied,
+ * except for one potential scenario:
+ *
+ * If the request is a POST, and the posted form contains user defined fields
+ * for a username and a password, and the username and password are correct,
+ * then return the response obtained by a GET to this URL.
+ *
+ * If an additional user defined location field is present in the form,
+ * instead of a GET of the current URL, redirect the browser to the new
+ * location.
+ *
+ * As a further option, if the user defined fields for the type of request,
+ * the mime type of the body of the request, and the body of the request
+ * itself are present, replace this request with a new request of the given
+ * type and with the given body.
+ *
+ * Otherwise access is denied.
+ *
+ * Reading the body requires some song and dance, because the input filters
+ * are not yet configured. To work around this problem, we create a
+ * subrequest and use that to create a sane filter stack we can read the
+ * form from.
+ *
+ * The main request is then capped with a kept_body input filter, which has
+ * the effect of guaranteeing the input stack can be safely read a second time.
+ *
+ */
+ if (HTTP_UNAUTHORIZED == rv && r->method_number == M_POST && ap_is_initial_req(r)) {
+ request_rec *rr;
+ apr_bucket_brigade *sent_body = NULL;
+
+ /* create a subrequest of our current uri */
+ rr = ap_sub_req_lookup_uri(r->uri, r, r->input_filters);
+ rr->headers_in = r->headers_in;
+
+ /* run the insert_filters hook on the subrequest to ensure a body read can
+ * be done properly.
+ */
+ ap_run_insert_filter(rr);
+
+ /* parse the form by reading the subrequest */
+ rv = get_form_auth(rr, conf->username, conf->password, conf->location,
+ conf->method, conf->mimetype, conf->body,
+ &sent_user, &sent_pw, &sent_loc, &sent_method,
+ &sent_mimetype, &sent_body, conf);
+
+ /* make sure any user detected within the subrequest is saved back to
+ * the main request.
+ */
+ r->user = apr_pstrdup(r->pool, rr->user);
+
+ /* we cannot clean up rr at this point, as memory allocated to rr is
+ * referenced from the main request. It will be cleaned up when the
+ * main request is cleaned up.
+ */
+
+ /* insert the kept_body filter on the main request to guarantee the
+ * input filter stack cannot be read a second time, optionally inject
+ * a saved body if one was specified in the login form.
+ */
+ if (sent_body && sent_mimetype) {
+ apr_table_set(r->headers_in, "Content-Type", sent_mimetype);
+ r->kept_body = sent_body;
+ }
+ else {
+ r->kept_body = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+ }
+ ap_request_insert_filter_fn(r);
+
+ /* did the form ask to change the method? if so, switch in the redirect handler
+ * to relaunch this request as the subrequest with the new method. If the
+ * form didn't specify a method, the default value GET will force a redirect.
+ */
+ if (sent_method && strcmp(r->method, sent_method)) {
+ r->handler = FORM_REDIRECT_HANDLER;
+ }
+
+ /* check the authn in the main request, based on the username found */
+ if (OK == rv) {
+ rv = check_authn(r, sent_user, sent_pw);
+ if (OK == rv) {
+ fake_basic_authentication(r, conf, sent_user, sent_pw);
+ set_session_auth(r, sent_user, sent_pw, conf->site);
+ if (sent_loc) {
+ apr_table_set(r->headers_out, "Location", sent_loc);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ if (conf->loginsuccess) {
+ const char *loginsuccess = ap_expr_str_exec(r,
+ conf->loginsuccess, &err);
+ if (!err) {
+ apr_table_set(r->headers_out, "Location", loginsuccess);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02339)
+ "Can't evaluate login success expression: %s", err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ }
+ }
+
+ }
+
+ /*
+ * did the admin prefer to be redirected to the login page on failure
+ * instead?
+ */
+ if (HTTP_UNAUTHORIZED == rv && conf->loginrequired) {
+ const char *loginrequired = ap_expr_str_exec(r,
+ conf->loginrequired, &err);
+ if (!err) {
+ apr_table_set(r->headers_out, "Location", loginrequired);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02340)
+ "Can't evaluate login required expression: %s", err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ /* did the user ask to be redirected on login success? */
+ if (sent_loc) {
+ apr_table_set(r->headers_out, "Location", sent_loc);
+ rv = HTTP_MOVED_TEMPORARILY;
+ }
+
+
+ /*
+ * potential security issue: if we return a login to the browser, we must
+ * send a no-store to make sure a well behaved browser will not try and
+ * send the login details a second time if the back button is pressed.
+ *
+ * if the user has full control over the backend, the
+ * AuthCookieDisableNoStore can be used to turn this off.
+ */
+ if (HTTP_UNAUTHORIZED == rv && !conf->disable_no_store) {
+ apr_table_addn(r->headers_out, "Cache-Control", "no-store");
+ apr_table_addn(r->err_headers_out, "Cache-Control", "no-store");
+ }
+
+ return rv;
+
+}
+
+/**
+ * Handle a login attempt.
+ *
+ * If the login session is either missing or form authnz is unsuccessful, a
+ * 401 Not Authorized will be returned to the browser. The webmaster
+ * is expected to insert a login form into the 401 Not Authorized
+ * error screen.
+ *
+ * If the webmaster wishes, they can point the form submission at this
+ * handler, which will redirect the user to the correct page on success.
+ * On failure, the 401 Not Authorized error screen will be redisplayed,
+ * where the login attempt can be repeated.
+ *
+ */
+static int authenticate_form_login_handler(request_rec * r)
+{
+ auth_form_config_rec *conf;
+ const char *err;
+
+ const char *sent_user = NULL, *sent_pw = NULL, *sent_loc = NULL;
+ int rv;
+
+ if (strcmp(r->handler, FORM_LOGIN_HANDLER)) {
+ return DECLINED;
+ }
+
+ if (r->method_number != M_POST) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01811)
+ "the " FORM_LOGIN_HANDLER " only supports the POST method for %s",
+ r->uri);
+ return HTTP_METHOD_NOT_ALLOWED;
+ }
+
+ conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
+
+ rv = get_form_auth(r, conf->username, conf->password, conf->location,
+ NULL, NULL, NULL,
+ &sent_user, &sent_pw, &sent_loc,
+ NULL, NULL, NULL, conf);
+ if (OK == rv) {
+ rv = check_authn(r, sent_user, sent_pw);
+ if (OK == rv) {
+ set_session_auth(r, sent_user, sent_pw, conf->site);
+ if (sent_loc) {
+ apr_table_set(r->headers_out, "Location", sent_loc);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ if (conf->loginsuccess) {
+ const char *loginsuccess = ap_expr_str_exec(r,
+ conf->loginsuccess, &err);
+ if (!err) {
+ apr_table_set(r->headers_out, "Location", loginsuccess);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02341)
+ "Can't evaluate login success expression: %s", err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ return HTTP_OK;
+ }
+ }
+
+ /* did we prefer to be redirected to the login page on failure instead? */
+ if (HTTP_UNAUTHORIZED == rv && conf->loginrequired) {
+ const char *loginrequired = ap_expr_str_exec(r,
+ conf->loginrequired, &err);
+ if (!err) {
+ apr_table_set(r->headers_out, "Location", loginrequired);
+ return HTTP_MOVED_TEMPORARILY;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02342)
+ "Can't evaluate login required expression: %s", err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ return rv;
+
+}
+
+/**
+ * Handle a logout attempt.
+ *
+ * If an attempt is made to access this URL, any username and password
+ * embedded in the session is deleted.
+ *
+ * This has the effect of logging the person out.
+ *
+ * If a logout URI has been specified, this function will create an
+ * internal redirect to this page.
+ */
+static int authenticate_form_logout_handler(request_rec * r)
+{
+ auth_form_config_rec *conf;
+ const char *err;
+
+ if (strcmp(r->handler, FORM_LOGOUT_HANDLER)) {
+ return DECLINED;
+ }
+
+ conf = ap_get_module_config(r->per_dir_config, &auth_form_module);
+
+ /* remove the username and password, effectively logging the user out */
+ set_session_auth(r, NULL, NULL, NULL);
+
+ /*
+ * make sure the logout page is never cached - otherwise the logout won't
+ * work!
+ */
+ apr_table_addn(r->headers_out, "Cache-Control", "no-store");
+ apr_table_addn(r->err_headers_out, "Cache-Control", "no-store");
+
+ /* if set, internal redirect to the logout page */
+ if (conf->logout) {
+ const char *logout = ap_expr_str_exec(r,
+ conf->logout, &err);
+ if (!err) {
+ apr_table_addn(r->headers_out, "Location", logout);
+ return HTTP_TEMPORARY_REDIRECT;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02343)
+ "Can't evaluate logout expression: %s", err);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ return HTTP_OK;
+
+}
+
+/**
+ * Handle a redirect attempt.
+ *
+ * If during a form login, the method, mimetype and request body are
+ * specified, this handler will ensure that this request is included
+ * as an internal redirect.
+ *
+ */
+static int authenticate_form_redirect_handler(request_rec * r)
+{
+
+ request_rec *rr = NULL;
+ const char *sent_method = NULL, *sent_mimetype = NULL;
+
+ if (strcmp(r->handler, FORM_REDIRECT_HANDLER)) {
+ return DECLINED;
+ }
+
+ /* get the method and mimetype from the notes */
+ get_notes_auth(r, NULL, NULL, &sent_method, &sent_mimetype);
+
+ if (r->kept_body && sent_method && sent_mimetype) {
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01812)
+ "internal redirect to method '%s' and body mimetype '%s' for the "
+ "uri: %s", sent_method, sent_mimetype, r->uri);
+
+ rr = ap_sub_req_method_uri(sent_method, r->uri, r, r->output_filters);
+ r->status = ap_run_sub_req(rr);
+
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01813)
+ "internal redirect requested but one or all of method, mimetype or "
+ "body are NULL: %s", r->uri);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ /* return the underlying error, or OK on success */
+ return r->status == HTTP_OK || r->status == OK ? OK : r->status;
+
+}
+
+static int authenticate_form_post_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+
+ if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
+ ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
+ ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
+ ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
+ if (!ap_session_load_fn || !ap_session_get_fn || !ap_session_set_fn) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02617)
+ "You must load mod_session to enable the mod_auth_form "
+ "functions");
+ return !OK;
+ }
+ }
+
+ if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
+ ap_request_insert_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_insert_filter);
+ ap_request_remove_filter_fn = APR_RETRIEVE_OPTIONAL_FN(ap_request_remove_filter);
+ if (!ap_request_insert_filter_fn || !ap_request_remove_filter_fn) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(02618)
+ "You must load mod_request to enable the mod_auth_form "
+ "functions");
+ return !OK;
+ }
+ }
+
+ return OK;
+}
+
+static void register_hooks(apr_pool_t * p)
+{
+ ap_hook_post_config(authenticate_form_post_config,NULL,NULL,APR_HOOK_MIDDLE);
+
+#if AP_MODULE_MAGIC_AT_LEAST(20080403,1)
+ ap_hook_check_authn(authenticate_form_authn, NULL, NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
+#else
+ ap_hook_check_user_id(authenticate_form_authn, NULL, NULL, APR_HOOK_MIDDLE);
+#endif
+ ap_hook_handler(authenticate_form_login_handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(authenticate_form_logout_handler, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(authenticate_form_redirect_handler, NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_hook_note_auth_failure(hook_note_cookie_auth_failure, NULL, NULL,
+ APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(auth_form) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_auth_form_dir_config, /* dir config creater */
+ merge_auth_form_dir_config, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ auth_form_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_auth_form.dep b/modules/aaa/mod_auth_form.dep
new file mode 100644
index 0000000..190b2db
--- /dev/null
+++ b/modules/aaa/mod_auth_form.dep
@@ -0,0 +1,66 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_auth_form.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_auth_form.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\mod_request.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_md5.h"\
+ "..\..\srclib\apr-util\include\apr_base64.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_uuid.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ "..\session\mod_session.h"\
+
diff --git a/modules/aaa/mod_auth_form.dsp b/modules/aaa/mod_auth_form.dsp
new file mode 100644
index 0000000..f47c1a2
--- /dev/null
+++ b/modules/aaa/mod_auth_form.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_auth_form" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_auth_form - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_form.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_form.mak" CFG="mod_auth_form - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_form - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_form - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Release\mod_auth_form_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_auth_form.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fd"Debug\mod_auth_form_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_auth_form.so" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_auth_form.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_auth_form - Win32 Release"
+# Name "mod_auth_form - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_auth_form.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_auth_form.mak b/modules/aaa/mod_auth_form.mak
new file mode 100644
index 0000000..3c6c67a
--- /dev/null
+++ b/modules/aaa/mod_auth_form.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_auth_form.dsp
+!IF "$(CFG)" == ""
+CFG=mod_auth_form - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_auth_form - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_auth_form - Win32 Release" && "$(CFG)" != "mod_auth_form - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_auth_form.mak" CFG="mod_auth_form - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_auth_form - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_auth_form - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_form.obj"
+ -@erase "$(INTDIR)\mod_auth_form.res"
+ -@erase "$(INTDIR)\mod_auth_form_src.idb"
+ -@erase "$(INTDIR)\mod_auth_form_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_form.exp"
+ -@erase "$(OUTDIR)\mod_auth_form.lib"
+ -@erase "$(OUTDIR)\mod_auth_form.pdb"
+ -@erase "$(OUTDIR)\mod_auth_form.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_form_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_form.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_form.pdb" /debug /out:"$(OUTDIR)\mod_auth_form.so" /implib:"$(OUTDIR)\mod_auth_form.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_form.obj" \
+ "$(INTDIR)\mod_auth_form.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_form.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_auth_form.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_form.so"
+ if exist .\Release\mod_auth_form.so.manifest mt.exe -manifest .\Release\mod_auth_form.so.manifest -outputresource:.\Release\mod_auth_form.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_auth_form.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_auth_form.obj"
+ -@erase "$(INTDIR)\mod_auth_form.res"
+ -@erase "$(INTDIR)\mod_auth_form_src.idb"
+ -@erase "$(INTDIR)\mod_auth_form_src.pdb"
+ -@erase "$(OUTDIR)\mod_auth_form.exp"
+ -@erase "$(OUTDIR)\mod_auth_form.lib"
+ -@erase "$(OUTDIR)\mod_auth_form.pdb"
+ -@erase "$(OUTDIR)\mod_auth_form.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../session" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AAA_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_auth_form_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_auth_form.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_auth_form.pdb" /debug /out:"$(OUTDIR)\mod_auth_form.so" /implib:"$(OUTDIR)\mod_auth_form.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_auth_form.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_auth_form.obj" \
+ "$(INTDIR)\mod_auth_form.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_auth_form.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_auth_form.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_auth_form.so"
+ if exist .\Debug\mod_auth_form.so.manifest mt.exe -manifest .\Debug\mod_auth_form.so.manifest -outputresource:.\Debug\mod_auth_form.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_auth_form.dep")
+!INCLUDE "mod_auth_form.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_auth_form.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release" || "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_auth_form - Win32 Release"
+
+
+"$(INTDIR)\mod_auth_form.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_auth_form - Win32 Debug"
+
+
+"$(INTDIR)\mod_auth_form.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_auth_form.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_auth_form.so" /d LONG_NAME="auth_form_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_auth_form.c
+
+"$(INTDIR)\mod_auth_form.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_anon.c b/modules/aaa/mod_authn_anon.c
new file mode 100644
index 0000000..82559bc
--- /dev/null
+++ b/modules/aaa/mod_authn_anon.c
@@ -0,0 +1,215 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Adapted to allow anonymous logins, just like with Anon-FTP, when
+ * one gives the magic user name 'anonymous' and ones email address
+ * as the password.
+ *
+ * Just add the following tokes to your <directory> setup:
+ *
+ * Anonymous magic-userid [magic-userid]...
+ *
+ * Anonymous_MustGiveEmail [ on | off ] default = on
+ * Anonymous_LogEmail [ on | off ] default = on
+ * Anonymous_VerifyEmail [ on | off ] default = off
+ * Anonymous_NoUserId [ on | off ] default = off
+ *
+ * The magic user id is something like 'anonymous', it is NOT case sensitive.
+ *
+ * The MustGiveEmail flag can be used to force users to enter something
+ * in the password field (like an email address). Default is on.
+ *
+ * Furthermore the 'NoUserID' flag can be set to allow completely empty
+ * usernames in as well; this can be is convenient as a single return
+ * in broken GUIs like W95 is often given by the user. The Default is off.
+ *
+ * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx
+ *
+ */
+
+#include "apr_strings.h"
+
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_request.h"
+#include "http_protocol.h"
+
+#include "mod_auth.h"
+
+typedef struct anon_auth_user {
+ const char *user;
+ struct anon_auth_user *next;
+} anon_auth_user;
+
+typedef struct {
+ anon_auth_user *users;
+ int nouserid;
+ int logemail;
+ int verifyemail;
+ int mustemail;
+ int anyuserid;
+} authn_anon_config_rec;
+
+static void *create_authn_anon_dir_config(apr_pool_t *p, char *d)
+{
+ authn_anon_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ /* just to illustrate the defaults really. */
+ conf->users = NULL;
+
+ conf->nouserid = 0;
+ conf->anyuserid = 0;
+ conf->logemail = 1;
+ conf->verifyemail = 0;
+ conf->mustemail = 1;
+ return conf;
+}
+
+static const char *anon_set_string_slots(cmd_parms *cmd,
+ void *my_config, const char *arg)
+{
+ authn_anon_config_rec *conf = my_config;
+ anon_auth_user *first;
+
+ if (!*arg) {
+ return "Anonymous string cannot be empty, use Anonymous_NoUserId";
+ }
+
+ /* squeeze in a record */
+ if (!conf->anyuserid) {
+ if (!strcmp(arg, "*")) {
+ conf->anyuserid = 1;
+ }
+ else {
+ first = conf->users;
+ conf->users = apr_palloc(cmd->pool, sizeof(*conf->users));
+ conf->users->user = arg;
+ conf->users->next = first;
+ }
+ }
+
+ return NULL;
+}
+
+static const command_rec authn_anon_cmds[] =
+{
+ AP_INIT_ITERATE("Anonymous", anon_set_string_slots, NULL, OR_AUTHCFG,
+ "a space-separated list of user IDs"),
+ AP_INIT_FLAG("Anonymous_MustGiveEmail", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_anon_config_rec, mustemail),
+ OR_AUTHCFG, "Limited to 'on' or 'off'"),
+ AP_INIT_FLAG("Anonymous_NoUserId", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_anon_config_rec, nouserid),
+ OR_AUTHCFG, "Limited to 'on' or 'off'"),
+ AP_INIT_FLAG("Anonymous_VerifyEmail", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_anon_config_rec, verifyemail),
+ OR_AUTHCFG, "Limited to 'on' or 'off'"),
+ AP_INIT_FLAG("Anonymous_LogEmail", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_anon_config_rec, logemail),
+ OR_AUTHCFG, "Limited to 'on' or 'off'"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authn_anon_module;
+
+static authn_status check_anonymous(request_rec *r, const char *user,
+ const char *sent_pw)
+{
+ authn_anon_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authn_anon_module);
+ authn_status res = AUTH_USER_NOT_FOUND;
+
+ /* Ignore if we are not configured */
+ if (!conf->users && !conf->anyuserid) {
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ /* Do we allow an empty userID and/or is it the magic one
+ */
+ if (!*user) {
+ if (conf->nouserid) {
+ res = AUTH_USER_FOUND;
+ }
+ }
+ else if (conf->anyuserid) {
+ res = AUTH_USER_FOUND;
+ }
+ else {
+ anon_auth_user *p = conf->users;
+
+ while (p) {
+ if (!strcasecmp(user, p->user)) {
+ res = AUTH_USER_FOUND;
+ break;
+ }
+ p = p->next;
+ }
+ }
+
+ /* Now if the supplied user-ID was ok, grant access if:
+ * (a) no passwd was sent and no password and no verification
+ * were configured.
+ * (b) password was sent and no verification was configured
+ * (c) verification was configured and the password (sent or not)
+ * looks like an email address
+ */
+ if ( (res == AUTH_USER_FOUND)
+ && (!conf->mustemail || *sent_pw)
+ && ( !conf->verifyemail
+ || (ap_strchr_c(sent_pw, '@') && ap_strchr_c(sent_pw, '.'))))
+ {
+ if (conf->logemail && ap_is_initial_req(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r, APLOGNO(01672)
+ "Anonymous: Passwd <%s> Accepted",
+ sent_pw ? sent_pw : "\'none\'");
+ }
+
+ return AUTH_GRANTED;
+ }
+
+ return (res == AUTH_USER_NOT_FOUND ? res : AUTH_DENIED);
+}
+
+static const authn_provider authn_anon_provider =
+{
+ &check_anonymous,
+ NULL
+};
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "anon",
+ AUTHN_PROVIDER_VERSION,
+ &authn_anon_provider, AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authn_anon) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authn_anon_dir_config, /* dir config creater */
+ NULL, /* dir merger ensure strictness */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authn_anon_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authn_anon.dep b/modules/aaa/mod_authn_anon.dep
new file mode 100644
index 0000000..30bb436
--- /dev/null
+++ b/modules/aaa/mod_authn_anon.dep
@@ -0,0 +1,58 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_anon.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_anon.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_anon.dsp b/modules/aaa/mod_authn_anon.dsp
new file mode 100644
index 0000000..be88104
--- /dev/null
+++ b/modules/aaa/mod_authn_anon.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_anon" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_anon - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_anon.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_anon.mak" CFG="mod_authn_anon - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_anon - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_anon - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_anon_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_anon.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_anon_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_anon.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_anon.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_anon - Win32 Release"
+# Name "mod_authn_anon - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authn_anon.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_anon.mak b/modules/aaa/mod_authn_anon.mak
new file mode 100644
index 0000000..6ff9972
--- /dev/null
+++ b/modules/aaa/mod_authn_anon.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_anon.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_anon - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_anon - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_anon - Win32 Release" && "$(CFG)" != "mod_authn_anon - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_anon.mak" CFG="mod_authn_anon - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_anon - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_anon - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_anon.obj"
+ -@erase "$(INTDIR)\mod_authn_anon.res"
+ -@erase "$(INTDIR)\mod_authn_anon_src.idb"
+ -@erase "$(INTDIR)\mod_authn_anon_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_anon.exp"
+ -@erase "$(OUTDIR)\mod_authn_anon.lib"
+ -@erase "$(OUTDIR)\mod_authn_anon.pdb"
+ -@erase "$(OUTDIR)\mod_authn_anon.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_anon_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_anon.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_anon.pdb" /debug /out:"$(OUTDIR)\mod_authn_anon.so" /implib:"$(OUTDIR)\mod_authn_anon.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_anon.obj" \
+ "$(INTDIR)\mod_authn_anon.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_anon.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_anon.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_anon.so"
+ if exist .\Release\mod_authn_anon.so.manifest mt.exe -manifest .\Release\mod_authn_anon.so.manifest -outputresource:.\Release\mod_authn_anon.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_anon.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_anon.obj"
+ -@erase "$(INTDIR)\mod_authn_anon.res"
+ -@erase "$(INTDIR)\mod_authn_anon_src.idb"
+ -@erase "$(INTDIR)\mod_authn_anon_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_anon.exp"
+ -@erase "$(OUTDIR)\mod_authn_anon.lib"
+ -@erase "$(OUTDIR)\mod_authn_anon.pdb"
+ -@erase "$(OUTDIR)\mod_authn_anon.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_anon_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_anon.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_anon.pdb" /debug /out:"$(OUTDIR)\mod_authn_anon.so" /implib:"$(OUTDIR)\mod_authn_anon.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_anon.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_anon.obj" \
+ "$(INTDIR)\mod_authn_anon.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_anon.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_anon.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_anon.so"
+ if exist .\Debug\mod_authn_anon.so.manifest mt.exe -manifest .\Debug\mod_authn_anon.so.manifest -outputresource:.\Debug\mod_authn_anon.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_anon.dep")
+!INCLUDE "mod_authn_anon.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_anon.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release" || "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_anon - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_anon.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_anon - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_anon.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_anon.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_anon.so" /d LONG_NAME="authn_anon_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_anon.c
+
+"$(INTDIR)\mod_authn_anon.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_core.c b/modules/aaa/mod_authn_core.c
new file mode 100644
index 0000000..7af1265
--- /dev/null
+++ b/modules/aaa/mod_authn_core.c
@@ -0,0 +1,386 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Security options etc.
+ *
+ * Module derived from code originally written by Rob McCool
+ *
+ */
+
+#include "apr_strings.h"
+#include "apr_network_io.h"
+#define APR_WANT_STRFUNC
+#define APR_WANT_BYTEFUNC
+#include "apr_want.h"
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_request.h"
+#include "http_protocol.h"
+#include "ap_provider.h"
+
+#include "mod_auth.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+/* TODO List
+
+- Track down all of the references to r->ap_auth_type
+ and change them to ap_auth_type()
+- Remove ap_auth_type and ap_auth_name from the
+ request_rec
+
+*/
+
+typedef struct {
+ const char *ap_auth_type;
+ int auth_type_set;
+ const char *ap_auth_name;
+} authn_core_dir_conf;
+
+typedef struct provider_alias_rec {
+ char *provider_name;
+ char *provider_alias;
+ ap_conf_vector_t *sec_auth;
+ const authn_provider *provider;
+} provider_alias_rec;
+
+typedef struct authn_alias_srv_conf {
+ apr_hash_t *alias_rec;
+} authn_alias_srv_conf;
+
+
+module AP_MODULE_DECLARE_DATA authn_core_module;
+
+static void *create_authn_core_dir_config(apr_pool_t *p, char *dummy)
+{
+ authn_core_dir_conf *conf =
+ (authn_core_dir_conf *)apr_pcalloc(p, sizeof(authn_core_dir_conf));
+
+ return (void *)conf;
+}
+
+static void *merge_authn_core_dir_config(apr_pool_t *a, void *basev, void *newv)
+{
+ authn_core_dir_conf *base = (authn_core_dir_conf *)basev;
+ authn_core_dir_conf *new = (authn_core_dir_conf *)newv;
+ authn_core_dir_conf *conf =
+ (authn_core_dir_conf *)apr_pcalloc(a, sizeof(authn_core_dir_conf));
+
+ if (new->auth_type_set) {
+ conf->ap_auth_type = new->ap_auth_type;
+ conf->auth_type_set = 1;
+ }
+ else {
+ conf->ap_auth_type = base->ap_auth_type;
+ conf->auth_type_set = base->auth_type_set;
+ }
+
+ if (new->ap_auth_name) {
+ conf->ap_auth_name = new->ap_auth_name;
+ } else {
+ conf->ap_auth_name = base->ap_auth_name;
+ }
+
+ return (void*)conf;
+}
+
+static authn_status authn_alias_check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ /* Look up the provider alias in the alias list */
+ /* Get the dir_config and call ap_Merge_per_dir_configs() */
+ /* Call the real provider->check_password() function */
+ /* return the result of the above function call */
+
+ const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+ authn_status ret = AUTH_USER_NOT_FOUND;
+ authn_alias_srv_conf *authcfg =
+ (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config,
+ &authn_core_module);
+
+ if (provider_name) {
+ provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec,
+ provider_name, APR_HASH_KEY_STRING);
+ ap_conf_vector_t *orig_dir_config = r->per_dir_config;
+
+ /* If we found the alias provider in the list, then merge the directory
+ configurations and call the real provider */
+ if (prvdraliasrec) {
+ r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config,
+ prvdraliasrec->sec_auth);
+ ret = prvdraliasrec->provider->check_password(r,user,password);
+ r->per_dir_config = orig_dir_config;
+ }
+ }
+
+ return ret;
+}
+
+static authn_status authn_alias_get_realm_hash(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ /* Look up the provider alias in the alias list */
+ /* Get the dir_config and call ap_Merge_per_dir_configs() */
+ /* Call the real provider->get_realm_hash() function */
+ /* return the result of the above function call */
+
+ const char *provider_name = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+ authn_status ret = AUTH_USER_NOT_FOUND;
+ authn_alias_srv_conf *authcfg =
+ (authn_alias_srv_conf *)ap_get_module_config(r->server->module_config,
+ &authn_core_module);
+
+ if (provider_name) {
+ provider_alias_rec *prvdraliasrec = apr_hash_get(authcfg->alias_rec,
+ provider_name, APR_HASH_KEY_STRING);
+ ap_conf_vector_t *orig_dir_config = r->per_dir_config;
+
+ /* If we found the alias provider in the list, then merge the directory
+ configurations and call the real provider */
+ if (prvdraliasrec) {
+ r->per_dir_config = ap_merge_per_dir_configs(r->pool, orig_dir_config,
+ prvdraliasrec->sec_auth);
+ ret = prvdraliasrec->provider->get_realm_hash(r,user,realm,rethash);
+ r->per_dir_config = orig_dir_config;
+ }
+ }
+
+ return ret;
+}
+
+static void *create_authn_alias_svr_config(apr_pool_t *p, server_rec *s)
+{
+
+ authn_alias_srv_conf *authcfg;
+
+ authcfg = (authn_alias_srv_conf *) apr_pcalloc(p, sizeof(authn_alias_srv_conf));
+ authcfg->alias_rec = apr_hash_make(p);
+
+ return (void *) authcfg;
+}
+
+/* Only per-server directive we have is GLOBAL_ONLY */
+static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv)
+{
+ return basev;
+}
+
+static const authn_provider authn_alias_provider =
+{
+ &authn_alias_check_password,
+ &authn_alias_get_realm_hash,
+};
+
+static const authn_provider authn_alias_provider_nodigest =
+{
+ &authn_alias_check_password,
+ NULL,
+};
+
+static const char *authaliassection(cmd_parms *cmd, void *mconfig, const char *arg)
+{
+ const char *endp = ap_strrchr_c(arg, '>');
+ const char *args;
+ char *provider_alias;
+ char *provider_name;
+ int old_overrides = cmd->override;
+ const char *errmsg;
+ const authn_provider *provider = NULL;
+ ap_conf_vector_t *new_auth_config = ap_create_per_dir_config(cmd->pool);
+ authn_alias_srv_conf *authcfg =
+ (authn_alias_srv_conf *)ap_get_module_config(cmd->server->module_config,
+ &authn_core_module);
+
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
+
+ if (endp == NULL) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive missing closing '>'", NULL);
+ }
+
+ args = apr_pstrndup(cmd->temp_pool, arg, endp - arg);
+
+ if (!args[0]) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive requires additional arguments", NULL);
+ }
+
+ /* Pull the real provider name and the alias name from the block header */
+ provider_name = ap_getword_conf(cmd->pool, &args);
+ provider_alias = ap_getword_conf(cmd->pool, &args);
+
+ if (!provider_name[0] || !provider_alias[0]) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive requires additional arguments", NULL);
+ }
+
+ if (strcasecmp(provider_name, provider_alias) == 0) {
+ return apr_pstrcat(cmd->pool,
+ "The alias provider name must be different from the base provider name.", NULL);
+ }
+
+ /* Look up the alias provider to make sure that it hasn't already been registered. */
+ provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_alias,
+ AUTHN_PROVIDER_VERSION);
+ if (provider) {
+ return apr_pstrcat(cmd->pool, "The alias provider ", provider_alias,
+ " has already be registered previously as either a base provider or an alias provider.",
+ NULL);
+ }
+
+ /* walk the subsection configuration to get the per_dir config that we will
+ merge just before the real provider is called. */
+ cmd->override = OR_AUTHCFG | ACCESS_CONF;
+ errmsg = ap_walk_config(cmd->directive->first_child, cmd, new_auth_config);
+ cmd->override = old_overrides;
+
+ if (!errmsg) {
+ provider_alias_rec *prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(provider_alias_rec));
+ provider = ap_lookup_provider(AUTHN_PROVIDER_GROUP, provider_name,
+ AUTHN_PROVIDER_VERSION);
+
+ if (!provider) {
+ /* by the time they use it, the provider should be loaded and
+ registered with us. */
+ return apr_psprintf(cmd->pool,
+ "Unknown Authn provider: %s",
+ provider_name);
+ }
+
+ /* Save off the new directory config along with the original provider name
+ and function pointer data */
+ prvdraliasrec->sec_auth = new_auth_config;
+ prvdraliasrec->provider_name = provider_name;
+ prvdraliasrec->provider_alias = provider_alias;
+ prvdraliasrec->provider = provider;
+ apr_hash_set(authcfg->alias_rec, provider_alias, APR_HASH_KEY_STRING, prvdraliasrec);
+
+ /* Register the fake provider so that we get called first */
+ ap_register_auth_provider(cmd->pool, AUTHN_PROVIDER_GROUP,
+ provider_alias, AUTHN_PROVIDER_VERSION,
+ provider->get_realm_hash ?
+ &authn_alias_provider :
+ &authn_alias_provider_nodigest,
+ AP_AUTH_INTERNAL_PER_CONF);
+ }
+
+ return errmsg;
+}
+
+/*
+ * Load an authorisation realm into our location configuration, applying the
+ * usual rules that apply to realms.
+ */
+static const char *set_authname(cmd_parms *cmd, void *mconfig,
+ const char *word1)
+{
+ authn_core_dir_conf *aconfig = (authn_core_dir_conf *)mconfig;
+
+ aconfig->ap_auth_name = ap_escape_quotes(cmd->pool, word1);
+ return NULL;
+}
+
+static const char *set_authtype(cmd_parms *cmd, void *mconfig,
+ const char *word1)
+{
+ authn_core_dir_conf *aconfig = (authn_core_dir_conf *)mconfig;
+
+ aconfig->auth_type_set = 1;
+ aconfig->ap_auth_type = strcasecmp(word1, "None") ? word1 : NULL;
+
+ return NULL;
+}
+
+static const char *authn_ap_auth_type(request_rec *r)
+{
+ authn_core_dir_conf *conf;
+
+ conf = (authn_core_dir_conf *)ap_get_module_config(r->per_dir_config,
+ &authn_core_module);
+
+ return conf->ap_auth_type;
+}
+
+static const char *authn_ap_auth_name(request_rec *r)
+{
+ authn_core_dir_conf *conf;
+
+ conf = (authn_core_dir_conf *)ap_get_module_config(r->per_dir_config,
+ &authn_core_module);
+
+ return apr_pstrdup(r->pool, conf->ap_auth_name);
+}
+
+static const command_rec authn_cmds[] =
+{
+ AP_INIT_TAKE1("AuthType", set_authtype, NULL, OR_AUTHCFG,
+ "an HTTP authorization type (e.g., \"Basic\")"),
+ AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG,
+ "the authentication realm (e.g. \"Members Only\")"),
+ AP_INIT_RAW_ARGS("<AuthnProviderAlias", authaliassection, NULL, RSRC_CONF,
+ "container for grouping an authentication provider's "
+ "directives under a provider alias"),
+ {NULL}
+};
+
+static int authenticate_no_user(request_rec *r)
+{
+ /* if there isn't an AuthType, then assume that no authentication
+ is required so return OK */
+ if (!ap_auth_type(r)) {
+ return OK;
+ }
+
+ /* there's an AuthType configured, but no authentication module
+ * loaded to support it
+ */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01796)
+ "AuthType %s configured without corresponding module",
+ ap_auth_type(r));
+
+ return HTTP_INTERNAL_SERVER_ERROR;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ APR_REGISTER_OPTIONAL_FN(authn_ap_auth_type);
+ APR_REGISTER_OPTIONAL_FN(authn_ap_auth_name);
+
+ ap_hook_check_authn(authenticate_no_user, NULL, NULL, APR_HOOK_LAST,
+ AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authn_core) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authn_core_dir_config, /* dir config creater */
+ merge_authn_core_dir_config, /* dir merger --- default is to override */
+ create_authn_alias_svr_config, /* server config */
+ merge_authn_alias_svr_config, /* merge server config */
+ authn_cmds,
+ register_hooks /* register hooks */
+};
+
diff --git a/modules/aaa/mod_authn_core.dep b/modules/aaa/mod_authn_core.dep
new file mode 100644
index 0000000..18003b3
--- /dev/null
+++ b/modules/aaa/mod_authn_core.dep
@@ -0,0 +1,58 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_core.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_core.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_core.dsp b/modules/aaa/mod_authn_core.dsp
new file mode 100644
index 0000000..506c96e
--- /dev/null
+++ b/modules/aaa/mod_authn_core.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_core" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_core - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_core.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_core.mak" CFG="mod_authn_core - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_core_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_core_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_core - Win32 Release"
+# Name "mod_authn_core - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authn_core.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_core.mak b/modules/aaa/mod_authn_core.mak
new file mode 100644
index 0000000..ec88b2d
--- /dev/null
+++ b/modules/aaa/mod_authn_core.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_core.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_core - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_core - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_core - Win32 Release" && "$(CFG)" != "mod_authn_core - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_core.mak" CFG="mod_authn_core - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_core.obj"
+ -@erase "$(INTDIR)\mod_authn_core.res"
+ -@erase "$(INTDIR)\mod_authn_core_src.idb"
+ -@erase "$(INTDIR)\mod_authn_core_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_core.exp"
+ -@erase "$(OUTDIR)\mod_authn_core.lib"
+ -@erase "$(OUTDIR)\mod_authn_core.pdb"
+ -@erase "$(OUTDIR)\mod_authn_core.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_core_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_core.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_core.pdb" /debug /out:"$(OUTDIR)\mod_authn_core.so" /implib:"$(OUTDIR)\mod_authn_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_core.obj" \
+ "$(INTDIR)\mod_authn_core.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_core.so"
+ if exist .\Release\mod_authn_core.so.manifest mt.exe -manifest .\Release\mod_authn_core.so.manifest -outputresource:.\Release\mod_authn_core.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_core.obj"
+ -@erase "$(INTDIR)\mod_authn_core.res"
+ -@erase "$(INTDIR)\mod_authn_core_src.idb"
+ -@erase "$(INTDIR)\mod_authn_core_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_core.exp"
+ -@erase "$(OUTDIR)\mod_authn_core.lib"
+ -@erase "$(OUTDIR)\mod_authn_core.pdb"
+ -@erase "$(OUTDIR)\mod_authn_core.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_core_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_core.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_core.pdb" /debug /out:"$(OUTDIR)\mod_authn_core.so" /implib:"$(OUTDIR)\mod_authn_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_core.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_core.obj" \
+ "$(INTDIR)\mod_authn_core.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_core.so"
+ if exist .\Debug\mod_authn_core.so.manifest mt.exe -manifest .\Debug\mod_authn_core.so.manifest -outputresource:.\Debug\mod_authn_core.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_core.dep")
+!INCLUDE "mod_authn_core.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_core.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release" || "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_core - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_core.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_core - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_core.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_core.so" /d LONG_NAME="authn_core_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_core.c
+
+"$(INTDIR)\mod_authn_core.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_dbd.c b/modules/aaa/mod_authn_dbd.c
new file mode 100644
index 0000000..57090d2
--- /dev/null
+++ b/modules/aaa/mod_authn_dbd.c
@@ -0,0 +1,309 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "http_request.h"
+#include "apr_lib.h"
+#include "apr_dbd.h"
+#include "mod_dbd.h"
+#include "apr_strings.h"
+#include "mod_auth.h"
+#include "apr_md5.h"
+#include "apu_version.h"
+
+module AP_MODULE_DECLARE_DATA authn_dbd_module;
+
+typedef struct {
+ const char *user;
+ const char *realm;
+} authn_dbd_conf;
+
+/* optional function - look it up once in post_config */
+static ap_dbd_t *(*authn_dbd_acquire_fn)(request_rec*) = NULL;
+static void (*authn_dbd_prepare_fn)(server_rec*, const char*, const char*) = NULL;
+static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
+#define AUTHN_CACHE_STORE(r,user,realm,data) \
+ if (authn_cache_store != NULL) \
+ authn_cache_store((r), "dbd", (user), (realm), (data))
+
+static void *authn_dbd_cr_conf(apr_pool_t *pool, char *dummy)
+{
+ authn_dbd_conf *ret = apr_pcalloc(pool, sizeof(authn_dbd_conf));
+ return ret;
+}
+
+static void *authn_dbd_merge_conf(apr_pool_t *pool, void *BASE, void *ADD)
+{
+ authn_dbd_conf *add = ADD;
+ authn_dbd_conf *base = BASE;
+ authn_dbd_conf *ret = apr_palloc(pool, sizeof(authn_dbd_conf));
+ ret->user = (add->user == NULL) ? base->user : add->user;
+ ret->realm = (add->realm == NULL) ? base->realm : add->realm;
+ return ret;
+}
+
+static const char *authn_dbd_prepare(cmd_parms *cmd, void *cfg, const char *query)
+{
+ static unsigned int label_num = 0;
+ char *label;
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
+ if (err)
+ return err;
+
+ if (authn_dbd_prepare_fn == NULL) {
+ authn_dbd_prepare_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
+ if (authn_dbd_prepare_fn == NULL) {
+ return "You must load mod_dbd to enable AuthDBD functions";
+ }
+ authn_dbd_acquire_fn = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ }
+ label = apr_psprintf(cmd->pool, "authn_dbd_%d", ++label_num);
+
+ authn_dbd_prepare_fn(cmd->server, query, label);
+
+ /* save the label here for our own use */
+ return ap_set_string_slot(cmd, cfg, label);
+}
+
+static const command_rec authn_dbd_cmds[] =
+{
+ AP_INIT_TAKE1("AuthDBDUserPWQuery", authn_dbd_prepare,
+ (void *)APR_OFFSETOF(authn_dbd_conf, user), ACCESS_CONF,
+ "Query used to fetch password for user"),
+ AP_INIT_TAKE1("AuthDBDUserRealmQuery", authn_dbd_prepare,
+ (void *)APR_OFFSETOF(authn_dbd_conf, realm), ACCESS_CONF,
+ "Query used to fetch password for user+realm"),
+ {NULL}
+};
+
+static authn_status authn_dbd_password(request_rec *r, const char *user,
+ const char *password)
+{
+ apr_status_t rv;
+ const char *dbd_password = NULL;
+ apr_dbd_prepared_t *statement;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+ int ret;
+
+ authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
+ &authn_dbd_module);
+ ap_dbd_t *dbd = authn_dbd_acquire_fn(r);
+ if (dbd == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01653)
+ "Failed to acquire database connection to look up "
+ "user '%s'", user);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ if (conf->user == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01654)
+ "No AuthDBDUserPWQuery has been specified");
+ return AUTH_GENERAL_ERROR;
+ }
+
+ statement = apr_hash_get(dbd->prepared, conf->user, APR_HASH_KEY_STRING);
+ if (statement == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01655)
+ "A prepared statement could not be found for "
+ "AuthDBDUserPWQuery with the key '%s'", conf->user);
+ return AUTH_GENERAL_ERROR;
+ }
+ if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
+ statement, 0, user, NULL)) != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01656)
+ "Query execution error looking up '%s' "
+ "in database [%s]",
+ user, apr_dbd_error(dbd->driver, dbd->handle, ret));
+ return AUTH_GENERAL_ERROR;
+ }
+ for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
+ rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
+ if (rv != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01657)
+ "Error retrieving results while looking up '%s' "
+ "in database", user);
+ return AUTH_GENERAL_ERROR;
+ }
+ if (dbd_password == NULL) {
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3)
+ /* add the rest of the columns to the environment */
+ int i = 1;
+ const char *name;
+ for (name = apr_dbd_get_name(dbd->driver, res, i);
+ name != NULL;
+ name = apr_dbd_get_name(dbd->driver, res, i)) {
+
+ char *str = apr_pstrcat(r->pool, AUTHN_PREFIX,
+ name,
+ NULL);
+ int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */
+ while (str[j]) {
+ if (!apr_isalnum(str[j])) {
+ str[j] = '_';
+ }
+ else {
+ str[j] = apr_toupper(str[j]);
+ }
+ j++;
+ }
+ apr_table_set(r->subprocess_env, str,
+ apr_dbd_get_entry(dbd->driver, row, i));
+ i++;
+ }
+#endif
+ dbd_password = apr_pstrdup(r->pool,
+ apr_dbd_get_entry(dbd->driver, row, 0));
+ }
+ /* we can't break out here or row won't get cleaned up */
+ }
+
+ if (!dbd_password) {
+ return AUTH_USER_NOT_FOUND;
+ }
+ AUTHN_CACHE_STORE(r, user, NULL, dbd_password);
+
+ rv = apr_password_validate(password, dbd_password);
+
+ if (rv != APR_SUCCESS) {
+ return AUTH_DENIED;
+ }
+
+ return AUTH_GRANTED;
+}
+
+static authn_status authn_dbd_realm(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ apr_status_t rv;
+ const char *dbd_hash = NULL;
+ apr_dbd_prepared_t *statement;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+ int ret;
+
+ authn_dbd_conf *conf = ap_get_module_config(r->per_dir_config,
+ &authn_dbd_module);
+ ap_dbd_t *dbd = authn_dbd_acquire_fn(r);
+ if (dbd == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01658)
+ "Failed to acquire database connection to look up "
+ "user '%s:%s'", user, realm);
+ return AUTH_GENERAL_ERROR;
+ }
+ if (conf->realm == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01659)
+ "No AuthDBDUserRealmQuery has been specified");
+ return AUTH_GENERAL_ERROR;
+ }
+ statement = apr_hash_get(dbd->prepared, conf->realm, APR_HASH_KEY_STRING);
+ if (statement == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01660)
+ "A prepared statement could not be found for "
+ "AuthDBDUserRealmQuery with the key '%s'", conf->realm);
+ return AUTH_GENERAL_ERROR;
+ }
+ if ((ret = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
+ statement, 0, user, realm, NULL)) != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01661)
+ "Query execution error looking up '%s:%s' "
+ "in database [%s]",
+ user, realm,
+ apr_dbd_error(dbd->driver, dbd->handle, ret));
+ return AUTH_GENERAL_ERROR;
+ }
+ for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
+ rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
+ if (rv != 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01662)
+ "Error retrieving results while looking up '%s:%s' "
+ "in database", user, realm);
+ return AUTH_GENERAL_ERROR;
+ }
+ if (dbd_hash == NULL) {
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 3)
+ /* add the rest of the columns to the environment */
+ int i = 1;
+ const char *name;
+ for (name = apr_dbd_get_name(dbd->driver, res, i);
+ name != NULL;
+ name = apr_dbd_get_name(dbd->driver, res, i)) {
+
+ char *str = apr_pstrcat(r->pool, AUTHN_PREFIX,
+ name,
+ NULL);
+ int j = sizeof(AUTHN_PREFIX)-1; /* string length of "AUTHENTICATE_", excluding the trailing NIL */
+ while (str[j]) {
+ if (!apr_isalnum(str[j])) {
+ str[j] = '_';
+ }
+ else {
+ str[j] = apr_toupper(str[j]);
+ }
+ j++;
+ }
+ apr_table_set(r->subprocess_env, str,
+ apr_dbd_get_entry(dbd->driver, row, i));
+ i++;
+ }
+#endif
+ dbd_hash = apr_pstrdup(r->pool,
+ apr_dbd_get_entry(dbd->driver, row, 0));
+ }
+ /* we can't break out here or row won't get cleaned up */
+ }
+
+ if (!dbd_hash) {
+ return AUTH_USER_NOT_FOUND;
+ }
+ AUTHN_CACHE_STORE(r, user, realm, dbd_hash);
+ *rethash = apr_pstrdup(r->pool, dbd_hash);
+ return AUTH_USER_FOUND;
+}
+
+static void opt_retr(void)
+{
+ authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
+}
+
+static void authn_dbd_hooks(apr_pool_t *p)
+{
+ static const authn_provider authn_dbd_provider = {
+ &authn_dbd_password,
+ &authn_dbd_realm
+ };
+
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "dbd",
+ AUTHN_PROVIDER_VERSION,
+ &authn_dbd_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authn_dbd) =
+{
+ STANDARD20_MODULE_STUFF,
+ authn_dbd_cr_conf,
+ authn_dbd_merge_conf,
+ NULL,
+ NULL,
+ authn_dbd_cmds,
+ authn_dbd_hooks
+};
diff --git a/modules/aaa/mod_authn_dbd.dep b/modules/aaa/mod_authn_dbd.dep
new file mode 100644
index 0000000..257ee49
--- /dev/null
+++ b/modules/aaa/mod_authn_dbd.dep
@@ -0,0 +1,56 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_dbd.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_dbd.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_dbd.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr-util\include\apu_version.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_version.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_dbd.dsp b/modules/aaa/mod_authn_dbd.dsp
new file mode 100644
index 0000000..9094d33
--- /dev/null
+++ b/modules/aaa/mod_authn_dbd.dsp
@@ -0,0 +1,115 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_dbd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_dbd - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbd.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbd.mak" CFG="mod_authn_dbd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I ../database /D DBD_DECLARE_EXPORT /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I ../database /D DBD_DECLARE_EXPORT /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_dbd - Win32 Release"
+# Name "mod_authn_dbd - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\database\mod_dbd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_authn_dbd.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_dbd.mak b/modules/aaa/mod_authn_dbd.mak
new file mode 100644
index 0000000..9c983dc
--- /dev/null
+++ b/modules/aaa/mod_authn_dbd.mak
@@ -0,0 +1,409 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_dbd.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_dbd - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_dbd - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_dbd - Win32 Release" && "$(CFG)" != "mod_authn_dbd - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbd.mak" CFG="mod_authn_dbd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_dbd - Win32 Release" "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_dbd.obj"
+ -@erase "$(INTDIR)\mod_authn_dbd.res"
+ -@erase "$(INTDIR)\mod_authn_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_authn_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbd.exp"
+ -@erase "$(OUTDIR)\mod_authn_dbd.lib"
+ -@erase "$(OUTDIR)\mod_authn_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbd_src" /FD /I ../database /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbd.so" /implib:"$(OUTDIR)\mod_authn_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_dbd.obj" \
+ "$(INTDIR)\mod_authn_dbd.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib" \
+ "..\database\Release\mod_dbd.lib"
+
+"$(OUTDIR)\mod_authn_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbd.so"
+ if exist .\Release\mod_authn_dbd.so.manifest mt.exe -manifest .\Release\mod_authn_dbd.so.manifest -outputresource:.\Release\mod_authn_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_dbd - Win32 Debug" "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_dbd.obj"
+ -@erase "$(INTDIR)\mod_authn_dbd.res"
+ -@erase "$(INTDIR)\mod_authn_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_authn_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbd.exp"
+ -@erase "$(OUTDIR)\mod_authn_dbd.lib"
+ -@erase "$(OUTDIR)\mod_authn_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbd_src" /FD /EHsc /I ../database /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbd.so" /implib:"$(OUTDIR)\mod_authn_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbd.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_dbd.obj" \
+ "$(INTDIR)\mod_authn_dbd.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib" \
+ "..\database\Debug\mod_dbd.lib"
+
+"$(OUTDIR)\mod_authn_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbd.so"
+ if exist .\Debug\mod_authn_dbd.so.manifest mt.exe -manifest .\Debug\mod_authn_dbd.so.manifest -outputresource:.\Debug\mod_authn_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_dbd.dep")
+!INCLUDE "mod_authn_dbd.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_dbd.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release" || "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+"mod_dbd - Win32 Release" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release"
+ cd "..\aaa"
+
+"mod_dbd - Win32 ReleaseCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+"mod_dbd - Win32 Debug" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug"
+ cd "..\aaa"
+
+"mod_dbd - Win32 DebugCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_dbd - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_dbd - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_dbd.so" /d LONG_NAME="authn_dbd_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_dbd.c
+
+"$(INTDIR)\mod_authn_dbd.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_dbm.c b/modules/aaa/mod_authn_dbm.c
new file mode 100644
index 0000000..f4fb736
--- /dev/null
+++ b/modules/aaa/mod_authn_dbm.c
@@ -0,0 +1,208 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * http_auth: authentication
+ *
+ * Rob McCool & Brian Behlendorf.
+ *
+ * Adapted to Apache by rst.
+ *
+ */
+
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+#include "apr_strings.h"
+#include "apr_dbm.h"
+#include "apr_md5.h" /* for apr_password_validate */
+
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/
+
+#include "mod_auth.h"
+
+static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
+#define AUTHN_CACHE_STORE(r,user,realm,data) \
+ if (authn_cache_store != NULL) \
+ authn_cache_store((r), "dbm", (user), (realm), (data))
+
+typedef struct {
+ const char *pwfile;
+ const char *dbmtype;
+} authn_dbm_config_rec;
+
+static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
+{
+ authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ conf->pwfile = NULL;
+ conf->dbmtype = "default";
+
+ return conf;
+}
+
+static const command_rec authn_dbm_cmds[] =
+{
+ AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
+ (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
+ OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
+ AP_INIT_TAKE1("AuthDBMType", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authn_dbm_config_rec, dbmtype),
+ OR_AUTHCFG, "what type of DBM file the user file is"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authn_dbm_module;
+
+static apr_status_t fetch_dbm_value(const char *dbmtype, const char *dbmfile,
+ const char *user, char **value,
+ apr_pool_t *pool)
+{
+ apr_dbm_t *f;
+ apr_datum_t key, val;
+ apr_status_t rv;
+
+ rv = apr_dbm_open_ex(&f, dbmtype, dbmfile, APR_DBM_READONLY,
+ APR_OS_DEFAULT, pool);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+
+ key.dptr = (char*)user;
+#ifndef NETSCAPE_DBM_COMPAT
+ key.dsize = strlen(key.dptr);
+#else
+ key.dsize = strlen(key.dptr) + 1;
+#endif
+
+ *value = NULL;
+
+ if (apr_dbm_fetch(f, key, &val) == APR_SUCCESS && val.dptr) {
+ *value = apr_pstrmemdup(pool, val.dptr, val.dsize);
+ }
+
+ apr_dbm_close(f);
+
+ return rv;
+}
+
+static authn_status check_dbm_pw(request_rec *r, const char *user,
+ const char *password)
+{
+ authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authn_dbm_module);
+ apr_status_t rv;
+ char *dbm_password;
+ char *colon_pw;
+
+ rv = fetch_dbm_value(conf->dbmtype, conf->pwfile, user, &dbm_password,
+ r->pool);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01754)
+ "could not open dbm (type %s) auth file: %s",
+ conf->dbmtype, conf->pwfile);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ if (!dbm_password) {
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ colon_pw = ap_strchr(dbm_password, ':');
+ if (colon_pw) {
+ *colon_pw = '\0';
+ }
+ AUTHN_CACHE_STORE(r, user, NULL, dbm_password);
+
+ rv = apr_password_validate(password, dbm_password);
+
+ if (rv != APR_SUCCESS) {
+ return AUTH_DENIED;
+ }
+
+ return AUTH_GRANTED;
+}
+
+static authn_status get_dbm_realm_hash(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authn_dbm_module);
+ apr_status_t rv;
+ char *dbm_hash;
+ char *colon_hash;
+
+ rv = fetch_dbm_value(conf->dbmtype, conf->pwfile,
+ apr_pstrcat(r->pool, user, ":", realm, NULL),
+ &dbm_hash, r->pool);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01755)
+ "Could not open dbm (type %s) hash file: %s",
+ conf->dbmtype, conf->pwfile);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ if (!dbm_hash) {
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ colon_hash = ap_strchr(dbm_hash, ':');
+ if (colon_hash) {
+ *colon_hash = '\0';
+ }
+
+ *rethash = dbm_hash;
+ AUTHN_CACHE_STORE(r, user, realm, dbm_hash);
+
+ return AUTH_USER_FOUND;
+}
+
+static const authn_provider authn_dbm_provider =
+{
+ &check_dbm_pw,
+ &get_dbm_realm_hash,
+};
+
+static void opt_retr(void)
+{
+ authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
+}
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "dbm",
+ AUTHN_PROVIDER_VERSION,
+ &authn_dbm_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authn_dbm) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authn_dbm_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authn_dbm_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authn_dbm.dep b/modules/aaa/mod_authn_dbm.dep
new file mode 100644
index 0000000..2239b12
--- /dev/null
+++ b/modules/aaa/mod_authn_dbm.dep
@@ -0,0 +1,61 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_dbm.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_dbm.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_dbm.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_dbm.dsp b/modules/aaa/mod_authn_dbm.dsp
new file mode 100644
index 0000000..f2c3ff8
--- /dev/null
+++ b/modules/aaa/mod_authn_dbm.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_dbm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_dbm - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbm.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbm.mak" CFG="mod_authn_dbm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_dbm_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_dbm_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_dbm - Win32 Release"
+# Name "mod_authn_dbm - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authn_dbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_dbm.mak b/modules/aaa/mod_authn_dbm.mak
new file mode 100644
index 0000000..e15242a
--- /dev/null
+++ b/modules/aaa/mod_authn_dbm.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_dbm.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_dbm - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_dbm - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_dbm - Win32 Release" && "$(CFG)" != "mod_authn_dbm - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_dbm.mak" CFG="mod_authn_dbm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_dbm.obj"
+ -@erase "$(INTDIR)\mod_authn_dbm.res"
+ -@erase "$(INTDIR)\mod_authn_dbm_src.idb"
+ -@erase "$(INTDIR)\mod_authn_dbm_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbm.exp"
+ -@erase "$(OUTDIR)\mod_authn_dbm.lib"
+ -@erase "$(OUTDIR)\mod_authn_dbm.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbm.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbm_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbm.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbm.so" /implib:"$(OUTDIR)\mod_authn_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_dbm.obj" \
+ "$(INTDIR)\mod_authn_dbm.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbm.so"
+ if exist .\Release\mod_authn_dbm.so.manifest mt.exe -manifest .\Release\mod_authn_dbm.so.manifest -outputresource:.\Release\mod_authn_dbm.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_dbm.obj"
+ -@erase "$(INTDIR)\mod_authn_dbm.res"
+ -@erase "$(INTDIR)\mod_authn_dbm_src.idb"
+ -@erase "$(INTDIR)\mod_authn_dbm_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbm.exp"
+ -@erase "$(OUTDIR)\mod_authn_dbm.lib"
+ -@erase "$(OUTDIR)\mod_authn_dbm.pdb"
+ -@erase "$(OUTDIR)\mod_authn_dbm.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_dbm_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_dbm.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authn_dbm.so" /implib:"$(OUTDIR)\mod_authn_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_dbm.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_dbm.obj" \
+ "$(INTDIR)\mod_authn_dbm.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_dbm.so"
+ if exist .\Debug\mod_authn_dbm.so.manifest mt.exe -manifest .\Debug\mod_authn_dbm.so.manifest -outputresource:.\Debug\mod_authn_dbm.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_dbm.dep")
+!INCLUDE "mod_authn_dbm.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_dbm.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release" || "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_dbm - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_dbm.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_dbm - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_dbm.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_dbm.so" /d LONG_NAME="authn_dbm_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_dbm.c
+
+"$(INTDIR)\mod_authn_dbm.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_file.c b/modules/aaa/mod_authn_file.c
new file mode 100644
index 0000000..9909e44
--- /dev/null
+++ b/modules/aaa/mod_authn_file.c
@@ -0,0 +1,194 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_md5.h" /* for apr_password_validate */
+
+#include "ap_config.h"
+#include "ap_provider.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 "mod_auth.h"
+
+typedef struct {
+ char *pwfile;
+} authn_file_config_rec;
+
+static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
+#define AUTHN_CACHE_STORE(r,user,realm,data) \
+ if (authn_cache_store != NULL) \
+ authn_cache_store((r), "file", (user), (realm), (data))
+
+static void *create_authn_file_dir_config(apr_pool_t *p, char *d)
+{
+ authn_file_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ conf->pwfile = NULL; /* just to illustrate the default really */
+ return conf;
+}
+
+static const command_rec authn_file_cmds[] =
+{
+ AP_INIT_TAKE1("AuthUserFile", ap_set_file_slot,
+ (void *)APR_OFFSETOF(authn_file_config_rec, pwfile),
+ OR_AUTHCFG, "text file containing user IDs and passwords"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authn_file_module;
+
+static authn_status check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authn_file_module);
+ ap_configfile_t *f;
+ char l[MAX_STRING_LEN];
+ apr_status_t status;
+ char *file_password = NULL;
+
+ if (!conf->pwfile) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01619)
+ "AuthUserFile not specified in the configuration");
+ return AUTH_GENERAL_ERROR;
+ }
+
+ status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
+
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01620)
+ "Could not open password file: %s", conf->pwfile);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
+ const char *rpw, *w;
+
+ /* Skip # or blank lines. */
+ if ((l[0] == '#') || (!l[0])) {
+ continue;
+ }
+
+ rpw = l;
+ w = ap_getword(r->pool, &rpw, ':');
+
+ if (!strcmp(user, w)) {
+ file_password = ap_getword(r->pool, &rpw, ':');
+ break;
+ }
+ }
+ ap_cfg_closefile(f);
+
+ if (!file_password) {
+ return AUTH_USER_NOT_FOUND;
+ }
+ AUTHN_CACHE_STORE(r, user, NULL, file_password);
+
+ status = apr_password_validate(password, file_password);
+ if (status != APR_SUCCESS) {
+ return AUTH_DENIED;
+ }
+
+ return AUTH_GRANTED;
+}
+
+static authn_status get_realm_hash(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authn_file_module);
+ ap_configfile_t *f;
+ char l[MAX_STRING_LEN];
+ apr_status_t status;
+ char *file_hash = NULL;
+
+ if (!conf->pwfile) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01621)
+ "AuthUserFile not specified in the configuration");
+ return AUTH_GENERAL_ERROR;
+ }
+
+ status = ap_pcfg_openfile(&f, r->pool, conf->pwfile);
+
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01622)
+ "Could not open password file: %s", conf->pwfile);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
+ const char *rpw, *w, *x;
+
+ /* Skip # or blank lines. */
+ if ((l[0] == '#') || (!l[0])) {
+ continue;
+ }
+
+ rpw = l;
+ w = ap_getword(r->pool, &rpw, ':');
+ x = ap_getword(r->pool, &rpw, ':');
+
+ if (x && w && !strcmp(user, w) && !strcmp(realm, x)) {
+ /* Remember that this is a md5 hash of user:realm:password. */
+ file_hash = ap_getword(r->pool, &rpw, ':');
+ break;
+ }
+ }
+ ap_cfg_closefile(f);
+
+ if (!file_hash) {
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ *rethash = file_hash;
+ AUTHN_CACHE_STORE(r, user, realm, file_hash);
+
+ return AUTH_USER_FOUND;
+}
+
+static const authn_provider authn_file_provider =
+{
+ &check_password,
+ &get_realm_hash,
+};
+
+static void opt_retr(void)
+{
+ authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
+}
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "file",
+ AUTHN_PROVIDER_VERSION,
+ &authn_file_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authn_file) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authn_file_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authn_file_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authn_file.dep b/modules/aaa/mod_authn_file.dep
new file mode 100644
index 0000000..a841fa6
--- /dev/null
+++ b/modules/aaa/mod_authn_file.dep
@@ -0,0 +1,60 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_file.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_file.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_file.dsp b/modules/aaa/mod_authn_file.dsp
new file mode 100644
index 0000000..4dc03d5
--- /dev/null
+++ b/modules/aaa/mod_authn_file.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_file" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_file - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_file.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_file.mak" CFG="mod_authn_file - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_file - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_file - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_file_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_file.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_file_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_file.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_file.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_file - Win32 Release"
+# Name "mod_authn_file - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authn_file.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_file.mak b/modules/aaa/mod_authn_file.mak
new file mode 100644
index 0000000..3d98ce2
--- /dev/null
+++ b/modules/aaa/mod_authn_file.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_file.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_file - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_file - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_file - Win32 Release" && "$(CFG)" != "mod_authn_file - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_file.mak" CFG="mod_authn_file - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_file - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_file - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_file.obj"
+ -@erase "$(INTDIR)\mod_authn_file.res"
+ -@erase "$(INTDIR)\mod_authn_file_src.idb"
+ -@erase "$(INTDIR)\mod_authn_file_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_file.exp"
+ -@erase "$(OUTDIR)\mod_authn_file.lib"
+ -@erase "$(OUTDIR)\mod_authn_file.pdb"
+ -@erase "$(OUTDIR)\mod_authn_file.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_file_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_file.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_file.pdb" /debug /out:"$(OUTDIR)\mod_authn_file.so" /implib:"$(OUTDIR)\mod_authn_file.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_file.obj" \
+ "$(INTDIR)\mod_authn_file.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_file.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_file.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_file.so"
+ if exist .\Release\mod_authn_file.so.manifest mt.exe -manifest .\Release\mod_authn_file.so.manifest -outputresource:.\Release\mod_authn_file.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_file.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_file.obj"
+ -@erase "$(INTDIR)\mod_authn_file.res"
+ -@erase "$(INTDIR)\mod_authn_file_src.idb"
+ -@erase "$(INTDIR)\mod_authn_file_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_file.exp"
+ -@erase "$(OUTDIR)\mod_authn_file.lib"
+ -@erase "$(OUTDIR)\mod_authn_file.pdb"
+ -@erase "$(OUTDIR)\mod_authn_file.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_file_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_file.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_file.pdb" /debug /out:"$(OUTDIR)\mod_authn_file.so" /implib:"$(OUTDIR)\mod_authn_file.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_file.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_file.obj" \
+ "$(INTDIR)\mod_authn_file.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authn_file.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_file.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_file.so"
+ if exist .\Debug\mod_authn_file.so.manifest mt.exe -manifest .\Debug\mod_authn_file.so.manifest -outputresource:.\Debug\mod_authn_file.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_file.dep")
+!INCLUDE "mod_authn_file.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_file.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release" || "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_file - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_file.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_file - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_file.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_file.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_file.so" /d LONG_NAME="authn_file_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_file.c
+
+"$(INTDIR)\mod_authn_file.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authn_socache.c b/modules/aaa/mod_authn_socache.c
new file mode 100644
index 0000000..550bc66
--- /dev/null
+++ b/modules/aaa/mod_authn_socache.c
@@ -0,0 +1,475 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_md5.h" /* for apr_password_validate */
+
+#include "ap_config.h"
+#include "ap_provider.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 "mod_auth.h"
+
+#include "ap_socache.h"
+#include "util_mutex.h"
+#include "apr_optional.h"
+
+module AP_MODULE_DECLARE_DATA authn_socache_module;
+
+typedef struct authn_cache_dircfg {
+ apr_interval_time_t timeout;
+ apr_array_header_t *providers;
+ const char *context;
+} authn_cache_dircfg;
+
+/* FIXME:
+ * I think the cache and mutex should be global
+ */
+static apr_global_mutex_t *authn_cache_mutex = NULL;
+static ap_socache_provider_t *socache_provider = NULL;
+static ap_socache_instance_t *socache_instance = NULL;
+static const char *const authn_cache_id = "authn-socache";
+static int configured;
+
+static apr_status_t remove_lock(void *data)
+{
+ if (authn_cache_mutex) {
+ apr_global_mutex_destroy(authn_cache_mutex);
+ authn_cache_mutex = NULL;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t destroy_cache(void *data)
+{
+ if (socache_instance) {
+ socache_provider->destroy(socache_instance, (server_rec*)data);
+ socache_instance = NULL;
+ }
+ return APR_SUCCESS;
+}
+
+static int authn_cache_precfg(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptmp)
+{
+ apr_status_t rv = ap_mutex_register(pconf, authn_cache_id,
+ NULL, APR_LOCK_DEFAULT, 0);
+ if (rv != APR_SUCCESS) {
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01673)
+ "failed to register %s mutex", authn_cache_id);
+ return 500; /* An HTTP status would be a misnomer! */
+ }
+ socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
+ AP_SOCACHE_DEFAULT_PROVIDER,
+ AP_SOCACHE_PROVIDER_VERSION);
+ configured = 0;
+ return OK;
+}
+
+static int authn_cache_post_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptmp, server_rec *s)
+{
+ apr_status_t rv;
+ static struct ap_socache_hints authn_cache_hints = {64, 32, 60000000};
+ const char *errmsg;
+
+ if (!configured) {
+ return OK; /* don't waste the overhead of creating mutex & cache */
+ }
+ if (socache_provider == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(01674)
+ "Please select a socache provider with AuthnCacheSOCache "
+ "(no default found on this platform). Maybe you need to "
+ "load mod_socache_shmcb or another socache module first");
+ return 500; /* An HTTP status would be a misnomer! */
+ }
+
+ /* We have socache_provider, but do not have socache_instance. This should
+ * happen only when using "default" socache_provider, so create default
+ * socache_instance in this case. */
+ if (socache_instance == NULL) {
+ errmsg = socache_provider->create(&socache_instance, NULL,
+ ptmp, pconf);
+ if (errmsg) {
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, 0, plog, APLOGNO(02612)
+ "failed to create mod_socache_shmcb socache "
+ "instance: %s", errmsg);
+ return 500;
+ }
+ }
+
+ rv = ap_global_mutex_create(&authn_cache_mutex, NULL,
+ authn_cache_id, NULL, s, pconf, 0);
+ if (rv != APR_SUCCESS) {
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01675)
+ "failed to create %s mutex", authn_cache_id);
+ return 500; /* An HTTP status would be a misnomer! */
+ }
+ apr_pool_cleanup_register(pconf, NULL, remove_lock, apr_pool_cleanup_null);
+
+ rv = socache_provider->init(socache_instance, authn_cache_id,
+ &authn_cache_hints, s, pconf);
+ if (rv != APR_SUCCESS) {
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(01677)
+ "failed to initialise %s cache", authn_cache_id);
+ return 500; /* An HTTP status would be a misnomer! */
+ }
+ apr_pool_cleanup_register(pconf, (void*)s, destroy_cache, apr_pool_cleanup_null);
+ return OK;
+}
+
+static void authn_cache_child_init(apr_pool_t *p, server_rec *s)
+{
+ const char *lock;
+ apr_status_t rv;
+ if (!configured) {
+ return; /* don't waste the overhead of creating mutex & cache */
+ }
+ lock = apr_global_mutex_lockfile(authn_cache_mutex);
+ rv = apr_global_mutex_child_init(&authn_cache_mutex, lock, p);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(01678)
+ "failed to initialise mutex in child_init");
+ }
+}
+
+static const char *authn_cache_socache(cmd_parms *cmd, void *CFG,
+ const char *arg)
+{
+ const char *errmsg = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ const char *sep, *name;
+
+ if (errmsg)
+ return errmsg;
+
+ /* Argument is of form 'name:args' or just 'name'. */
+ sep = ap_strchr_c(arg, ':');
+ if (sep) {
+ name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
+ sep++;
+ }
+ else {
+ name = arg;
+ }
+
+ socache_provider = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP, name,
+ AP_SOCACHE_PROVIDER_VERSION);
+ if (socache_provider == NULL) {
+ errmsg = apr_psprintf(cmd->pool,
+ "Unknown socache provider '%s'. Maybe you need "
+ "to load the appropriate socache module "
+ "(mod_socache_%s?)", arg, arg);
+ }
+ else {
+ errmsg = socache_provider->create(&socache_instance, sep,
+ cmd->temp_pool, cmd->pool);
+ }
+
+ if (errmsg) {
+ errmsg = apr_psprintf(cmd->pool, "AuthnCacheSOCache: %s", errmsg);
+ }
+ return errmsg;
+}
+
+static const char *authn_cache_enable(cmd_parms *cmd, void *CFG)
+{
+ const char *errmsg = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ configured = 1;
+ return errmsg;
+}
+
+static const char *const directory = "directory";
+static void* authn_cache_dircfg_create(apr_pool_t *pool, char *s)
+{
+ authn_cache_dircfg *ret = apr_palloc(pool, sizeof(authn_cache_dircfg));
+ ret->timeout = apr_time_from_sec(300);
+ ret->providers = NULL;
+ ret->context = directory;
+ return ret;
+}
+
+/* not sure we want this. Might be safer to document use-all-or-none */
+static void* authn_cache_dircfg_merge(apr_pool_t *pool, void *BASE, void *ADD)
+{
+ authn_cache_dircfg *base = BASE;
+ authn_cache_dircfg *add = ADD;
+ authn_cache_dircfg *ret = apr_pmemdup(pool, add, sizeof(authn_cache_dircfg));
+ /* preserve context and timeout if not defaults */
+ if (add->context == directory) {
+ ret->context = base->context;
+ }
+ if (add->timeout == apr_time_from_sec(300)) {
+ ret->timeout = base->timeout;
+ }
+ if (add->providers == NULL) {
+ ret->providers = base->providers;
+ }
+ return ret;
+}
+
+static const char *authn_cache_setprovider(cmd_parms *cmd, void *CFG,
+ const char *arg)
+{
+ authn_cache_dircfg *cfg = CFG;
+ if (cfg->providers == NULL) {
+ cfg->providers = apr_array_make(cmd->pool, 4, sizeof(const char*));
+ }
+ APR_ARRAY_PUSH(cfg->providers, const char*) = arg;
+ configured = 1;
+ return NULL;
+}
+
+static const char *authn_cache_timeout(cmd_parms *cmd, void *CFG,
+ const char *arg)
+{
+ authn_cache_dircfg *cfg = CFG;
+ int secs = atoi(arg);
+ cfg->timeout = apr_time_from_sec(secs);
+ return NULL;
+}
+
+static const command_rec authn_cache_cmds[] =
+{
+ /* global stuff: cache and mutex */
+ AP_INIT_TAKE1("AuthnCacheSOCache", authn_cache_socache, NULL, RSRC_CONF,
+ "socache provider for authn cache"),
+ AP_INIT_NO_ARGS("AuthnCacheEnable", authn_cache_enable, NULL, RSRC_CONF,
+ "enable socache configuration in htaccess even if not enabled anywhere else"),
+ /* per-dir stuff */
+ AP_INIT_ITERATE("AuthnCacheProvideFor", authn_cache_setprovider, NULL,
+ OR_AUTHCFG, "Determine what authn providers to cache for"),
+ AP_INIT_TAKE1("AuthnCacheTimeout", authn_cache_timeout, NULL,
+ OR_AUTHCFG, "Timeout (secs) for cached credentials"),
+ AP_INIT_TAKE1("AuthnCacheContext", ap_set_string_slot,
+ (void*)APR_OFFSETOF(authn_cache_dircfg, context),
+ ACCESS_CONF, "Context for authn cache"),
+ {NULL}
+};
+
+static const char *construct_key(request_rec *r, const char *context,
+ const char *user, const char *realm)
+{
+ /* handle "special" context values */
+ if (!strcmp(context, directory)) {
+ /* FIXME: are we at risk of this blowing up? */
+ char *new_context;
+ char *slash = strrchr(r->uri, '/');
+ new_context = apr_palloc(r->pool, slash - r->uri +
+ strlen(r->server->server_hostname) + 1);
+ strcpy(new_context, r->server->server_hostname);
+ strncat(new_context, r->uri, slash - r->uri);
+ context = new_context;
+ }
+ else if (!strcmp(context, "server")) {
+ context = r->server->server_hostname;
+ }
+ /* any other context value is literal */
+
+ if (realm == NULL) { /* basic auth */
+ return apr_pstrcat(r->pool, context, ":", user, NULL);
+ }
+ else { /* digest auth */
+ return apr_pstrcat(r->pool, context, ":", user, ":", realm, NULL);
+ }
+}
+
+static void ap_authn_cache_store(request_rec *r, const char *module,
+ const char *user, const char *realm,
+ const char* data)
+{
+ apr_status_t rv;
+ authn_cache_dircfg *dcfg;
+ const char *key;
+ apr_time_t expiry;
+
+ /* first check whether we're cacheing for this module */
+ dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
+ if (!configured || !dcfg->providers) {
+ return;
+ }
+ if (!ap_array_str_contains(dcfg->providers, module)) {
+ return;
+ }
+
+ /* OK, we're on. Grab mutex to do our business */
+ rv = apr_global_mutex_trylock(authn_cache_mutex);
+ if (APR_STATUS_IS_EBUSY(rv)) {
+ /* don't wait around; just abandon it */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01679)
+ "authn credentials for %s not cached (mutex busy)", user);
+ return;
+ }
+ else if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01680)
+ "Failed to cache authn credentials for %s in %s",
+ module, dcfg->context);
+ return;
+ }
+
+ /* We have the mutex, so go ahead */
+ /* first build our key and determine expiry time */
+ key = construct_key(r, dcfg->context, user, realm);
+ expiry = apr_time_now() + dcfg->timeout;
+
+ /* store it */
+ rv = socache_provider->store(socache_instance, r->server,
+ (unsigned char*)key, strlen(key), expiry,
+ (unsigned char*)data, strlen(data), r->pool);
+ if (rv == APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01681)
+ "Cached authn credentials for %s in %s",
+ user, dcfg->context);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01682)
+ "Failed to cache authn credentials for %s in %s",
+ module, dcfg->context);
+ }
+
+ /* We're done with the mutex */
+ rv = apr_global_mutex_unlock(authn_cache_mutex);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01683) "Failed to release mutex!");
+ }
+}
+
+#define MAX_VAL_LEN 100
+static authn_status check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ /* construct key
+ * look it up
+ * if found, test password
+ *
+ * mutexing here would be a big performance drag.
+ * It's definitely unnecessary with some backends (like ndbm or gdbm)
+ * Is there a risk in the general case? I guess the only risk we
+ * care about is a race condition that gets us a dangling pointer
+ * to no-longer-defined memory. Hmmm ...
+ */
+ apr_status_t rv;
+ const char *key;
+ authn_cache_dircfg *dcfg;
+ unsigned char val[MAX_VAL_LEN];
+ unsigned int vallen = MAX_VAL_LEN - 1;
+ dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
+ if (!configured || !dcfg->providers) {
+ return AUTH_USER_NOT_FOUND;
+ }
+ key = construct_key(r, dcfg->context, user, NULL);
+ rv = socache_provider->retrieve(socache_instance, r->server,
+ (unsigned char*)key, strlen(key),
+ val, &vallen, r->pool);
+
+ if (APR_STATUS_IS_NOTFOUND(rv)) {
+ /* not found - just return */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01684)
+ "Authn cache: no credentials found for %s", user);
+ return AUTH_USER_NOT_FOUND;
+ }
+ else if (rv == APR_SUCCESS) {
+ /* OK, we got a value */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01685)
+ "Authn cache: found credentials for %s", user);
+ val[vallen] = 0;
+ }
+ else {
+ /* error: give up and pass the buck */
+ /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01686)
+ "Error accessing authentication cache");
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ rv = apr_password_validate(password, (char*) val);
+ if (rv != APR_SUCCESS) {
+ return AUTH_DENIED;
+ }
+
+ return AUTH_GRANTED;
+}
+
+static authn_status get_realm_hash(request_rec *r, const char *user,
+ const char *realm, char **rethash)
+{
+ apr_status_t rv;
+ const char *key;
+ authn_cache_dircfg *dcfg;
+ unsigned char val[MAX_VAL_LEN];
+ unsigned int vallen = MAX_VAL_LEN - 1;
+ dcfg = ap_get_module_config(r->per_dir_config, &authn_socache_module);
+ if (!configured || !dcfg->providers) {
+ return AUTH_USER_NOT_FOUND;
+ }
+ key = construct_key(r, dcfg->context, user, realm);
+ rv = socache_provider->retrieve(socache_instance, r->server,
+ (unsigned char*)key, strlen(key),
+ val, &vallen, r->pool);
+
+ if (APR_STATUS_IS_NOTFOUND(rv)) {
+ /* not found - just return */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01687)
+ "Authn cache: no credentials found for %s", user);
+ return AUTH_USER_NOT_FOUND;
+ }
+ else if (rv == APR_SUCCESS) {
+ /* OK, we got a value */
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01688)
+ "Authn cache: found credentials for %s", user);
+ }
+ else {
+ /* error: give up and pass the buck */
+ /* FIXME: getting this for NOTFOUND - prolly a bug in mod_socache */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01689)
+ "Error accessing authentication cache");
+ return AUTH_USER_NOT_FOUND;
+ }
+ *rethash = apr_pstrmemdup(r->pool, (char *)val, vallen);
+
+ return AUTH_USER_FOUND;
+}
+
+static const authn_provider authn_cache_provider =
+{
+ &check_password,
+ &get_realm_hash,
+};
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "socache",
+ AUTHN_PROVIDER_VERSION,
+ &authn_cache_provider, AP_AUTH_INTERNAL_PER_CONF);
+ APR_REGISTER_OPTIONAL_FN(ap_authn_cache_store);
+ ap_hook_pre_config(authn_cache_precfg, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(authn_cache_post_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_child_init(authn_cache_child_init, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authn_socache) =
+{
+ STANDARD20_MODULE_STUFF,
+ authn_cache_dircfg_create,
+ authn_cache_dircfg_merge,
+ NULL,
+ NULL,
+ authn_cache_cmds,
+ register_hooks
+};
diff --git a/modules/aaa/mod_authn_socache.dep b/modules/aaa/mod_authn_socache.dep
new file mode 100644
index 0000000..c8b3d28
--- /dev/null
+++ b/modules/aaa/mod_authn_socache.dep
@@ -0,0 +1,62 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authn_socache.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authn_socache.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\ap_socache.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_mutex.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authn_socache.dsp b/modules/aaa/mod_authn_socache.dsp
new file mode 100644
index 0000000..c0cad1c
--- /dev/null
+++ b/modules/aaa/mod_authn_socache.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authn_socache" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authn_socache - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_socache.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_socache.mak" CFG="mod_authn_socache - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_socache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authn_socache_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authn_socache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authn_socache_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authn_socache.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authn_socache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authn_socache - Win32 Release"
+# Name "mod_authn_socache - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authn_socache.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authn_socache.mak b/modules/aaa/mod_authn_socache.mak
new file mode 100644
index 0000000..7d43473
--- /dev/null
+++ b/modules/aaa/mod_authn_socache.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authn_socache.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authn_socache - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authn_socache - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authn_socache - Win32 Release" && "$(CFG)" != "mod_authn_socache - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authn_socache.mak" CFG="mod_authn_socache - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authn_socache - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authn_socache - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_socache.obj"
+ -@erase "$(INTDIR)\mod_authn_socache.res"
+ -@erase "$(INTDIR)\mod_authn_socache_src.idb"
+ -@erase "$(INTDIR)\mod_authn_socache_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_socache.exp"
+ -@erase "$(OUTDIR)\mod_authn_socache.lib"
+ -@erase "$(OUTDIR)\mod_authn_socache.pdb"
+ -@erase "$(OUTDIR)\mod_authn_socache.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_socache_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_socache.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_socache.pdb" /debug /out:"$(OUTDIR)\mod_authn_socache.so" /implib:"$(OUTDIR)\mod_authn_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_socache.obj" \
+ "$(INTDIR)\mod_authn_socache.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_authn_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authn_socache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_socache.so"
+ if exist .\Release\mod_authn_socache.so.manifest mt.exe -manifest .\Release\mod_authn_socache.so.manifest -outputresource:.\Release\mod_authn_socache.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authn_socache.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authn_socache.obj"
+ -@erase "$(INTDIR)\mod_authn_socache.res"
+ -@erase "$(INTDIR)\mod_authn_socache_src.idb"
+ -@erase "$(INTDIR)\mod_authn_socache_src.pdb"
+ -@erase "$(OUTDIR)\mod_authn_socache.exp"
+ -@erase "$(OUTDIR)\mod_authn_socache.lib"
+ -@erase "$(OUTDIR)\mod_authn_socache.pdb"
+ -@erase "$(OUTDIR)\mod_authn_socache.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authn_socache_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authn_socache.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authn_socache.pdb" /debug /out:"$(OUTDIR)\mod_authn_socache.so" /implib:"$(OUTDIR)\mod_authn_socache.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authn_socache.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authn_socache.obj" \
+ "$(INTDIR)\mod_authn_socache.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_authn_socache.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authn_socache.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authn_socache.so"
+ if exist .\Debug\mod_authn_socache.so.manifest mt.exe -manifest .\Debug\mod_authn_socache.so.manifest -outputresource:.\Debug\mod_authn_socache.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authn_socache.dep")
+!INCLUDE "mod_authn_socache.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authn_socache.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release" || "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authn_socache - Win32 Release"
+
+
+"$(INTDIR)\mod_authn_socache.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authn_socache - Win32 Debug"
+
+
+"$(INTDIR)\mod_authn_socache.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authn_socache.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authn_socache.so" /d LONG_NAME="authn_socache_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authn_socache.c
+
+"$(INTDIR)\mod_authn_socache.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authnz_fcgi.c b/modules/aaa/mod_authnz_fcgi.c
new file mode 100644
index 0000000..d99f391
--- /dev/null
+++ b/modules/aaa/mod_authnz_fcgi.c
@@ -0,0 +1,1363 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_hash.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "http_log.h"
+#include "util_script.h"
+#include "ap_provider.h"
+#include "mod_auth.h"
+#include "util_fcgi.h"
+#include "ap_mmn.h"
+
+module AP_MODULE_DECLARE_DATA authnz_fcgi_module;
+
+typedef struct {
+ const char *name; /* provider name */
+ const char *backend; /* backend address, as configured */
+ const char *host;
+ apr_port_t port;
+ apr_sockaddr_t *backend_addrs;
+ int is_authn;
+ int is_authz;
+} fcgi_provider_conf;
+
+typedef struct {
+ const char *name; /* provider name */
+ const char *default_user; /* this is user if authorizer returns
+ * success and a user expression yields
+ * empty string
+ */
+ ap_expr_info_t *user_expr; /* expr to evaluate to set r->user */
+ char authoritative; /* fail request if user is rejected? */
+ char require_basic_auth; /* fail if client didn't send credentials? */
+} fcgi_dir_conf;
+
+typedef struct {
+ /* If an "authnz" provider successfully authenticates, record
+ * the provider name here for checking during authz.
+ */
+ const char *successful_authnz_provider;
+} fcgi_request_notes;
+
+static apr_hash_t *fcgi_authn_providers, *fcgi_authz_providers;
+
+#define FCGI_IO_TIMEOUT apr_time_from_sec(30)
+
+#ifndef NON200_RESPONSE_BUF_LEN
+#define NON200_RESPONSE_BUF_LEN 8192
+#endif
+
+/* fcgi://{hostname|IPv4|IPv6}:port[/] */
+#define FCGI_BACKEND_REGEX_STR "m%^fcgi://(.*):(\\d{1,5})/?$%"
+
+/*
+ * utility function to connect to a peer; generally useful, but
+ * wait for AF_UNIX support in this mod before thinking about how
+ * to make it available to other modules
+ */
+static apr_status_t connect_to_peer(apr_socket_t **newsock,
+ request_rec *r,
+ apr_sockaddr_t *backend_addrs,
+ const char *backend_name,
+ apr_interval_time_t timeout)
+{
+ apr_status_t rv = APR_EINVAL; /* returned if no backend addr was provided
+ */
+ int connected = 0;
+ apr_sockaddr_t *addr = backend_addrs;
+
+ while (addr && !connected) {
+ int loglevel = addr->next ? APLOG_DEBUG : APLOG_ERR;
+ rv = apr_socket_create(newsock, addr->family,
+ SOCK_STREAM, 0, r->pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, loglevel, rv, r,
+ APLOGNO(02494) "error creating family %d socket "
+ "for target %s",
+ addr->family, backend_name);
+ addr = addr->next;
+ continue;
+ }
+
+ apr_socket_opt_set(*newsock, APR_TCP_NODELAY, 1);
+ apr_socket_timeout_set(*newsock,
+ timeout ? timeout : r->server->timeout);
+
+ rv = apr_socket_connect(*newsock, addr);
+ if (rv != APR_SUCCESS) {
+ apr_socket_close(*newsock);
+ ap_log_rerror(APLOG_MARK, loglevel, rv, r,
+ APLOGNO(02495) "attempt to connect to %pI (%s) "
+ "failed", addr, backend_name);
+ addr = addr->next;
+ continue;
+ }
+
+ connected = 1;
+ }
+
+ return rv;
+#undef FN_LOG_MARK
+}
+
+static void log_provider_info(const fcgi_provider_conf *conf, request_rec *r)
+{
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02496) "name %s, backend %s, host %s, port %d, "
+ "first address %pI, %c%c",
+ conf->name,
+ conf->backend,
+ conf->host,
+ (int)conf->port,
+ conf->backend_addrs,
+ conf->is_authn ? 'N' : '_',
+ conf->is_authz ? 'Z' : '_');
+}
+
+static void setupenv(request_rec *r, const char *password, const char *apache_role)
+{
+ ap_add_common_vars(r);
+ ap_add_cgi_vars(r);
+ apr_table_setn(r->subprocess_env, "FCGI_ROLE", AP_FCGI_AUTHORIZER_STR);
+ if (apache_role) {
+ apr_table_setn(r->subprocess_env, "FCGI_APACHE_ROLE", apache_role);
+ }
+ if (password) {
+ apr_table_setn(r->subprocess_env, "REMOTE_PASSWD", password);
+ }
+ /* Drop the variables CONTENT_LENGTH, PATH_INFO, PATH_TRANSLATED,
+ * SCRIPT_NAME and most Hop-By-Hop headers - EXCEPT we will pass
+ * PROXY_AUTH to allow CGI to perform proxy auth for httpd
+ */
+ apr_table_unset(r->subprocess_env, "CONTENT_LENGTH");
+ apr_table_unset(r->subprocess_env, "PATH_INFO");
+ apr_table_unset(r->subprocess_env, "PATH_TRANSLATED");
+ apr_table_unset(r->subprocess_env, "SCRIPT_NAME");
+ apr_table_unset(r->subprocess_env, "HTTP_KEEP_ALIVE");
+ apr_table_unset(r->subprocess_env, "HTTP_TE");
+ apr_table_unset(r->subprocess_env, "HTTP_TRAILER");
+ apr_table_unset(r->subprocess_env, "HTTP_TRANSFER_ENCODING");
+ apr_table_unset(r->subprocess_env, "HTTP_UPGRADE");
+
+ /* Connection hop-by-hop header to prevent the CGI from hanging */
+ apr_table_setn(r->subprocess_env, "HTTP_CONNECTION", "close");
+}
+
+static apr_status_t recv_data(const fcgi_provider_conf *conf,
+ request_rec *r,
+ apr_socket_t *s,
+ char *buf,
+ apr_size_t *buflen)
+{
+ apr_status_t rv;
+
+ rv = apr_socket_recv(s, buf, buflen);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02497) "Couldn't read from backend %s",
+ conf->backend);
+ return rv;
+ }
+
+#if AP_MODULE_MAGIC_AT_LEAST(20130702,2)
+ ap_log_rdata(APLOG_MARK, APLOG_TRACE5, r, "FastCGI data received",
+ buf, *buflen, AP_LOG_DATA_SHOW_OFFSET);
+#endif
+ return APR_SUCCESS;
+}
+
+static apr_status_t recv_data_full(const fcgi_provider_conf *conf,
+ request_rec *r,
+ apr_socket_t *s,
+ char *buf,
+ apr_size_t buflen)
+{
+ apr_size_t readlen;
+ apr_size_t cumulative_len = 0;
+ apr_status_t rv;
+
+ do {
+ readlen = buflen - cumulative_len;
+ rv = recv_data(conf, r, s, buf + cumulative_len, &readlen);
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ cumulative_len += readlen;
+ } while (cumulative_len < buflen);
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t sendv_data(const fcgi_provider_conf *conf,
+ request_rec *r,
+ apr_socket_t *s,
+ struct iovec *vec,
+ int nvec,
+ apr_size_t *len)
+{
+ apr_size_t to_write = 0, written = 0;
+ apr_status_t rv = APR_SUCCESS;
+ int i, offset;
+
+ for (i = 0; i < nvec; i++) {
+ to_write += vec[i].iov_len;
+#if AP_MODULE_MAGIC_AT_LEAST(20130702,2)
+ ap_log_rdata(APLOG_MARK, APLOG_TRACE5, r, "FastCGI data sent",
+ vec[i].iov_base, vec[i].iov_len, AP_LOG_DATA_SHOW_OFFSET);
+#endif
+ }
+
+ offset = 0;
+ while (to_write) {
+ apr_size_t n = 0;
+ rv = apr_socket_sendv(s, vec + offset, nvec - offset, &n);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02498) "Sending data to %s failed",
+ conf->backend);
+ break;
+ }
+ if (n > 0) {
+ written += n;
+ if (written >= to_write)
+ break; /* short circuit out */
+ for (i = offset; i < nvec; ) {
+ if (n >= vec[i].iov_len) {
+ offset++;
+ n -= vec[i++].iov_len;
+ } else {
+ vec[i].iov_len -= n;
+ vec[i].iov_base = (char *) vec[i].iov_base + n;
+ break;
+ }
+ }
+ }
+ }
+
+ *len = written;
+
+ return rv;
+}
+
+static apr_status_t send_begin_request(request_rec *r,
+ const fcgi_provider_conf *conf,
+ apr_socket_t *s, int role,
+ apr_uint16_t request_id)
+{
+ struct iovec vec[2];
+ ap_fcgi_header header;
+ unsigned char farray[AP_FCGI_HEADER_LEN];
+ ap_fcgi_begin_request_body brb;
+ unsigned char abrb[AP_FCGI_HEADER_LEN];
+ apr_size_t len;
+
+ ap_fcgi_fill_in_header(&header, AP_FCGI_BEGIN_REQUEST, request_id,
+ sizeof(abrb), 0);
+ ap_fcgi_fill_in_request_body(&brb, role, 0 /* *NOT* AP_FCGI_KEEP_CONN */);
+
+ ap_fcgi_header_to_array(&header, farray);
+ ap_fcgi_begin_request_body_to_array(&brb, abrb);
+
+ vec[0].iov_base = (void *)farray;
+ vec[0].iov_len = sizeof(farray);
+ vec[1].iov_base = (void *)abrb;
+ vec[1].iov_len = sizeof(abrb);
+
+ return sendv_data(conf, r, s, vec, 2, &len);
+}
+
+static apr_status_t send_environment(apr_socket_t *s,
+ const fcgi_provider_conf *conf,
+ request_rec *r, apr_uint16_t request_id,
+ apr_pool_t *temp_pool)
+{
+ const char *fn = "send_environment";
+ const apr_array_header_t *envarr;
+ const apr_table_entry_t *elts;
+ struct iovec vec[2];
+ ap_fcgi_header header;
+ unsigned char farray[AP_FCGI_HEADER_LEN];
+ char *body;
+ apr_status_t rv;
+ apr_size_t avail_len, len, required_len;
+ int i, next_elem, starting_elem;
+
+ envarr = apr_table_elts(r->subprocess_env);
+ elts = (const apr_table_entry_t *) envarr->elts;
+
+ if (APLOG_R_IS_LEVEL(r, APLOG_TRACE2)) {
+
+ for (i = 0; i < envarr->nelts; ++i) {
+ if (!elts[i].key) {
+ continue;
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
+ "%s: '%s': '%s'",
+ fn, elts[i].key,
+ !strcmp(elts[i].key, "REMOTE_PASSWD") ?
+ "XXXXXXXX" : elts[i].val);
+ }
+ }
+
+ /* Send envvars over in as many FastCGI records as it takes, */
+ next_elem = 0; /* starting with the first one */
+
+ avail_len = 16 * 1024; /* our limit per record, which could have been up
+ * to AP_FCGI_MAX_CONTENT_LEN
+ */
+
+ while (next_elem < envarr->nelts) {
+ starting_elem = next_elem;
+ required_len = ap_fcgi_encoded_env_len(r->subprocess_env,
+ avail_len,
+ &next_elem);
+
+ if (!required_len) {
+ if (next_elem < envarr->nelts) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ APLOGNO(02499) "couldn't encode envvar '%s' in %"
+ APR_SIZE_T_FMT " bytes",
+ elts[next_elem].key, avail_len);
+ /* skip this envvar and continue */
+ ++next_elem;
+ continue;
+ }
+ /* only an unused element at the end of the array */
+ break;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02500) "required len for encoding envvars: %"
+ APR_SIZE_T_FMT ", %d/%d elems processed so far",
+ required_len, next_elem, envarr->nelts);
+
+ body = apr_palloc(temp_pool, required_len);
+ rv = ap_fcgi_encode_env(r, r->subprocess_env, body, required_len,
+ &starting_elem);
+ /* we pre-compute, so we can't run out of space */
+ ap_assert(rv == APR_SUCCESS);
+ /* compute and encode must be in sync */
+ ap_assert(starting_elem == next_elem);
+
+ ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id,
+ (apr_uint16_t)required_len, 0);
+ ap_fcgi_header_to_array(&header, farray);
+
+ vec[0].iov_base = (void *)farray;
+ vec[0].iov_len = sizeof(farray);
+ vec[1].iov_base = body;
+ vec[1].iov_len = required_len;
+
+ rv = sendv_data(conf, r, s, vec, 2, &len);
+ apr_pool_clear(temp_pool);
+
+ if (rv) {
+ return rv;
+ }
+ }
+
+ /* Envvars sent, so say we're done */
+ ap_fcgi_fill_in_header(&header, AP_FCGI_PARAMS, request_id, 0, 0);
+ ap_fcgi_header_to_array(&header, farray);
+
+ vec[0].iov_base = (void *)farray;
+ vec[0].iov_len = sizeof(farray);
+
+ return sendv_data(conf, r, s, vec, 1, &len);
+}
+
+/*
+ * This header-state logic is from mod_proxy_fcgi.
+ */
+enum {
+ HDR_STATE_READING_HEADERS,
+ HDR_STATE_GOT_CR,
+ HDR_STATE_GOT_CRLF,
+ HDR_STATE_GOT_CRLFCR,
+ HDR_STATE_GOT_LF,
+ HDR_STATE_DONE_WITH_HEADERS
+};
+
+/* Try to find the end of the script headers in the response from the back
+ * end fastcgi server. STATE holds the current header parsing state for this
+ * request.
+ *
+ * Returns 0 if it can't find the end of the headers, and 1 if it found the
+ * end of the headers. */
+static int handle_headers(request_rec *r, int *state,
+ const char *readbuf, apr_size_t readlen)
+{
+ const char *itr = readbuf;
+
+ while (readlen--) {
+ if (*itr == '\r') {
+ switch (*state) {
+ case HDR_STATE_GOT_CRLF:
+ *state = HDR_STATE_GOT_CRLFCR;
+ break;
+
+ default:
+ *state = HDR_STATE_GOT_CR;
+ break;
+ }
+ }
+ else if (*itr == '\n') {
+ switch (*state) {
+ case HDR_STATE_GOT_LF:
+ *state = HDR_STATE_DONE_WITH_HEADERS;
+ break;
+
+ case HDR_STATE_GOT_CR:
+ *state = HDR_STATE_GOT_CRLF;
+ break;
+
+ case HDR_STATE_GOT_CRLFCR:
+ *state = HDR_STATE_DONE_WITH_HEADERS;
+ break;
+
+ default:
+ *state = HDR_STATE_GOT_LF;
+ break;
+ }
+ }
+ else {
+ *state = HDR_STATE_READING_HEADERS;
+ }
+
+ if (*state == HDR_STATE_DONE_WITH_HEADERS)
+ break;
+
+ ++itr;
+ }
+
+ if (*state == HDR_STATE_DONE_WITH_HEADERS) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * handle_response() is based on mod_proxy_fcgi's dispatch()
+ */
+static apr_status_t handle_response(const fcgi_provider_conf *conf,
+ request_rec *r, apr_socket_t *s,
+ apr_pool_t *temp_pool,
+ apr_uint16_t request_id,
+ char *rspbuf,
+ apr_size_t *rspbuflen)
+{
+ apr_bucket *b;
+ apr_bucket_brigade *ob;
+ apr_size_t orspbuflen = 0;
+ apr_status_t rv = APR_SUCCESS;
+ const char *fn = "handle_response";
+ int header_state = HDR_STATE_READING_HEADERS;
+ int seen_end_of_headers = 0, done = 0;
+
+ if (rspbuflen) {
+ orspbuflen = *rspbuflen;
+ *rspbuflen = 0; /* unless we actually read something */
+ }
+
+ ob = apr_brigade_create(r->pool, r->connection->bucket_alloc);
+
+ while (!done && rv == APR_SUCCESS) { /* Keep reading FastCGI records until
+ * we get AP_FCGI_END_REQUEST (done)
+ * or an error occurs.
+ */
+ apr_size_t readbuflen;
+ apr_uint16_t clen;
+ apr_uint16_t rid;
+ char readbuf[AP_IOBUFSIZE + 1];
+ unsigned char farray[AP_FCGI_HEADER_LEN];
+ unsigned char plen;
+ unsigned char type;
+ unsigned char version;
+
+ rv = recv_data_full(conf, r, s, (char *)farray, AP_FCGI_HEADER_LEN);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02501) "%s: Error occurred before reading "
+ "entire header", fn);
+ break;
+ }
+
+ ap_fcgi_header_fields_from_array(&version, &type, &rid, &clen, &plen,
+ farray);
+
+ if (version != AP_FCGI_VERSION_1) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02502) "%s: Got bogus FastCGI header "
+ "version %d", fn, (int)version);
+ rv = APR_EINVAL;
+ break;
+ }
+
+ if (rid != request_id) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02503) "%s: Got bogus FastCGI header "
+ "request id %d, expected %d",
+ fn, rid, request_id);
+ rv = APR_EINVAL;
+ break;
+ }
+
+ recv_again: /* if we need to keep reading more of a record's content */
+
+ if (clen > sizeof(readbuf) - 1) {
+ readbuflen = sizeof(readbuf) - 1;
+ } else {
+ readbuflen = clen;
+ }
+
+ /*
+ * Now get the actual content of the record.
+ */
+ if (readbuflen != 0) {
+ rv = recv_data(conf, r, s, readbuf, &readbuflen);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ readbuf[readbuflen] = '\0';
+ }
+
+ switch (type) {
+ case AP_FCGI_STDOUT: /* Response headers and optional body */
+ if (clen != 0) {
+ b = apr_bucket_transient_create(readbuf,
+ readbuflen,
+ r->connection->bucket_alloc);
+
+ APR_BRIGADE_INSERT_TAIL(ob, b);
+
+ if (!seen_end_of_headers) {
+ int st = handle_headers(r, &header_state,
+ readbuf, readbuflen);
+
+ if (st == 1) {
+ int status;
+
+ seen_end_of_headers = 1;
+
+ status =
+ ap_scan_script_header_err_brigade_ex(r, ob,
+ NULL,
+ APLOG_MODULE_INDEX);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02504) "%s: script header "
+ "parsing -> %d/%d",
+ fn, status, r->status);
+
+ if (rspbuf) { /* caller wants to see response body,
+ * if any
+ */
+ apr_status_t tmprv;
+
+ if (rspbuflen) {
+ *rspbuflen = orspbuflen;
+ }
+ tmprv = apr_brigade_flatten(ob, rspbuf, rspbuflen);
+ if (tmprv != APR_SUCCESS) {
+ /* should not occur for these bucket types;
+ * does not indicate overflow
+ */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, tmprv, r,
+ APLOGNO(02505) "%s: error "
+ "flattening response body",
+ fn);
+ }
+ }
+
+ if (status != OK) {
+ r->status = status;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02506) "%s: Error parsing "
+ "script headers from %s",
+ fn, conf->backend);
+ rv = APR_EINVAL;
+ break;
+ }
+ apr_pool_clear(temp_pool);
+ }
+ else {
+ /* We're still looking for the end of the
+ * headers, so this part of the data will need
+ * to persist. */
+ apr_bucket_setaside(b, temp_pool);
+ }
+ }
+
+ /* If we didn't read all the data go back and get the
+ * rest of it. */
+ if (clen > readbuflen) {
+ clen -= readbuflen;
+ goto recv_again;
+ }
+ }
+ break;
+
+ case AP_FCGI_STDERR: /* Text to log */
+ if (clen) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ APLOGNO(02507) "%s: Logged from %s: '%s'",
+ fn, conf->backend, readbuf);
+ }
+
+ if (clen > readbuflen) {
+ clen -= readbuflen;
+ goto recv_again; /* continue reading this record */
+ }
+ break;
+
+ case AP_FCGI_END_REQUEST:
+ done = 1;
+ break;
+
+ default:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02508) "%s: Got bogus FastCGI record type "
+ "%d", fn, type);
+ break;
+ }
+ /* Leave on above switch's inner error. */
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+
+ /*
+ * Read/discard any trailing padding.
+ */
+ if (plen) {
+ rv = recv_data_full(conf, r, s, readbuf, plen);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02509) "%s: Error occurred reading "
+ "padding",
+ fn);
+ break;
+ }
+ }
+ }
+
+ apr_brigade_cleanup(ob);
+
+ if (rv == APR_SUCCESS && !seen_end_of_headers) {
+ rv = APR_EINVAL;
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02510) "%s: Never reached end of script headers",
+ fn);
+ }
+
+ return rv;
+}
+
+/* almost from mod_fcgid */
+static int mod_fcgid_modify_auth_header(void *vars,
+ const char *key, const char *val)
+{
+ /* When the application gives a 200 response, the server ignores response
+ headers whose names aren't prefixed with Variable- prefix, and ignores
+ any response content */
+ if (strncasecmp(key, "Variable-", 9) == 0)
+ apr_table_setn(vars, key, val);
+ return 1;
+}
+
+static int fix_auth_header(void *vr, const char *key, const char *val)
+{
+ request_rec *r = vr;
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, "moving %s->%s", key, val);
+ apr_table_unset(r->err_headers_out, key);
+ apr_table_setn(r->subprocess_env, key + 9, val);
+ return 1;
+}
+
+static void req_rsp(request_rec *r, const fcgi_provider_conf *conf,
+ const char *password, const char *apache_role,
+ char *rspbuf, apr_size_t *rspbuflen)
+{
+ const char *fn = "req_rsp";
+ apr_pool_t *temp_pool;
+ apr_size_t orspbuflen = 0;
+ apr_socket_t *s;
+ apr_status_t rv;
+ apr_table_t *saved_subprocess_env =
+ apr_table_copy(r->pool, r->subprocess_env);
+
+ if (rspbuflen) {
+ orspbuflen = *rspbuflen;
+ *rspbuflen = 0; /* unless we actually read something */
+ }
+
+ apr_pool_create(&temp_pool, r->pool);
+
+ setupenv(r, password, apache_role);
+
+ rv = connect_to_peer(&s, r, conf->backend_addrs,
+ conf->backend, FCGI_IO_TIMEOUT);
+ if (rv == APR_SUCCESS) {
+ apr_uint16_t request_id = 1;
+
+ rv = send_begin_request(r, conf, s, AP_FCGI_AUTHORIZER, request_id);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02511) "%s: Failed writing request to %s",
+ fn, conf->backend);
+ }
+
+ if (rv == APR_SUCCESS) {
+ rv = send_environment(s, conf, r, request_id, temp_pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02512) "%s: Failed writing environment "
+ "to %s", fn, conf->backend);
+ }
+ }
+
+ /* The responder owns the request body, not the authorizer.
+ * Don't even send an empty AP_FCGI_STDIN block. libfcgi doesn't care,
+ * but it wasn't sent to authorizers by mod_fastcgi or mod_fcgi and
+ * may be unhandled by the app. Additionally, the FastCGI spec does
+ * not mention FCGI_STDIN in the Authorizer description, though it
+ * does describe FCGI_STDIN elsewhere in more general terms than
+ * simply a wrapper for the client's request body.
+ */
+
+ if (rv == APR_SUCCESS) {
+ if (rspbuflen) {
+ *rspbuflen = orspbuflen;
+ }
+ rv = handle_response(conf, r, s, temp_pool, request_id, rspbuf,
+ rspbuflen);
+ if (rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ APLOGNO(02514) "%s: Failed handling response "
+ "from %s", fn, conf->backend);
+ }
+ }
+
+ apr_socket_close(s);
+ }
+
+ if (rv != APR_SUCCESS) {
+ /* some sort of mechanical problem */
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02515) "%s: Received HTTP status %d",
+ fn, r->status);
+ }
+
+ r->subprocess_env = saved_subprocess_env;
+
+ if (r->status == HTTP_OK) {
+ /* An Authorizer application's 200 response may include headers
+ * whose names are prefixed with Variable-, and they should be
+ * available to subsequent phases via subprocess_env (and yanked
+ * from the client response).
+ */
+ apr_table_t *vars = apr_table_make(temp_pool, /* not used to allocate
+ * any values that end up
+ * in r->(anything)
+ */
+ 10);
+ apr_table_do(mod_fcgid_modify_auth_header, vars,
+ r->err_headers_out, NULL);
+ apr_table_do(fix_auth_header, r, vars, NULL);
+ }
+
+ apr_pool_destroy(temp_pool);
+}
+
+static int fcgi_check_authn(request_rec *r)
+{
+ const char *fn = "fcgi_check_authn";
+ fcgi_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+ &authnz_fcgi_module);
+ const char *password = NULL;
+ const fcgi_provider_conf *conf;
+ const char *prov;
+ const char *auth_type;
+ char rspbuf[NON200_RESPONSE_BUF_LEN + 1]; /* extra byte for '\0' */
+ apr_size_t rspbuflen = sizeof rspbuf - 1;
+ int res;
+
+ prov = dconf && dconf->name ? dconf->name : NULL;
+
+ if (!prov || !strcasecmp(prov, "None")) {
+ return DECLINED;
+ }
+
+ auth_type = ap_auth_type(r);
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02516) "%s, prov %s, authoritative %s, "
+ "require-basic %s, user expr? %s type %s",
+ fn, prov,
+ dconf->authoritative ? "yes" : "no",
+ dconf->require_basic_auth ? "yes" : "no",
+ dconf->user_expr ? "yes" : "no",
+ auth_type);
+
+ if (auth_type && !strcasecmp(auth_type, "Basic")) {
+ if ((res = ap_get_basic_auth_pw(r, &password))) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02517) "%s: couldn't retrieve basic auth "
+ "password", fn);
+ if (dconf->require_basic_auth) {
+ return res;
+ }
+ password = NULL;
+ }
+ }
+
+ conf = apr_hash_get(fcgi_authn_providers, prov, APR_HASH_KEY_STRING);
+ if (!conf) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
+ APLOGNO(02518) "%s: can't find config for provider %s",
+ fn, prov);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (APLOGrdebug(r)) {
+ log_provider_info(conf, r);
+ }
+
+ req_rsp(r, conf, password, AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR,
+ rspbuf, &rspbuflen);
+
+ if (r->status == HTTP_OK) {
+ if (dconf->user_expr) {
+ const char *err;
+ const char *user = ap_expr_str_exec(r, dconf->user_expr,
+ &err);
+ if (user && strlen(user)) {
+ r->user = apr_pstrdup(r->pool, user);
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02519) "%s: Setting user to '%s'",
+ fn, r->user);
+ }
+ else if (user && dconf->default_user) {
+ r->user = apr_pstrdup(r->pool, dconf->default_user);
+ }
+ else if (user) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02520) "%s: Failure extracting user "
+ "after calling authorizer: user expression "
+ "yielded empty string (variable not set?)",
+ fn);
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ else {
+ /* unexpected error, not even an empty string was returned */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ APLOGNO(02521) "%s: Failure extracting user "
+ "after calling authorizer: %s",
+ fn, err);
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ if (conf->is_authz) {
+ /* combined authn/authz phase, so app won't be invoked for authz
+ *
+ * Remember that the request was successfully authorized by this
+ * provider.
+ */
+ fcgi_request_notes *rnotes = apr_palloc(r->pool, sizeof(*rnotes));
+ rnotes->successful_authnz_provider = conf->name;
+ ap_set_module_config(r->request_config, &authnz_fcgi_module,
+ rnotes);
+ }
+ }
+ else {
+ /* From the spec:
+ * For Authorizer response status values other than "200" (OK), the
+ * Web server denies access and sends the response status, headers,
+ * and content back to the HTTP client.
+ * But:
+ * This only makes sense if this authorizer is authoritative.
+ */
+ if (rspbuflen > 0 && !dconf->authoritative) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ APLOGNO(02522) "%s: Ignoring response body from non-"
+ "authoritative authorizer", fn);
+ }
+ else if (rspbuflen > 0) {
+ if (rspbuflen == sizeof rspbuf - 1) {
+ /* apr_brigade_flatten() interface :( */
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ APLOGNO(02523) "%s: possible overflow handling "
+ "response body", fn);
+ }
+ rspbuf[rspbuflen] = '\0'; /* we reserved an extra byte for '\0' */
+ ap_custom_response(r, r->status, rspbuf); /* API makes a copy */
+ }
+ }
+
+ return r->status == HTTP_OK ?
+ OK : dconf->authoritative ? r->status : DECLINED;
+}
+
+static authn_status fcgi_check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ const char *fn = "fcgi_check_password";
+ const char *prov = apr_table_get(r->notes, AUTHN_PROVIDER_NAME_NOTE);
+ const fcgi_provider_conf *conf;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02524) "%s(%s, XXX): provider %s",
+ fn, user, prov);
+
+ if (!prov) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
+ APLOGNO(02525) "%s: provider note isn't set", fn);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ conf = apr_hash_get(fcgi_authn_providers, prov, APR_HASH_KEY_STRING);
+ if (!conf) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
+ APLOGNO(02526) "%s: can't find config for provider %s",
+ fn, prov);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ if (APLOGrdebug(r)) {
+ log_provider_info(conf, r);
+ }
+
+ req_rsp(r, conf, password,
+ /* combined authn and authz: FCGI_APACHE_ROLE not set */
+ conf->is_authz ? NULL : AP_FCGI_APACHE_ROLE_AUTHENTICATOR_STR,
+ NULL, NULL);
+
+ if (r->status == HTTP_OK) {
+ if (conf->is_authz) {
+ /* combined authn/authz phase, so app won't be invoked for authz
+ *
+ * Remember that the request was successfully authorized by this
+ * provider.
+ */
+ fcgi_request_notes *rnotes = apr_palloc(r->pool, sizeof(*rnotes));
+ rnotes->successful_authnz_provider = conf->name;
+ ap_set_module_config(r->request_config, &authnz_fcgi_module,
+ rnotes);
+ }
+ return AUTH_GRANTED;
+ }
+ else if (r->status == HTTP_INTERNAL_SERVER_ERROR) {
+ return AUTH_GENERAL_ERROR;
+ }
+ else {
+ return AUTH_DENIED;
+ }
+}
+
+static const authn_provider fcgi_authn_provider = {
+ &fcgi_check_password,
+ NULL /* get-realm-hash not supported */
+};
+
+static authz_status fcgi_authz_check(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *fn = "fcgi_authz_check";
+ const char *prov = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
+ const fcgi_provider_conf *conf;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ APLOGNO(02527) "%s(%s)", fn, require_line);
+
+ if (!prov) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
+ APLOGNO(02528) "%s: provider note isn't set", fn);
+ return AUTHZ_GENERAL_ERROR;
+ }
+
+ conf = apr_hash_get(fcgi_authz_providers, prov, APR_HASH_KEY_STRING);
+ if (!conf) {
+ ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
+ APLOGNO(02529) "%s: can't find config for provider %s",
+ fn, prov);
+ return AUTHZ_GENERAL_ERROR;
+ }
+
+ if (APLOGrdebug(r)) {
+ log_provider_info(conf, r);
+ }
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (conf->is_authn) {
+ /* combined authn/authz phase, so app won't be invoked for authz
+ *
+ * If the provider already successfully authorized this request,
+ * success.
+ */
+ fcgi_request_notes *rnotes = ap_get_module_config(r->request_config,
+ &authnz_fcgi_module);
+ if (rnotes
+ && rnotes->successful_authnz_provider
+ && !strcmp(rnotes->successful_authnz_provider, conf->name)) {
+ return AUTHZ_GRANTED;
+ }
+ else {
+ return AUTHZ_DENIED;
+ }
+ }
+ else {
+ req_rsp(r, conf, NULL, AP_FCGI_APACHE_ROLE_AUTHORIZER_STR, NULL, NULL);
+
+ if (r->status == HTTP_OK) {
+ return AUTHZ_GRANTED;
+ }
+ else if (r->status == HTTP_INTERNAL_SERVER_ERROR) {
+ return AUTHZ_GENERAL_ERROR;
+ }
+ else {
+ return AUTHZ_DENIED;
+ }
+ }
+}
+
+static const char *fcgi_authz_parse(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ /* Allowed form: Require [not] registered-provider-name<EOS>
+ */
+ if (strcmp(require_line, "")) {
+ return "mod_authnz_fcgi doesn't support restrictions on providers "
+ "(i.e., multiple require args)";
+ }
+
+ return NULL;
+}
+
+static const authz_provider fcgi_authz_provider = {
+ &fcgi_authz_check,
+ &fcgi_authz_parse,
+};
+
+static const char *fcgi_check_authn_provider(cmd_parms *cmd,
+ void *d,
+ int argc,
+ char *const argv[])
+{
+ const char *dname = "AuthnzFcgiCheckAuthnProvider";
+ fcgi_dir_conf *dc = d;
+ int ca = 0;
+
+ if (ca >= argc) {
+ return apr_pstrcat(cmd->pool, dname, ": No provider given", NULL);
+ }
+
+ dc->name = argv[ca];
+ ca++;
+
+ if (!strcasecmp(dc->name, "None")) {
+ if (ca < argc) {
+ return "Options aren't supported with \"None\"";
+ }
+ }
+
+ while (ca < argc) {
+ const char *var = argv[ca], *val;
+ int badarg = 0;
+
+ ca++;
+
+ /* at present, everything needs an argument */
+ if (ca >= argc) {
+ return apr_pstrcat(cmd->pool, dname, ": ", var,
+ "needs an argument", NULL);
+ }
+
+ val = argv[ca];
+ ca++;
+
+ if (!strcasecmp(var, "Authoritative")) {
+ if (!strcasecmp(val, "On")) {
+ dc->authoritative = 1;
+ }
+ else if (!strcasecmp(val, "Off")) {
+ dc->authoritative = 0;
+ }
+ else {
+ badarg = 1;
+ }
+ }
+ else if (!strcasecmp(var, "DefaultUser")) {
+ dc->default_user = val;
+ }
+ else if (!strcasecmp(var, "RequireBasicAuth")) {
+ if (!strcasecmp(val, "On")) {
+ dc->require_basic_auth = 1;
+ }
+ else if (!strcasecmp(val, "Off")) {
+ dc->require_basic_auth = 0;
+ }
+ else {
+ badarg = 1;
+ }
+ }
+ else if (!strcasecmp(var, "UserExpr")) {
+ const char *err;
+ int flags = AP_EXPR_FLAG_DONT_VARY | AP_EXPR_FLAG_RESTRICTED
+ | AP_EXPR_FLAG_STRING_RESULT;
+
+ dc->user_expr = ap_expr_parse_cmd(cmd, val,
+ flags, &err, NULL);
+ if (err) {
+ return apr_psprintf(cmd->pool, "%s: Error parsing '%s': '%s'",
+ dname, val, err);
+ }
+ }
+ else {
+ return apr_pstrcat(cmd->pool, dname, ": Unexpected option '",
+ var, "'", NULL);
+ }
+ if (badarg) {
+ return apr_pstrcat(cmd->pool, dname, ": Bad argument '",
+ val, "' to option '", var, "'", NULL);
+ }
+ }
+
+ return NULL;
+}
+
+/* AuthnzFcgiAuthDefineProvider {authn|authz|authnz} provider-name \
+ * fcgi://backendhost:backendport/
+ */
+static const char *fcgi_define_provider(cmd_parms *cmd,
+ void *d,
+ int argc,
+ char *const argv[])
+{
+ const char *dname = "AuthnzFcgiDefineProvider";
+ ap_rxplus_t *fcgi_backend_regex;
+ apr_status_t rv;
+ char *host;
+ const char *err, *stype;
+ fcgi_provider_conf *conf = apr_pcalloc(cmd->pool, sizeof(*conf));
+ int ca = 0, rc, port;
+
+ fcgi_backend_regex = ap_rxplus_compile(cmd->pool, FCGI_BACKEND_REGEX_STR);
+ if (!fcgi_backend_regex) {
+ return apr_psprintf(cmd->pool,
+ "%s: failed to compile regexec '%s'",
+ dname, FCGI_BACKEND_REGEX_STR);
+ }
+
+ err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err)
+ return err;
+
+ if (ca >= argc) {
+ return apr_pstrcat(cmd->pool, dname, ": No type given", NULL);
+ }
+
+ stype = argv[ca];
+ ca++;
+
+ if (!strcasecmp(stype, "authn")) {
+ conf->is_authn = 1;
+ }
+ else if (!strcasecmp(stype, "authz")) {
+ conf->is_authz = 1;
+ }
+ else if (!strcasecmp(stype, "authnz")) {
+ conf->is_authn = conf->is_authz = 1;
+ }
+ else {
+ return apr_pstrcat(cmd->pool,
+ dname,
+ ": Invalid provider type ",
+ stype,
+ NULL);
+ }
+
+ if (ca >= argc) {
+ return apr_pstrcat(cmd->pool, dname, ": No provider name given", NULL);
+ }
+ conf->name = argv[ca];
+ ca++;
+
+ if (ca >= argc) {
+ return apr_pstrcat(cmd->pool, dname, ": No backend-address given",
+ NULL);
+ }
+
+ rc = ap_rxplus_exec(cmd->pool, fcgi_backend_regex, argv[ca], NULL);
+ if (!rc || ap_rxplus_nmatch(fcgi_backend_regex) != 3) {
+ return apr_pstrcat(cmd->pool,
+ dname, ": backend-address '",
+ argv[ca],
+ "' has invalid form",
+ NULL);
+ }
+
+ host = ap_rxplus_pmatch(cmd->pool, fcgi_backend_regex, 1);
+ if (host[0] == '[' && host[strlen(host) - 1] == ']') {
+ host += 1;
+ host[strlen(host) - 1] = '\0';
+ }
+
+ port = atoi(ap_rxplus_pmatch(cmd->pool, fcgi_backend_regex, 2));
+ if (port > 65535) {
+ return apr_pstrcat(cmd->pool,
+ dname, ": backend-address '",
+ argv[ca],
+ "' has invalid port",
+ NULL);
+ }
+
+ conf->backend = argv[ca];
+ conf->host = host;
+ conf->port = port;
+ ca++;
+
+ rv = apr_sockaddr_info_get(&conf->backend_addrs, conf->host,
+ APR_UNSPEC, conf->port, 0, cmd->pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, rv, NULL,
+ APLOGNO(02530) "Address %s could not be resolved",
+ conf->backend);
+ return apr_pstrcat(cmd->pool,
+ dname,
+ ": Error resolving backend address",
+ NULL);
+ }
+
+ if (ca != argc) {
+ return apr_pstrcat(cmd->pool,
+ dname,
+ ": Unexpected parameter ",
+ argv[ca],
+ NULL);
+ }
+
+ if (conf->is_authn) {
+ apr_hash_set(fcgi_authn_providers, conf->name, APR_HASH_KEY_STRING,
+ conf);
+ ap_register_auth_provider(cmd->pool, AUTHN_PROVIDER_GROUP,
+ conf->name,
+ AUTHN_PROVIDER_VERSION,
+ &fcgi_authn_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ }
+
+ if (conf->is_authz) {
+ apr_hash_set(fcgi_authz_providers, conf->name, APR_HASH_KEY_STRING,
+ conf);
+ ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP,
+ conf->name,
+ AUTHZ_PROVIDER_VERSION,
+ &fcgi_authz_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ }
+
+ return NULL;
+}
+
+static const command_rec fcgi_cmds[] = {
+ AP_INIT_TAKE_ARGV("AuthnzFcgiDefineProvider",
+ fcgi_define_provider,
+ NULL,
+ RSRC_CONF,
+ "Define a FastCGI authn and/or authz provider"),
+
+ AP_INIT_TAKE_ARGV("AuthnzFcgiCheckAuthnProvider",
+ fcgi_check_authn_provider,
+ NULL,
+ OR_FILEINFO,
+ "Enable/disable a FastCGI authorizer to handle "
+ "check_authn phase"),
+
+ {NULL}
+};
+
+static int fcgi_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ fcgi_authn_providers = apr_hash_make(pconf);
+ fcgi_authz_providers = apr_hash_make(pconf);
+
+ return OK;
+}
+
+static void fcgi_register_hooks(apr_pool_t *p)
+{
+ static const char * const auth_basic_runs_after_me[] =
+ {"mod_auth_basic.c", NULL}; /* to allow for custom response */
+
+ ap_hook_pre_config(fcgi_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_check_authn(fcgi_check_authn, NULL, auth_basic_runs_after_me,
+ APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF);
+}
+
+static void *create_dir_conf(apr_pool_t *p, char *dummy)
+{
+ fcgi_dir_conf *dconf = apr_pcalloc(p, sizeof(fcgi_dir_conf));
+
+ dconf->authoritative = 1;
+ return dconf;
+}
+
+static void *merge_dir_conf(apr_pool_t *p, void *basev, void *overridesv)
+{
+ fcgi_dir_conf *a = (fcgi_dir_conf *)apr_pcalloc(p, sizeof(*a));
+ fcgi_dir_conf *base = (fcgi_dir_conf *)basev,
+ *over = (fcgi_dir_conf *)overridesv;
+
+ /* currently we just have a single directive applicable to a
+ * directory, so if it is set then grab all fields from fcgi_dir_conf
+ */
+ if (over->name) {
+ memcpy(a, over, sizeof(*a));
+ }
+ else {
+ memcpy(a, base, sizeof(*a));
+ }
+
+ return a;
+}
+
+AP_DECLARE_MODULE(authnz_fcgi) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_dir_conf, /* dir config creater */
+ merge_dir_conf, /* dir merger */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ fcgi_cmds, /* command apr_table_t */
+ fcgi_register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authnz_fcgi.dep b/modules/aaa/mod_authnz_fcgi.dep
new file mode 100644
index 0000000..7424929
--- /dev/null
+++ b/modules/aaa/mod_authnz_fcgi.dep
@@ -0,0 +1,61 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authnz_fcgi.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authnz_fcgi.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_fcgi.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_script.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authnz_fcgi.dsp b/modules/aaa/mod_authnz_fcgi.dsp
new file mode 100644
index 0000000..a731e4f
--- /dev/null
+++ b/modules/aaa/mod_authnz_fcgi.dsp
@@ -0,0 +1,119 @@
+# Microsoft Developer Studio Project File - Name="mod_authnz_fcgi" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authnz_fcgi - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_fcgi.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_fcgi.mak" CFG="mod_authnz_fcgi - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authnz_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authnz_fcgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authnz_fcgi_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authnz_fcgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authnz_fcgi_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authnz_fcgi.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authnz_fcgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authnz_fcgi - Win32 Release"
+# Name "mod_authnz_fcgi - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authnz_fcgi.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\mod_auth.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\util_fcgi.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authnz_fcgi.mak b/modules/aaa/mod_authnz_fcgi.mak
new file mode 100644
index 0000000..772cae2
--- /dev/null
+++ b/modules/aaa/mod_authnz_fcgi.mak
@@ -0,0 +1,353 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authnz_fcgi.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authnz_fcgi - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authnz_fcgi - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authnz_fcgi - Win32 Release" && "$(CFG)" != "mod_authnz_fcgi - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_fcgi.mak" CFG="mod_authnz_fcgi - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authnz_fcgi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authnz_fcgi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authnz_fcgi.obj"
+ -@erase "$(INTDIR)\mod_authnz_fcgi.res"
+ -@erase "$(INTDIR)\mod_authnz_fcgi_src.idb"
+ -@erase "$(INTDIR)\mod_authnz_fcgi_src.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.exp"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.lib"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_fcgi_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_fcgi.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_authnz_fcgi.so" /implib:"$(OUTDIR)\mod_authnz_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authnz_fcgi.obj" \
+ "$(INTDIR)\mod_authnz_fcgi.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib"
+
+"$(OUTDIR)\mod_authnz_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authnz_fcgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_fcgi.so"
+ if exist .\Release\mod_authnz_fcgi.so.manifest mt.exe -manifest .\Release\mod_authnz_fcgi.so.manifest -outputresource:.\Release\mod_authnz_fcgi.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authnz_fcgi.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authnz_fcgi.obj"
+ -@erase "$(INTDIR)\mod_authnz_fcgi.res"
+ -@erase "$(INTDIR)\mod_authnz_fcgi_src.idb"
+ -@erase "$(INTDIR)\mod_authnz_fcgi_src.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.exp"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.lib"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_fcgi.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "authnz_fcgi_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_fcgi_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_fcgi.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_fcgi.pdb" /debug /out:"$(OUTDIR)\mod_authnz_fcgi.so" /implib:"$(OUTDIR)\mod_authnz_fcgi.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_fcgi.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authnz_fcgi.obj" \
+ "$(INTDIR)\mod_authnz_fcgi.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib"
+
+"$(OUTDIR)\mod_authnz_fcgi.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authnz_fcgi.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_fcgi.so"
+ if exist .\Debug\mod_authnz_fcgi.so.manifest mt.exe -manifest .\Debug\mod_authnz_fcgi.so.manifest -outputresource:.\Debug\mod_authnz_fcgi.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authnz_fcgi.dep")
+!INCLUDE "mod_authnz_fcgi.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authnz_fcgi.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release" || "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authnz_fcgi - Win32 Release"
+
+
+"$(INTDIR)\mod_authnz_fcgi.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authnz_fcgi - Win32 Debug"
+
+
+"$(INTDIR)\mod_authnz_fcgi.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_fcgi.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authnz_fcgi.so" /d LONG_NAME="authnz_fcgi_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authnz_fcgi.c
+
+"$(INTDIR)\mod_authnz_fcgi.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authnz_ldap.c b/modules/aaa/mod_authnz_ldap.c
new file mode 100644
index 0000000..4634fe9
--- /dev/null
+++ b/modules/aaa/mod_authnz_ldap.c
@@ -0,0 +1,1962 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "ap_provider.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h"
+#include "util_ldap.h"
+
+#include "mod_auth.h"
+
+#include "apr_strings.h"
+#include "apr_xlate.h"
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+#include "apr_lib.h"
+
+#include <ctype.h>
+
+#if !APR_HAS_LDAP
+#error mod_authnz_ldap requires APR-util to have LDAP support built in. To fix add --with-ldap to ./configure.
+#endif
+
+static char *default_attributes[3] = { "member", "uniqueMember", NULL };
+
+typedef struct {
+ apr_pool_t *pool; /* Pool that this config is allocated from */
+#if APR_HAS_THREADS
+ apr_thread_mutex_t *lock; /* Lock for this config */
+#endif
+
+ /* 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 bind_authoritative; /* If true, will return errors when bind fails */
+
+ int user_is_dn; /* If true, r->user is replaced by DN during authn */
+ char *remote_user_attribute; /* If set, r->user is replaced by this attribute during authn */
+ 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 identifying user members. Default:"member uniqueMember" */
+ int group_attrib_is_dn; /* If true, the group attribute is the DN, otherwise,
+ it's the exact string passed by the HTTP client */
+ char **sgAttributes; /* Array of strings constructed (post-config) from subgroupattrs. Last entry is NULL. */
+ apr_array_header_t *subgroupclasses; /* List of object classes of sub-groups. Default:"groupOfNames groupOfUniqueNames" */
+ int maxNestingDepth; /* Maximum recursive nesting depth permitted during subgroup processing. Default: 10 */
+
+ int secure; /* True if SSL connections are requested */
+ char *authz_prefix; /* Prefix for environment variables added during authz */
+ int initial_bind_as_user; /* true if we should try to bind (to lookup DN) directly with the basic auth username */
+ ap_regex_t *bind_regex; /* basic auth -> bind'able username regex */
+ const char *bind_subst; /* basic auth -> bind'able username substitution */
+ int search_as_user; /* true if authz searches should be done with the users credentials (when we did authn) */
+ int compare_as_user; /* true if authz compares should be done with the users credentials (when we did authn) */
+} authn_ldap_config_t;
+
+typedef struct {
+ char *dn; /* The saved dn from a successful search */
+ char *user; /* The username provided by the client */
+ const char **vals; /* The additional values pulled during the DN search*/
+ char *password; /* if this module successfully authenticates, the basic auth password, else null */
+} authn_ldap_request_t;
+
+enum auth_ldap_phase {
+ LDAP_AUTHN, LDAP_AUTHZ
+};
+
+enum auth_ldap_optype {
+ LDAP_SEARCH, LDAP_COMPARE, LDAP_COMPARE_AND_SEARCH /* nested groups */
+};
+
+/* maximum group elements supported */
+#define GROUPATTR_MAX_ELTS 10
+
+module AP_MODULE_DECLARE_DATA authnz_ldap_module;
+
+static APR_OPTIONAL_FN_TYPE(uldap_connection_close) *util_ldap_connection_close;
+static APR_OPTIONAL_FN_TYPE(uldap_connection_find) *util_ldap_connection_find;
+static APR_OPTIONAL_FN_TYPE(uldap_cache_comparedn) *util_ldap_cache_comparedn;
+static APR_OPTIONAL_FN_TYPE(uldap_cache_compare) *util_ldap_cache_compare;
+static APR_OPTIONAL_FN_TYPE(uldap_cache_check_subgroups) *util_ldap_cache_check_subgroups;
+static APR_OPTIONAL_FN_TYPE(uldap_cache_checkuserid) *util_ldap_cache_checkuserid;
+static APR_OPTIONAL_FN_TYPE(uldap_cache_getuserdn) *util_ldap_cache_getuserdn;
+static APR_OPTIONAL_FN_TYPE(uldap_ssl_supported) *util_ldap_ssl_supported;
+
+static apr_hash_t *charset_conversions = NULL;
+static char *to_charset = NULL; /* UTF-8 identifier derived from the charset.conv file */
+
+
+/* Derive a code page ID give a language name or ID */
+static char* derive_codepage_from_lang (apr_pool_t *p, char *language)
+{
+ char *charset;
+
+ if (!language) /* our default codepage */
+ return apr_pstrdup(p, "ISO-8859-1");
+
+ charset = (char*) apr_hash_get(charset_conversions, language, APR_HASH_KEY_STRING);
+
+ /*
+ * Test if language values like 'en-US' return a match from the charset
+ * conversion map when shortened to 'en'.
+ */
+ if (!charset && strlen(language) > 3 && language[2] == '-') {
+ char *language_short = apr_pstrndup(p, language, 2);
+ charset = (char*) apr_hash_get(charset_conversions, language_short, APR_HASH_KEY_STRING);
+ }
+
+ if (charset) {
+ charset = apr_pstrdup(p, charset);
+ }
+
+ return charset;
+}
+
+static apr_xlate_t* get_conv_set (request_rec *r)
+{
+ char *lang_line = (char*)apr_table_get(r->headers_in, "accept-language");
+ char *lang;
+ apr_xlate_t *convset;
+
+ if (lang_line) {
+ lang_line = apr_pstrdup(r->pool, lang_line);
+ for (lang = lang_line;*lang;lang++) {
+ if ((*lang == ',') || (*lang == ';')) {
+ *lang = '\0';
+ break;
+ }
+ }
+ lang = derive_codepage_from_lang(r->pool, lang_line);
+
+ if (lang && (apr_xlate_open(&convset, to_charset, lang, r->pool) == APR_SUCCESS)) {
+ return convset;
+ }
+ }
+
+ return NULL;
+}
+
+
+static const char* authn_ldap_xlate_password(request_rec *r,
+ const char* sent_password)
+{
+ apr_xlate_t *convset = NULL;
+ apr_size_t inbytes;
+ apr_size_t outbytes;
+ char *outbuf;
+
+ if (charset_conversions && (convset = get_conv_set(r)) ) {
+ inbytes = strlen(sent_password);
+ outbytes = (inbytes+1)*3;
+ outbuf = apr_pcalloc(r->pool, outbytes);
+
+ /* Convert the password to UTF-8. */
+ if (apr_xlate_conv_buffer(convset, sent_password, &inbytes, outbuf,
+ &outbytes) == APR_SUCCESS)
+ return outbuf;
+ }
+
+ return sent_password;
+}
+
+
+/*
+ * 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
+static void authn_ldap_build_filter(char *filtbuf,
+ request_rec *r,
+ const char* sent_user,
+ const char* sent_filter,
+ authn_ldap_config_t *sec)
+{
+ char *p, *q, *filtbuf_end;
+ char *user, *filter;
+ apr_xlate_t *convset = NULL;
+ apr_size_t inbytes;
+ apr_size_t outbytes;
+ char *outbuf;
+ int nofilter = 0;
+
+ if (sent_user != NULL) {
+ user = apr_pstrdup (r->pool, sent_user);
+ }
+ else
+ return;
+
+ if (sent_filter != NULL) {
+ filter = apr_pstrdup (r->pool, sent_filter);
+ }
+ else
+ filter = sec->filter;
+
+ if (charset_conversions) {
+ convset = get_conv_set(r);
+ }
+
+ if (convset) {
+ inbytes = strlen(user);
+ outbytes = (inbytes+1)*3;
+ outbuf = apr_pcalloc(r->pool, outbytes);
+
+ /* Convert the user name to UTF-8. This is only valid for LDAP v3 */
+ if (apr_xlate_conv_buffer(convset, user, &inbytes, outbuf, &outbytes) == APR_SUCCESS) {
+ user = apr_pstrdup(r->pool, outbuf);
+ }
+ }
+
+ /*
+ * Create the first part of the filter, which consists of the
+ * config-supplied portions.
+ */
+
+ if ((nofilter = (filter && !strcasecmp(filter, "none")))) {
+ apr_snprintf(filtbuf, FILTER_LENGTH, "(%s=", sec->attribute);
+ }
+ else {
+ apr_snprintf(filtbuf, FILTER_LENGTH, "(&(%s)(%s=", 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;
+#if APR_HAS_MICROSOFT_LDAPSDK
+ for (p = user, q=filtbuf + strlen(filtbuf);
+ *p && q < filtbuf_end; ) {
+ if (strchr("*()\\", *p) != NULL) {
+ if ( q + 3 >= filtbuf_end)
+ break; /* Don't write part of escape sequence if we can't write all of it */
+ *q++ = '\\';
+ switch ( *p++ )
+ {
+ case '*':
+ *q++ = '2';
+ *q++ = 'a';
+ break;
+ case '(':
+ *q++ = '2';
+ *q++ = '8';
+ break;
+ case ')':
+ *q++ = '2';
+ *q++ = '9';
+ break;
+ case '\\':
+ *q++ = '5';
+ *q++ = 'c';
+ break;
+ }
+ }
+ else
+ *q++ = *p++;
+ }
+#else
+ for (p = user, q=filtbuf + strlen(filtbuf);
+ *p && q < filtbuf_end; *q++ = *p++) {
+ if (strchr("*()\\", *p) != NULL) {
+ *q++ = '\\';
+ if (q >= filtbuf_end) {
+ break;
+ }
+ }
+ }
+#endif
+ *q = '\0';
+
+ /*
+ * Append the closing parens of the filter, unless doing so would
+ * overrun the buffer.
+ */
+
+ if (nofilter) {
+ if (q + 1 <= filtbuf_end)
+ strcat(filtbuf, ")");
+ }
+ else {
+ if (q + 2 <= filtbuf_end)
+ strcat(filtbuf, "))");
+ }
+
+}
+
+static void *create_authnz_ldap_dir_config(apr_pool_t *p, char *d)
+{
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)apr_pcalloc(p, sizeof(authn_ldap_config_t));
+
+ sec->pool = p;
+#if APR_HAS_THREADS
+ apr_thread_mutex_create(&sec->lock, APR_THREAD_MUTEX_DEFAULT, p);
+#endif
+/*
+ sec->authz_enabled = 1;
+*/
+ sec->groupattr = apr_array_make(p, GROUPATTR_MAX_ELTS,
+ sizeof(struct mod_auth_ldap_groupattr_entry_t));
+ sec->subgroupclasses = 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->bind_authoritative = 1;
+ sec->deref = always;
+ sec->group_attrib_is_dn = 1;
+ sec->secure = -1; /*Initialize to unset*/
+ sec->maxNestingDepth = 10;
+ sec->sgAttributes = apr_pcalloc(p, sizeof (char *) * GROUPATTR_MAX_ELTS + 1);
+
+ sec->user_is_dn = 0;
+ sec->remote_user_attribute = NULL;
+ sec->compare_dn_on_server = 0;
+
+ sec->authz_prefix = AUTHZ_PREFIX;
+
+ return sec;
+}
+
+static apr_status_t authnz_ldap_cleanup_connection_close(void *param)
+{
+ util_ldap_connection_t *ldc = param;
+ util_ldap_connection_close(ldc);
+ return APR_SUCCESS;
+}
+
+static int set_request_vars(request_rec *r, enum auth_ldap_phase phase) {
+ char *prefix = NULL;
+ int prefix_len;
+ int remote_user_attribute_set = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+ const char **vals = req->vals;
+
+ prefix = (phase == LDAP_AUTHN) ? AUTHN_PREFIX : sec->authz_prefix;
+ prefix_len = strlen(prefix);
+
+ if (sec->attributes && vals) {
+ apr_table_t *e = r->subprocess_env;
+ int i = 0;
+ while (sec->attributes[i]) {
+ char *str = apr_pstrcat(r->pool, prefix, sec->attributes[i], NULL);
+ int j = prefix_len;
+ while (str[j]) {
+ str[j] = apr_toupper(str[j]);
+ j++;
+ }
+ apr_table_setn(e, str, vals[i] ? vals[i] : "");
+
+ /* handle remote_user_attribute, if set */
+ if ((phase == LDAP_AUTHN) &&
+ sec->remote_user_attribute &&
+ !strcmp(sec->remote_user_attribute, sec->attributes[i])) {
+ r->user = (char *)apr_pstrdup(r->pool, vals[i]);
+ remote_user_attribute_set = 1;
+ }
+ i++;
+ }
+ }
+ return remote_user_attribute_set;
+}
+
+static const char *ldap_determine_binddn(request_rec *r, const char *user) {
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+ const char *result = user;
+ ap_regmatch_t regm[AP_MAX_REG_MATCH];
+
+ if (NULL == user || NULL == sec || !sec->bind_regex || !sec->bind_subst) {
+ return result;
+ }
+
+ if (!ap_regexec(sec->bind_regex, user, AP_MAX_REG_MATCH, regm, 0)) {
+ char *substituted = ap_pregsub(r->pool, sec->bind_subst, user, AP_MAX_REG_MATCH, regm);
+ if (NULL != substituted) {
+ result = substituted;
+ }
+ }
+
+ apr_table_set(r->subprocess_env, "LDAP_BINDASUSER", result);
+
+ return result;
+}
+
+
+/* Some LDAP servers restrict who can search or compare, and the hard-coded ID
+ * might be good for the DN lookup but not for later operations.
+ */
+static util_ldap_connection_t *get_connection_for_authz(request_rec *r, enum auth_ldap_optype type) {
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ char *binddn = sec->binddn;
+ char *bindpw = sec->bindpw;
+
+ /* If the per-request config isn't set, we didn't authenticate this user, and leave the default credentials */
+ if (req && req->password &&
+ ((type == LDAP_SEARCH && sec->search_as_user) ||
+ (type == LDAP_COMPARE && sec->compare_as_user) ||
+ (type == LDAP_COMPARE_AND_SEARCH && sec->compare_as_user && sec->search_as_user))){
+ binddn = req->dn;
+ bindpw = req->password;
+ }
+
+ return util_ldap_connection_find(r, sec->host, sec->port,
+ binddn, bindpw,
+ sec->deref, sec->secure);
+}
+/*
+ * 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.
+ *
+ */
+static authn_status authn_ldap_check_password(request_rec *r, const char *user,
+ const char *password)
+{
+ char filtbuf[FILTER_LENGTH];
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+ int result = 0;
+ int remote_user_attribute_set = 0;
+ const char *dn = NULL;
+ const char *utfpassword;
+
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)apr_pcalloc(r->pool, sizeof(authn_ldap_request_t));
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+
+/*
+ if (!sec->enabled) {
+ return AUTH_USER_NOT_FOUND;
+ }
+*/
+
+ /*
+ * Basic sanity checks before any LDAP operations even happen.
+ */
+ if (!sec->have_ldap_url) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02558)
+ "no AuthLDAPURL");
+
+ return AUTH_GENERAL_ERROR;
+ }
+
+ /* There is a good AuthLDAPURL, right? */
+ if (sec->host) {
+ const char *binddn = sec->binddn;
+ const char *bindpw = sec->bindpw;
+ if (sec->initial_bind_as_user) {
+ bindpw = password;
+ binddn = ldap_determine_binddn(r, user);
+ }
+
+ ldc = util_ldap_connection_find(r, sec->host, sec->port,
+ binddn, bindpw,
+ sec->deref, sec->secure);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01690)
+ "auth_ldap authenticate: no sec->host - weird...?");
+ return AUTH_GENERAL_ERROR;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01691)
+ "auth_ldap authenticate: using URL %s", sec->url);
+
+ /* Get the password that the client sent */
+ if (password == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01692)
+ "auth_ldap authenticate: no password specified");
+ util_ldap_connection_close(ldc);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ if (user == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01693)
+ "auth_ldap authenticate: no user specified");
+ util_ldap_connection_close(ldc);
+ return AUTH_GENERAL_ERROR;
+ }
+
+ /* build the username filter */
+ authn_ldap_build_filter(filtbuf, r, user, NULL, sec);
+
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "auth_ldap authenticate: final authn filter is %s", filtbuf);
+
+ /* convert password to utf-8 */
+ utfpassword = authn_ldap_xlate_password(r, password);
+
+ /* do the user search */
+ result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
+ sec->attributes, filtbuf, utfpassword,
+ &dn, &(req->vals));
+ util_ldap_connection_close(ldc);
+
+ /* handle bind failure */
+ if (result != LDAP_SUCCESS) {
+ if (!sec->bind_authoritative) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01694)
+ "auth_ldap authenticate: user %s authentication failed; "
+ "URI %s [%s][%s] (not authoritative)",
+ user, r->uri, ldc->reason, ldap_err2string(result));
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01695)
+ "auth_ldap authenticate: "
+ "user %s authentication failed; URI %s [%s][%s]",
+ user, r->uri, ldc->reason, ldap_err2string(result));
+
+ /* talking to a primitive LDAP server (like RACF-over-LDAP) that doesn't return specific errors */
+ if (!strcasecmp(sec->filter, "none") && LDAP_OTHER == result) {
+ return AUTH_USER_NOT_FOUND;
+ }
+
+ return (LDAP_NO_SUCH_OBJECT == result) ? AUTH_USER_NOT_FOUND
+#ifdef LDAP_SECURITY_ERROR
+ : (LDAP_SECURITY_ERROR(result)) ? AUTH_DENIED
+#else
+ : (LDAP_INAPPROPRIATE_AUTH == result) ? AUTH_DENIED
+ : (LDAP_INVALID_CREDENTIALS == result) ? AUTH_DENIED
+#ifdef LDAP_INSUFFICIENT_ACCESS
+ : (LDAP_INSUFFICIENT_ACCESS == result) ? AUTH_DENIED
+#endif
+#ifdef LDAP_INSUFFICIENT_RIGHTS
+ : (LDAP_INSUFFICIENT_RIGHTS == result) ? AUTH_DENIED
+#endif
+#endif
+#ifdef LDAP_CONSTRAINT_VIOLATION
+ /* At least Sun Directory Server sends this if a user is
+ * locked. This is not covered by LDAP_SECURITY_ERROR.
+ */
+ : (LDAP_CONSTRAINT_VIOLATION == result) ? AUTH_DENIED
+#endif
+ : AUTH_GENERAL_ERROR;
+ }
+
+ /* mark the user and DN */
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = apr_pstrdup(r->pool, user);
+ req->password = apr_pstrdup(r->pool, password);
+ if (sec->user_is_dn) {
+ r->user = req->dn;
+ }
+
+ /* add environment variables */
+ remote_user_attribute_set = set_request_vars(r, LDAP_AUTHN);
+
+ /* sanity check */
+ if (sec->remote_user_attribute && !remote_user_attribute_set) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01696)
+ "auth_ldap authenticate: "
+ "REMOTE_USER was to be set with attribute '%s', "
+ "but this attribute was not requested for in the "
+ "LDAP query for the user. REMOTE_USER will fall "
+ "back to username or DN as appropriate.",
+ sec->remote_user_attribute);
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01697)
+ "auth_ldap authenticate: accepting %s", user);
+
+ return AUTH_GRANTED;
+}
+
+static authz_status ldapuser_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+ char *w;
+
+ char filtbuf[FILTER_LENGTH];
+ const char *dn = NULL;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_COMPARE);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01698)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * If we have been authenticated by some other module than mod_authnz_ldap,
+ * the req structure needed for authorization needs to be created
+ * and populated with the userid and DN of the account in LDAP
+ */
+
+
+ if (!strlen(r->user)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01699)
+ "ldap authorize: Userid is blank, AuthType=%s",
+ r->ap_auth_type);
+ }
+
+ if(!req) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01700)
+ "ldap authorize: Creating LDAP req structure");
+
+ req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
+ sizeof(authn_ldap_request_t));
+
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Search failed, log error and return failure */
+ if(result != LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01701)
+ "auth_ldap authorise: User DN not found, %s", ldc->reason);
+ return AUTHZ_DENIED;
+ }
+
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = r->user;
+
+ }
+
+ if (req->dn == NULL || strlen(req->dn) == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01702)
+ "auth_ldap authorize: require user: user's DN has not "
+ "been defined; failing authorization");
+ return AUTHZ_DENIED;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02585)
+ "auth_ldap authorize: require user: Can't evaluate expression: %s",
+ err);
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * 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, require);
+ switch(result) {
+ case LDAP_COMPARE_TRUE: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01703)
+ "auth_ldap authorize: require user: authorization "
+ "successful");
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ default: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01704)
+ "auth_ldap authorize: require user: "
+ "authorization failed [%s][%s]",
+ ldc->reason, ldap_err2string(result));
+ }
+ }
+
+ /*
+ * Now break apart the line and compare each word on it
+ */
+ t = require;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ 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, 0, r, APLOGNO(01705)
+ "auth_ldap authorize: "
+ "require user: authorization successful");
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ default: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01706)
+ "auth_ldap authorize: "
+ "require user: authorization failed [%s][%s]",
+ ldc->reason, ldap_err2string(result));
+ }
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01707)
+ "auth_ldap authorize user: authorization denied for "
+ "user %s to %s",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status ldapgroup_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+
+ char filtbuf[FILTER_LENGTH];
+ const char *dn = NULL;
+ struct mod_auth_ldap_groupattr_entry_t *ent;
+ int i;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_COMPARE); /* for the top-level group only */
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01708)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * 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;
+#if APR_HAS_THREADS
+ apr_thread_mutex_lock(sec->lock);
+#endif
+ grp = apr_array_push(sec->groupattr);
+ grp->name = "member";
+ grp = apr_array_push(sec->groupattr);
+ grp->name = "uniqueMember";
+#if APR_HAS_THREADS
+ apr_thread_mutex_unlock(sec->lock);
+#endif
+ }
+
+ /*
+ * If there are no elements in the sub group classes array, the default
+ * should be groupOfNames and groupOfUniqueNames; populate the array now.
+ */
+ if (sec->subgroupclasses->nelts == 0) {
+ struct mod_auth_ldap_groupattr_entry_t *grp;
+#if APR_HAS_THREADS
+ apr_thread_mutex_lock(sec->lock);
+#endif
+ grp = apr_array_push(sec->subgroupclasses);
+ grp->name = "groupOfNames";
+ grp = apr_array_push(sec->subgroupclasses);
+ grp->name = "groupOfUniqueNames";
+#if APR_HAS_THREADS
+ apr_thread_mutex_unlock(sec->lock);
+#endif
+ }
+
+ /*
+ * If we have been authenticated by some other module than mod_auth_ldap,
+ * the req structure needed for authorization needs to be created
+ * and populated with the userid and DN of the account in LDAP
+ */
+
+ if (!strlen(r->user)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01709)
+ "ldap authorize: Userid is blank, AuthType=%s",
+ r->ap_auth_type);
+ }
+
+ if(!req) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01710)
+ "ldap authorize: Creating LDAP req structure");
+
+ req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
+ sizeof(authn_ldap_request_t));
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Search failed, log error and return failure */
+ if(result != LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01711)
+ "auth_ldap authorise: User DN not found, %s", ldc->reason);
+ return AUTHZ_DENIED;
+ }
+
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = r->user;
+ }
+
+ ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts;
+
+ if (sec->group_attrib_is_dn) {
+ if (req->dn == NULL || strlen(req->dn) == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01712)
+ "auth_ldap authorize: require group: user's DN has "
+ "not been defined; failing authorization for user %s",
+ r->user);
+ return AUTHZ_DENIED;
+ }
+ }
+ 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;
+ }
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02586)
+ "auth_ldap authorize: require group: Can't evaluate expression: %s",
+ err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01713)
+ "auth_ldap authorize: require group: testing for group "
+ "membership in \"%s\"",
+ t);
+
+ /* PR52464 exhaust attrs in base group before checking subgroups */
+ for (i = 0; i < sec->groupattr->nelts; i++) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01714)
+ "auth_ldap authorize: require group: testing for %s: "
+ "%s (%s)",
+ 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);
+ if (result == LDAP_COMPARE_TRUE) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01715)
+ "auth_ldap authorize: require group: "
+ "authorization successful (attribute %s) "
+ "[%s][%d - %s]",
+ ent[i].name, ldc->reason, result,
+ ldap_err2string(result));
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01719)
+ "auth_ldap authorize: require group \"%s\": "
+ "didn't match with attr %s [%s][%d - %s]",
+ t, ent[i].name, ldc->reason, result,
+ ldap_err2string(result));
+ }
+ }
+
+ for (i = 0; i < sec->groupattr->nelts; i++) {
+ /* nested groups need searches and compares, so grab a new handle */
+ authnz_ldap_cleanup_connection_close(ldc);
+ apr_pool_cleanup_kill(r->pool, ldc,authnz_ldap_cleanup_connection_close);
+
+ ldc = get_connection_for_authz(r, LDAP_COMPARE_AND_SEARCH);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01716)
+ "auth_ldap authorise: require group \"%s\": "
+ "failed [%s][%d - %s], checking sub-groups",
+ t, ldc->reason, result, ldap_err2string(result));
+
+ result = util_ldap_cache_check_subgroups(r, ldc, sec->url, t, ent[i].name,
+ sec->group_attrib_is_dn ? req->dn : req->user,
+ sec->sgAttributes[0] ? sec->sgAttributes : default_attributes,
+ sec->subgroupclasses,
+ 0, sec->maxNestingDepth);
+ if (result == LDAP_COMPARE_TRUE) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01717)
+ "auth_ldap authorise: require group "
+ "(sub-group): authorisation successful "
+ "(attribute %s) [%s][%d - %s]",
+ ent[i].name, ldc->reason, result,
+ ldap_err2string(result));
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01718)
+ "auth_ldap authorise: require group "
+ "(sub-group) \"%s\": didn't match with attr %s "
+ "[%s][%d - %s]",
+ t, ldc->reason, ent[i].name, result,
+ ldap_err2string(result));
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01720)
+ "auth_ldap authorize group: authorization denied for "
+ "user %s to %s",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status ldapdn_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+
+ char filtbuf[FILTER_LENGTH];
+ const char *dn = NULL;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_SEARCH); /* _comparedn is a searche */
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01721)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * If we have been authenticated by some other module than mod_auth_ldap,
+ * the req structure needed for authorization needs to be created
+ * and populated with the userid and DN of the account in LDAP
+ */
+
+ if (!strlen(r->user)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01722)
+ "ldap authorize: Userid is blank, AuthType=%s",
+ r->ap_auth_type);
+ }
+
+ if(!req) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01723)
+ "ldap authorize: Creating LDAP req structure");
+
+ req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
+ sizeof(authn_ldap_request_t));
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Search failed, log error and return failure */
+ if(result != LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01724)
+ "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
+ return AUTHZ_DENIED;
+ }
+
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = r->user;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02587)
+ "auth_ldap authorize: require dn: Can't evaluate expression: %s",
+ err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+
+ if (req->dn == NULL || strlen(req->dn) == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01725)
+ "auth_ldap authorize: require dn: user's DN has not "
+ "been defined; failing authorization");
+ return AUTHZ_DENIED;
+ }
+
+ 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, 0, r, APLOGNO(01726)
+ "auth_ldap authorize: "
+ "require dn: authorization successful");
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ default: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01727)
+ "auth_ldap authorize: "
+ "require dn \"%s\": LDAP error [%s][%s]",
+ t, ldc->reason, ldap_err2string(result));
+ }
+ }
+
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01728)
+ "auth_ldap authorize dn: authorization denied for "
+ "user %s to %s",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status ldapattribute_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+ char *w, *value;
+
+ char filtbuf[FILTER_LENGTH];
+ const char *dn = NULL;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_COMPARE);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01729)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * If we have been authenticated by some other module than mod_auth_ldap,
+ * the req structure needed for authorization needs to be created
+ * and populated with the userid and DN of the account in LDAP
+ */
+
+ if (!strlen(r->user)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01730)
+ "ldap authorize: Userid is blank, AuthType=%s",
+ r->ap_auth_type);
+ }
+
+ if(!req) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01731)
+ "ldap authorize: Creating LDAP req structure");
+
+ req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
+ sizeof(authn_ldap_request_t));
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Search failed, log error and return failure */
+ if(result != LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01732)
+ "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
+ return AUTHZ_DENIED;
+ }
+
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = r->user;
+ }
+
+ if (req->dn == NULL || strlen(req->dn) == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01733)
+ "auth_ldap authorize: require ldap-attribute: user's DN "
+ "has not been defined; failing authorization");
+ return AUTHZ_DENIED;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02588)
+ "auth_ldap authorize: require ldap-attribute: Can't "
+ "evaluate expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+
+ while (t[0]) {
+ w = ap_getword(r->pool, &t, '=');
+ value = ap_getword_conf(r->pool, &t);
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01734)
+ "auth_ldap authorize: checking attribute %s has value %s",
+ w, value);
+ result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, w, value);
+ switch(result) {
+ case LDAP_COMPARE_TRUE: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01735)
+ "auth_ldap authorize: "
+ "require attribute: authorization successful");
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ default: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01736)
+ "auth_ldap authorize: require attribute: "
+ "authorization failed [%s][%s]",
+ ldc->reason, ldap_err2string(result));
+ }
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01737)
+ "auth_ldap authorize attribute: authorization denied for "
+ "user %s to %s",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status ldapfilter_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int result = 0;
+ authn_ldap_request_t *req =
+ (authn_ldap_request_t *)ap_get_module_config(r->request_config, &authnz_ldap_module);
+ authn_ldap_config_t *sec =
+ (authn_ldap_config_t *)ap_get_module_config(r->per_dir_config, &authnz_ldap_module);
+
+ util_ldap_connection_t *ldc = NULL;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+
+ char filtbuf[FILTER_LENGTH];
+ const char *dn = NULL;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!sec->have_ldap_url) {
+ return AUTHZ_DENIED;
+ }
+
+ if (sec->host) {
+ ldc = get_connection_for_authz(r, LDAP_SEARCH);
+ apr_pool_cleanup_register(r->pool, ldc,
+ authnz_ldap_cleanup_connection_close,
+ apr_pool_cleanup_null);
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01738)
+ "auth_ldap authorize: no sec->host - weird...?");
+ return AUTHZ_DENIED;
+ }
+
+ /*
+ * If we have been authenticated by some other module than mod_auth_ldap,
+ * the req structure needed for authorization needs to be created
+ * and populated with the userid and DN of the account in LDAP
+ */
+
+ if (!strlen(r->user)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01739)
+ "ldap authorize: Userid is blank, AuthType=%s",
+ r->ap_auth_type);
+ }
+
+ if(!req) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01740)
+ "ldap authorize: Creating LDAP req structure");
+
+ req = (authn_ldap_request_t *)apr_pcalloc(r->pool,
+ sizeof(authn_ldap_request_t));
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, r->user, NULL, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Search failed, log error and return failure */
+ if(result != LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01741)
+ "auth_ldap authorise: User DN not found with filter %s: %s", filtbuf, ldc->reason);
+ return AUTHZ_DENIED;
+ }
+
+ ap_set_module_config(r->request_config, &authnz_ldap_module, req);
+ req->dn = apr_pstrdup(r->pool, dn);
+ req->user = r->user;
+ }
+
+ if (req->dn == NULL || strlen(req->dn) == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01742)
+ "auth_ldap authorize: require ldap-filter: user's DN "
+ "has not been defined; failing authorization");
+ return AUTHZ_DENIED;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02589)
+ "auth_ldap authorize: require ldap-filter: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+
+ if (t[0]) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01743)
+ "auth_ldap authorize: checking filter %s", t);
+
+ /* Build the username filter */
+ authn_ldap_build_filter(filtbuf, r, req->user, t, sec);
+
+ /* Search for the user DN */
+ result = util_ldap_cache_getuserdn(r, ldc, sec->url, sec->basedn,
+ sec->scope, sec->attributes, filtbuf, &dn, &(req->vals));
+
+ /* Make sure that the filtered search returned the correct user dn */
+ if (result == LDAP_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01744)
+ "auth_ldap authorize: checking dn match %s", dn);
+ if (sec->compare_as_user) {
+ /* ldap-filter is the only authz that requires a search and a compare */
+ apr_pool_cleanup_kill(r->pool, ldc, authnz_ldap_cleanup_connection_close);
+ authnz_ldap_cleanup_connection_close(ldc);
+ ldc = get_connection_for_authz(r, LDAP_COMPARE);
+ }
+ result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, dn,
+ sec->compare_dn_on_server);
+ }
+
+ switch(result) {
+ case LDAP_COMPARE_TRUE: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01745)
+ "auth_ldap authorize: require ldap-filter: "
+ "authorization successful");
+ set_request_vars(r, LDAP_AUTHZ);
+ return AUTHZ_GRANTED;
+ }
+ case LDAP_FILTER_ERROR: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01746)
+ "auth_ldap authorize: require ldap-filter: "
+ "%s authorization failed [%s][%s]",
+ filtbuf, ldc->reason, ldap_err2string(result));
+ break;
+ }
+ default: {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01747)
+ "auth_ldap authorize: require ldap-filter: "
+ "authorization failed [%s][%s]",
+ ldc->reason, ldap_err2string(result));
+ }
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01748)
+ "auth_ldap authorize filter: authorization denied for "
+ "user %s to %s",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static const char *ldap_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+
+/*
+ * 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,
+ const char *mode)
+{
+ int rc;
+ apr_ldap_url_desc_t *urld;
+ apr_ldap_err_t *result;
+
+ authn_ldap_config_t *sec = config;
+
+ rc = apr_ldap_url_parse(cmd->pool, url, &(urld), &(result));
+ if (rc != APR_SUCCESS) {
+ return result->reason;
+ }
+ sec->url = apr_pstrdup(cmd->pool, url);
+
+ /* Set all the values, or at least some sane defaults */
+ if (sec->host) {
+ sec->host = apr_pstrcat(cmd->pool, urld->lud_host, " ", sec->host, NULL);
+ }
+ 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_pstrmemdup(cmd->pool, urld->lud_filter+1,
+ strlen(urld->lud_filter)-2);
+ }
+ else {
+ sec->filter = apr_pstrdup(cmd->pool, urld->lud_filter);
+ }
+ }
+ else {
+ sec->filter = "objectclass=*";
+ }
+
+ if (mode) {
+ if (0 == strcasecmp("NONE", mode)) {
+ sec->secure = APR_LDAP_NONE;
+ }
+ else if (0 == strcasecmp("SSL", mode)) {
+ sec->secure = APR_LDAP_SSL;
+ }
+ else if (0 == strcasecmp("TLS", mode) || 0 == strcasecmp("STARTTLS", mode)) {
+ sec->secure = APR_LDAP_STARTTLS;
+ }
+ else {
+ return "Invalid LDAP connection mode setting: must be one of NONE, "
+ "SSL, or TLS/STARTTLS";
+ }
+ }
+
+ /* "ldaps" indicates secure ldap connections desired
+ */
+ if (strncasecmp(url, "ldaps", 5) == 0)
+ {
+ sec->secure = APR_LDAP_SSL;
+ sec->port = urld->lud_port? urld->lud_port : LDAPS_PORT;
+ }
+ else
+ {
+ sec->port = urld->lud_port? urld->lud_port : LDAP_PORT;
+ }
+
+ sec->have_ldap_url = 1;
+
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, cmd->server,
+ "auth_ldap url parse: `%s', Host: %s, Port: %d, DN: %s, "
+ "attrib: %s, scope: %s, filter: %s, connection mode: %s",
+ url,
+ urld->lud_host,
+ urld->lud_port,
+ urld->lud_dn,
+ urld->lud_attrs? urld->lud_attrs[0] : "(null)",
+ (urld->lud_scope == LDAP_SCOPE_SUBTREE? "subtree" :
+ urld->lud_scope == LDAP_SCOPE_BASE? "base" :
+ urld->lud_scope == LDAP_SCOPE_ONELEVEL? "onelevel" : "unknown"),
+ urld->lud_filter,
+ sec->secure == APR_LDAP_SSL ? "using SSL": "not using SSL"
+ );
+
+ return NULL;
+}
+
+static const char *mod_auth_ldap_set_deref(cmd_parms *cmd, void *config, const char *arg)
+{
+ authn_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 AuthLDAPDereferenceAliases directive";
+ }
+ return NULL;
+}
+
+static const char *mod_auth_ldap_add_subgroup_attribute(cmd_parms *cmd, void *config, const char *arg)
+{
+ int i = 0;
+
+ authn_ldap_config_t *sec = config;
+
+ for (i = 0; sec->sgAttributes[i]; i++) {
+ ;
+ }
+ if (i == GROUPATTR_MAX_ELTS)
+ return "Too many AuthLDAPSubGroupAttribute values";
+
+ sec->sgAttributes[i] = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+static const char *mod_auth_ldap_add_subgroup_class(cmd_parms *cmd, void *config, const char *arg)
+{
+ struct mod_auth_ldap_groupattr_entry_t *new;
+
+ authn_ldap_config_t *sec = config;
+
+ if (sec->subgroupclasses->nelts > GROUPATTR_MAX_ELTS)
+ return "Too many AuthLDAPSubGroupClass values";
+
+ new = apr_array_push(sec->subgroupclasses);
+ new->name = apr_pstrdup(cmd->pool, arg);
+
+ return NULL;
+}
+
+static const char *mod_auth_ldap_set_subgroup_maxdepth(cmd_parms *cmd,
+ void *config,
+ const char *max_depth)
+{
+ authn_ldap_config_t *sec = config;
+
+ sec->maxNestingDepth = atol(max_depth);
+
+ 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;
+
+ authn_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;
+}
+
+static const char *set_charset_config(cmd_parms *cmd, void *config, const char *arg)
+{
+ ap_set_module_config(cmd->server->module_config, &authnz_ldap_module,
+ (void *)arg);
+ return NULL;
+}
+
+static const char *set_bind_pattern(cmd_parms *cmd, void *_cfg, const char *exp, const char *subst)
+{
+ authn_ldap_config_t *sec = _cfg;
+ ap_regex_t *regexp;
+
+ regexp = ap_pregcomp(cmd->pool, exp, AP_REG_EXTENDED);
+
+ if (!regexp) {
+ return apr_pstrcat(cmd->pool, "AuthLDAPInitialBindPattern: cannot compile regular "
+ "expression '", exp, "'", NULL);
+ }
+
+ sec->bind_regex = regexp;
+ sec->bind_subst = subst;
+
+ return NULL;
+}
+
+static const char *set_bind_password(cmd_parms *cmd, void *_cfg, const char *arg)
+{
+ authn_ldap_config_t *sec = _cfg;
+ int arglen = strlen(arg);
+ char **argv;
+ char *result;
+
+ if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
+ if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
+ return apr_pstrcat(cmd->pool,
+ "Unable to parse exec arguments from ",
+ arg+5, NULL);
+ }
+ argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
+
+ if (!argv[0]) {
+ return apr_pstrcat(cmd->pool,
+ "Invalid AuthLDAPBindPassword exec location:",
+ arg+5, NULL);
+ }
+ result = ap_get_exec_line(cmd->pool,
+ (const char*)argv[0], (const char * const *)argv);
+
+ if (!result) {
+ return apr_pstrcat(cmd->pool,
+ "Unable to get bind password from exec of ",
+ arg+5, NULL);
+ }
+ sec->bindpw = result;
+ }
+ else {
+ sec->bindpw = (char *)arg;
+ }
+
+ return NULL;
+}
+
+static const command_rec authnz_ldap_cmds[] =
+{
+ AP_INIT_TAKE12("AuthLDAPURL", mod_auth_ldap_parse_url, NULL, OR_AUTHCFG,
+ "URL to define LDAP connection. This should be an RFC 2255 compliant\n"
+ "URL of the form ldap://host[:port]/basedn[?attrib[?scope[?filter]]].\n"
+ "<ul>\n"
+ "<li>Host is the name of the LDAP server. Use a space separated list of hosts \n"
+ "to specify redundant servers.\n"
+ "<li>Port is optional, and specifies the port to connect to.\n"
+ "<li>basedn specifies the base DN to start searches from\n"
+ "<li>Attrib specifies what attribute to search for in the directory. If not "
+ "provided, it defaults to <b>uid</b>.\n"
+ "<li>Scope is the scope of the search, and can be either <b>sub</b> or "
+ "<b>one</b>. If not provided, the default is <b>sub</b>.\n"
+ "<li>Filter is a filter to use in the search. If not provided, "
+ "defaults to <b>(objectClass=*)</b>.\n"
+ "</ul>\n"
+ "Searches are performed using the attribute and the filter combined. "
+ "For example, assume that the\n"
+ "LDAP URL is <b>ldap://ldap.airius.com/ou=People, o=Airius?uid?sub?(posixid=*)</b>. "
+ "Searches will\n"
+ "be done using the filter <b>(&((posixid=*))(uid=<i>username</i>))</b>, "
+ "where <i>username</i>\n"
+ "is the user name passed by the HTTP client. The search will be a subtree "
+ "search on the branch <b>ou=People, o=Airius</b>."),
+
+ AP_INIT_TAKE1("AuthLDAPBindDN", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authn_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", set_bind_password, NULL, OR_AUTHCFG,
+ "Password to use to bind to LDAP server. If not provided, will do an anonymous bind."),
+
+ AP_INIT_FLAG("AuthLDAPBindAuthoritative", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, bind_authoritative), OR_AUTHCFG,
+ "Set to 'on' to return failures when user-specific bind fails - defaults to on."),
+
+ AP_INIT_FLAG("AuthLDAPRemoteUserIsDN", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_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_TAKE1("AuthLDAPRemoteUserAttribute", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, remote_user_attribute), OR_AUTHCFG,
+ "Override the user supplied username and place the "
+ "contents of this attribute in the REMOTE_USER "
+ "environment variable."),
+
+ AP_INIT_FLAG("AuthLDAPCompareDNOnServer", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_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("AuthLDAPSubGroupAttribute", mod_auth_ldap_add_subgroup_attribute, NULL, OR_AUTHCFG,
+ "Attribute labels used to define sub-group (or nested group) membership in groups - "
+ "defaults to member and uniqueMember"),
+
+ AP_INIT_ITERATE("AuthLDAPSubGroupClass", mod_auth_ldap_add_subgroup_class, NULL, OR_AUTHCFG,
+ "LDAP objectClass values used to identify sub-group instances - "
+ "defaults to groupOfNames and groupOfUniqueNames"),
+
+ AP_INIT_TAKE1("AuthLDAPMaxSubGroupDepth", mod_auth_ldap_set_subgroup_maxdepth, NULL, OR_AUTHCFG,
+ "Maximum subgroup nesting depth to be evaluated - defaults to 10 (top-level group = 0)"),
+
+ AP_INIT_ITERATE("AuthLDAPGroupAttribute", mod_auth_ldap_add_group_attribute, NULL, OR_AUTHCFG,
+ "A list of attribute labels used to identify the user members of groups - defaults to "
+ "member and uniquemember"),
+
+ AP_INIT_FLAG("AuthLDAPGroupAttributeIsDN", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_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 be one of the "
+ "values \"never\", \"searching\", \"finding\", or \"always\". "
+ "Defaults to always."),
+
+ AP_INIT_TAKE1("AuthLDAPCharsetConfig", set_charset_config, NULL, RSRC_CONF,
+ "Character set conversion configuration file. If omitted, character set "
+ "conversion is disabled."),
+
+ AP_INIT_TAKE1("AuthLDAPAuthorizePrefix", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, authz_prefix), OR_AUTHCFG,
+ "The prefix to add to environment variables set during "
+ "successful authorization, default '" AUTHZ_PREFIX "'"),
+
+ AP_INIT_FLAG("AuthLDAPInitialBindAsUser", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, initial_bind_as_user), OR_AUTHCFG,
+ "Set to 'on' to perform the initial DN lookup with the basic auth credentials "
+ "instead of anonymous or hard-coded credentials"),
+
+ AP_INIT_TAKE2("AuthLDAPInitialBindPattern", set_bind_pattern, NULL, OR_AUTHCFG,
+ "The regex and substitution to determine a username that can bind based on an HTTP basic auth username"),
+
+ AP_INIT_FLAG("AuthLDAPSearchAsUser", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, search_as_user), OR_AUTHCFG,
+ "Set to 'on' to perform authorization-based searches with the users credentials, when this module "
+ "has also performed authentication. Does not affect nested groups lookup."),
+ AP_INIT_FLAG("AuthLDAPCompareAsUser", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authn_ldap_config_t, compare_as_user), OR_AUTHCFG,
+ "Set to 'on' to perform authorization-based compares with the users credentials, when this module "
+ "has also performed authentication. Does not affect nested groups lookups."),
+ {NULL}
+};
+
+static int authnz_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
+{
+ ap_configfile_t *f;
+ char l[MAX_STRING_LEN];
+ const char *charset_confname = ap_get_module_config(s->module_config,
+ &authnz_ldap_module);
+ apr_status_t status;
+
+ /*
+ authn_ldap_config_t *sec = (authn_ldap_config_t *)
+ ap_get_module_config(s->module_config,
+ &authnz_ldap_module);
+
+ if (sec->secure)
+ {
+ if (!util_ldap_ssl_supported(s))
+ {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(03159)
+ "LDAP: SSL connections (ldaps://) not supported by utilLDAP");
+ return(!OK);
+ }
+ }
+ */
+
+ /* make sure that mod_ldap (util_ldap) is loaded */
+ if (ap_find_linked_module("util_ldap.c") == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01749)
+ "Module mod_ldap missing. Mod_ldap (aka. util_ldap) "
+ "must be loaded in order for mod_authnz_ldap to function properly");
+ return HTTP_INTERNAL_SERVER_ERROR;
+
+ }
+
+ if (!charset_confname) {
+ return OK;
+ }
+
+ charset_confname = ap_server_root_relative(p, charset_confname);
+ if (!charset_confname) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, APLOGNO(01750)
+ "Invalid charset conversion config path %s",
+ (const char *)ap_get_module_config(s->module_config,
+ &authnz_ldap_module));
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ if ((status = ap_pcfg_openfile(&f, ptemp, charset_confname))
+ != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, s, APLOGNO(01751)
+ "could not open charset conversion config file %s.",
+ charset_confname);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ charset_conversions = apr_hash_make(p);
+
+ while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
+ const char *ll = l;
+ char *lang;
+
+ if (l[0] == '#') {
+ continue;
+ }
+ lang = ap_getword_conf(p, &ll);
+ ap_str_tolower(lang);
+
+ if (ll[0]) {
+ char *charset = ap_getword_conf(p, &ll);
+ apr_hash_set(charset_conversions, lang, APR_HASH_KEY_STRING, charset);
+ }
+ }
+ ap_cfg_closefile(f);
+
+ to_charset = derive_codepage_from_lang (p, "utf-8");
+ if (to_charset == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, status, s, APLOGNO(01752)
+ "could not find the UTF-8 charset in the file %s.",
+ charset_confname);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ return OK;
+}
+
+static const authn_provider authn_ldap_provider =
+{
+ &authn_ldap_check_password,
+ NULL,
+};
+
+static const authz_provider authz_ldapuser_provider =
+{
+ &ldapuser_check_authorization,
+ &ldap_parse_config,
+};
+static const authz_provider authz_ldapgroup_provider =
+{
+ &ldapgroup_check_authorization,
+ &ldap_parse_config,
+};
+
+static const authz_provider authz_ldapdn_provider =
+{
+ &ldapdn_check_authorization,
+ &ldap_parse_config,
+};
+
+static const authz_provider authz_ldapattribute_provider =
+{
+ &ldapattribute_check_authorization,
+ &ldap_parse_config,
+};
+
+static const authz_provider authz_ldapfilter_provider =
+{
+ &ldapfilter_check_authorization,
+ &ldap_parse_config,
+};
+
+static void ImportULDAPOptFn(void)
+{
+ util_ldap_connection_close = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_close);
+ util_ldap_connection_find = APR_RETRIEVE_OPTIONAL_FN(uldap_connection_find);
+ util_ldap_cache_comparedn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_comparedn);
+ util_ldap_cache_compare = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_compare);
+ util_ldap_cache_checkuserid = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_checkuserid);
+ util_ldap_cache_getuserdn = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_getuserdn);
+ util_ldap_ssl_supported = APR_RETRIEVE_OPTIONAL_FN(uldap_ssl_supported);
+ util_ldap_cache_check_subgroups = APR_RETRIEVE_OPTIONAL_FN(uldap_cache_check_subgroups);
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ /* Register authn provider */
+ ap_register_auth_provider(p, AUTHN_PROVIDER_GROUP, "ldap",
+ AUTHN_PROVIDER_VERSION,
+ &authn_ldap_provider, AP_AUTH_INTERNAL_PER_CONF);
+
+ /* Register authz providers */
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-user",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapuser_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapgroup_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-dn",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapdn_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-attribute",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapattribute_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ldap-filter",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ldapfilter_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+
+ ap_hook_post_config(authnz_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
+
+ ap_hook_optional_fn_retrieve(ImportULDAPOptFn,NULL,NULL,APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authnz_ldap) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authnz_ldap_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authnz_ldap_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authnz_ldap.dep b/modules/aaa/mod_authnz_ldap.dep
new file mode 100644
index 0000000..906e060
--- /dev/null
+++ b/modules/aaa/mod_authnz_ldap.dep
@@ -0,0 +1,70 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authnz_ldap.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authnz_ldap.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_ldap.h"\
+ "..\..\srclib\apr-util\include\apr_anylock.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_ldap.h"\
+ "..\..\srclib\apr-util\include\apr_ldap_init.h"\
+ "..\..\srclib\apr-util\include\apr_ldap_option.h"\
+ "..\..\srclib\apr-util\include\apr_ldap_rebind.h"\
+ "..\..\srclib\apr-util\include\apr_ldap_url.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_rmm.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_thread_rwlock.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_version.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authnz_ldap.dsp b/modules/aaa/mod_authnz_ldap.dsp
new file mode 100644
index 0000000..e2ed929
--- /dev/null
+++ b/modules/aaa/mod_authnz_ldap.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authnz_ldap" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authnz_ldap - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_ldap.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_ldap.mak" CFG="mod_authnz_ldap - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authnz_ldap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authnz_ldap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Release\mod_authnz_ldap_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so
+# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authnz_ldap.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fd"Debug\mod_authnz_ldap_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so
+# ADD LINK32 kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authnz_ldap.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authnz_ldap.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authnz_ldap - Win32 Release"
+# Name "mod_authnz_ldap - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authnz_ldap.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authnz_ldap.mak b/modules/aaa/mod_authnz_ldap.mak
new file mode 100644
index 0000000..96cc044
--- /dev/null
+++ b/modules/aaa/mod_authnz_ldap.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authnz_ldap.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authnz_ldap - Win32 Release
+!MESSAGE No configuration specified. Defaulting to mod_authnz_ldap - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authnz_ldap - Win32 Release" && "$(CFG)" != "mod_authnz_ldap - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authnz_ldap.mak" CFG="mod_authnz_ldap - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authnz_ldap - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authnz_ldap - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_ldap - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_ldap - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authnz_ldap.obj"
+ -@erase "$(INTDIR)\mod_authnz_ldap.res"
+ -@erase "$(INTDIR)\mod_authnz_ldap_src.idb"
+ -@erase "$(INTDIR)\mod_authnz_ldap_src.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.exp"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.lib"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_ldap_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_ldap.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_ldap.pdb" /debug /out:"$(OUTDIR)\mod_authnz_ldap.so" /implib:"$(OUTDIR)\mod_authnz_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authnz_ldap.obj" \
+ "$(INTDIR)\mod_authnz_ldap.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "..\ldap\Release\mod_ldap.lib"
+
+"$(OUTDIR)\mod_authnz_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authnz_ldap.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_ldap.so"
+ if exist .\Release\mod_authnz_ldap.so.manifest mt.exe -manifest .\Release\mod_authnz_ldap.so.manifest -outputresource:.\Release\mod_authnz_ldap.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_ldap - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authnz_ldap.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_ldap - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authnz_ldap.obj"
+ -@erase "$(INTDIR)\mod_authnz_ldap.res"
+ -@erase "$(INTDIR)\mod_authnz_ldap_src.idb"
+ -@erase "$(INTDIR)\mod_authnz_ldap_src.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.exp"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.lib"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.pdb"
+ -@erase "$(OUTDIR)\mod_authnz_ldap.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../ldap" /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "LDAP_DECLARE_EXPORT" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authnz_ldap_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authnz_ldap.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib wldap32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authnz_ldap.pdb" /debug /out:"$(OUTDIR)\mod_authnz_ldap.so" /implib:"$(OUTDIR)\mod_authnz_ldap.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authnz_ldap.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authnz_ldap.obj" \
+ "$(INTDIR)\mod_authnz_ldap.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "..\ldap\Debug\mod_ldap.lib"
+
+"$(OUTDIR)\mod_authnz_ldap.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authnz_ldap.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authnz_ldap.so"
+ if exist .\Debug\mod_authnz_ldap.so.manifest mt.exe -manifest .\Debug\mod_authnz_ldap.so.manifest -outputresource:.\Debug\mod_authnz_ldap.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authnz_ldap.dep")
+!INCLUDE "mod_authnz_ldap.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authnz_ldap.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release" || "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+"mod_ldap - Win32 Release" :
+ cd ".\..\ldap"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Release"
+ cd "..\aaa"
+
+"mod_ldap - Win32 ReleaseCLEAN" :
+ cd ".\..\ldap"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Release" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+"mod_ldap - Win32 Debug" :
+ cd ".\..\ldap"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Debug"
+ cd "..\aaa"
+
+"mod_ldap - Win32 DebugCLEAN" :
+ cd ".\..\ldap"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_ldap.mak" CFG="mod_ldap - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authnz_ldap - Win32 Release"
+
+
+"$(INTDIR)\mod_authnz_ldap.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authnz_ldap - Win32 Debug"
+
+
+"$(INTDIR)\mod_authnz_ldap.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authnz_ldap.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authnz_ldap.so" /d LONG_NAME="authnz_ldap_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authnz_ldap.c
+
+"$(INTDIR)\mod_authnz_ldap.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_core.c b/modules/aaa/mod_authz_core.c
new file mode 100644
index 0000000..9585114
--- /dev/null
+++ b/modules/aaa/mod_authz_core.c
@@ -0,0 +1,1175 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Security options etc.
+ *
+ * Module derived from code originally written by Rob McCool
+ *
+ */
+
+#include "apr_strings.h"
+#include "apr_network_io.h"
+#include "apr_md5.h"
+
+#define APR_WANT_STRFUNC
+#define APR_WANT_BYTEFUNC
+#include "apr_want.h"
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_request.h"
+#include "http_protocol.h"
+#include "ap_provider.h"
+#include "ap_expr.h"
+
+#include "mod_auth.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#undef AUTHZ_EXTRA_CONFIGS
+
+typedef struct provider_alias_rec {
+ char *provider_name;
+ char *provider_alias;
+ char *provider_args;
+ const void *provider_parsed_args;
+ ap_conf_vector_t *sec_auth;
+ const authz_provider *provider;
+} provider_alias_rec;
+
+typedef enum {
+ AUTHZ_LOGIC_AND,
+ AUTHZ_LOGIC_OR,
+ AUTHZ_LOGIC_OFF,
+ AUTHZ_LOGIC_UNSET
+} authz_logic_op;
+
+typedef struct authz_section_conf authz_section_conf;
+
+struct authz_section_conf {
+ const char *provider_name;
+ const char *provider_args;
+ const void *provider_parsed_args;
+ const authz_provider *provider;
+ apr_int64_t limited;
+ authz_logic_op op;
+ int negate;
+ /** true if this is not a real container but produced by AuthMerging;
+ * only used for logging */
+ int is_merged;
+ authz_section_conf *first;
+ authz_section_conf *next;
+};
+
+typedef struct authz_core_dir_conf authz_core_dir_conf;
+
+struct authz_core_dir_conf {
+ authz_section_conf *section;
+ authz_core_dir_conf *next;
+ authz_logic_op op;
+ signed char authz_forbidden_on_fail;
+};
+
+#define UNSET -1
+
+typedef struct authz_core_srv_conf {
+ apr_hash_t *alias_rec;
+} authz_core_srv_conf;
+
+module AP_MODULE_DECLARE_DATA authz_core_module;
+
+static authz_core_dir_conf *authz_core_first_dir_conf;
+
+static void *create_authz_core_dir_config(apr_pool_t *p, char *dummy)
+{
+ authz_core_dir_conf *conf = apr_pcalloc(p, sizeof(*conf));
+
+ conf->op = AUTHZ_LOGIC_UNSET;
+ conf->authz_forbidden_on_fail = UNSET;
+
+ conf->next = authz_core_first_dir_conf;
+ authz_core_first_dir_conf = conf;
+
+ return (void *)conf;
+}
+
+static void *merge_authz_core_dir_config(apr_pool_t *p,
+ void *basev, void *newv)
+{
+ authz_core_dir_conf *base = (authz_core_dir_conf *)basev;
+ authz_core_dir_conf *new = (authz_core_dir_conf *)newv;
+ authz_core_dir_conf *conf;
+
+ if (new->op == AUTHZ_LOGIC_UNSET && !new->section && base->section ) {
+ /* Only authz_forbidden_on_fail has been set in new. Don't treat
+ * it as a new auth config w.r.t. AuthMerging */
+ conf = apr_pmemdup(p, base, sizeof(*base));
+ }
+ else if (new->op == AUTHZ_LOGIC_OFF || new->op == AUTHZ_LOGIC_UNSET ||
+ !(base->section || new->section)) {
+ conf = apr_pmemdup(p, new, sizeof(*new));
+ }
+ else {
+ authz_section_conf *section;
+
+ if (base->section) {
+ if (new->section) {
+ section = apr_pcalloc(p, sizeof(*section));
+
+ section->limited =
+ base->section->limited | new->section->limited;
+
+ section->op = new->op;
+ section->is_merged = 1;
+
+ section->first = apr_pmemdup(p, base->section,
+ sizeof(*base->section));
+ section->first->next = apr_pmemdup(p, new->section,
+ sizeof(*new->section));
+ } else {
+ section = apr_pmemdup(p, base->section,
+ sizeof(*base->section));
+ }
+ }
+ else {
+ section = apr_pmemdup(p, new->section, sizeof(*new->section));
+ }
+
+ conf = apr_pcalloc(p, sizeof(*conf));
+
+ conf->section = section;
+ conf->op = new->op;
+ }
+
+ if (new->authz_forbidden_on_fail == UNSET)
+ conf->authz_forbidden_on_fail = base->authz_forbidden_on_fail;
+ else
+ conf->authz_forbidden_on_fail = new->authz_forbidden_on_fail;
+
+ return (void*)conf;
+}
+
+/* Only per-server directive we have is GLOBAL_ONLY */
+static void *merge_authz_core_svr_config(apr_pool_t *p,
+ void *basev, void *newv)
+{
+ return basev;
+}
+
+static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s)
+{
+ authz_core_srv_conf *authcfg;
+
+ authcfg = apr_pcalloc(p, sizeof(*authcfg));
+ authcfg->alias_rec = apr_hash_make(p);
+
+ return (void *)authcfg;
+}
+
+/* This is a fake authz provider that really merges various authz alias
+ * configurations and then invokes them.
+ */
+static authz_status authz_alias_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ const char *provider_name;
+ authz_status ret = AUTHZ_DENIED;
+
+ /* Look up the provider alias in the alias list.
+ * Get the dir_config and call ap_Merge_per_dir_configs()
+ * Call the real provider->check_authorization() function
+ * return the result of the above function call
+ */
+
+ provider_name = apr_table_get(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
+
+ if (provider_name) {
+ authz_core_srv_conf *authcfg;
+ provider_alias_rec *prvdraliasrec;
+
+ authcfg = ap_get_module_config(r->server->module_config,
+ &authz_core_module);
+
+ prvdraliasrec = apr_hash_get(authcfg->alias_rec, provider_name,
+ APR_HASH_KEY_STRING);
+
+ /* If we found the alias provider in the list, then merge the directory
+ configurations and call the real provider */
+ if (prvdraliasrec) {
+ ap_conf_vector_t *orig_dir_config = r->per_dir_config;
+
+ r->per_dir_config =
+ ap_merge_per_dir_configs(r->pool, orig_dir_config,
+ prvdraliasrec->sec_auth);
+
+ ret = prvdraliasrec->provider->
+ check_authorization(r, prvdraliasrec->provider_args,
+ prvdraliasrec->provider_parsed_args);
+
+ r->per_dir_config = orig_dir_config;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02305)
+ "no alias provider found for '%s' (BUG?)",
+ provider_name);
+ }
+ }
+ else {
+ ap_assert(provider_name != NULL);
+ }
+
+ return ret;
+}
+
+static const authz_provider authz_alias_provider =
+{
+ &authz_alias_check_authorization,
+ NULL,
+};
+
+static const char *authz_require_alias_section(cmd_parms *cmd, void *mconfig,
+ const char *args)
+{
+ const char *endp = ap_strrchr_c(args, '>');
+ char *provider_name;
+ char *provider_alias;
+ char *provider_args, *extra_args;
+ ap_conf_vector_t *new_authz_config;
+ int old_overrides = cmd->override;
+ const char *errmsg;
+
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
+
+ if (endp == NULL) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive missing closing '>'", NULL);
+ }
+
+ args = apr_pstrndup(cmd->temp_pool, args, endp - args);
+
+ if (!args[0]) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive requires additional arguments", NULL);
+ }
+
+ /* Pull the real provider name and the alias name from the block header */
+ provider_name = ap_getword_conf(cmd->pool, &args);
+ provider_alias = ap_getword_conf(cmd->pool, &args);
+ provider_args = ap_getword_conf(cmd->pool, &args);
+ extra_args = ap_getword_conf(cmd->pool, &args);
+
+ if (!provider_name[0] || !provider_alias[0]) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive requires additional arguments", NULL);
+ }
+
+ /* We only handle one "Require-Parameters" parameter. If several parameters
+ are needed, they must be enclosed between quotes */
+ if (extra_args && *extra_args) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server, APLOGNO(10142)
+ "When several arguments (%s %s...) are passed to a %s directive, "
+ "they must be enclosed in quotation marks. Otherwise, only the "
+ "first one is taken into account",
+ provider_args, extra_args, cmd->cmd->name);
+ }
+
+ new_authz_config = ap_create_per_dir_config(cmd->pool);
+
+ /* Walk the subsection configuration to get the per_dir config that we will
+ * merge just before the real provider is called.
+ */
+ cmd->override = OR_AUTHCFG | ACCESS_CONF;
+ errmsg = ap_walk_config(cmd->directive->first_child, cmd,
+ new_authz_config);
+ cmd->override = old_overrides;
+
+ if (!errmsg) {
+ provider_alias_rec *prvdraliasrec;
+ authz_core_srv_conf *authcfg;
+
+ prvdraliasrec = apr_pcalloc(cmd->pool, sizeof(*prvdraliasrec));
+
+ /* Save off the new directory config along with the original
+ * provider name and function pointer data
+ */
+ prvdraliasrec->provider_name = provider_name;
+ prvdraliasrec->provider_alias = provider_alias;
+ prvdraliasrec->provider_args = provider_args;
+ prvdraliasrec->sec_auth = new_authz_config;
+ prvdraliasrec->provider =
+ ap_lookup_provider(AUTHZ_PROVIDER_GROUP, provider_name,
+ AUTHZ_PROVIDER_VERSION);
+
+ /* by the time the config file is used, the provider should be loaded
+ * and registered with us.
+ */
+ if (!prvdraliasrec->provider) {
+ return apr_psprintf(cmd->pool,
+ "Unknown Authz provider: %s",
+ provider_name);
+ }
+ if (prvdraliasrec->provider->parse_require_line) {
+ err = prvdraliasrec->provider->parse_require_line(cmd,
+ provider_args, &prvdraliasrec->provider_parsed_args);
+ if (err)
+ return apr_psprintf(cmd->pool,
+ "Can't parse 'Require %s %s': %s",
+ provider_name, provider_args, err);
+ }
+
+ authcfg = ap_get_module_config(cmd->server->module_config,
+ &authz_core_module);
+
+ apr_hash_set(authcfg->alias_rec, provider_alias,
+ APR_HASH_KEY_STRING, prvdraliasrec);
+
+ /* Register the fake provider so that we get called first */
+ ap_register_auth_provider(cmd->pool, AUTHZ_PROVIDER_GROUP,
+ provider_alias, AUTHZ_PROVIDER_VERSION,
+ &authz_alias_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ }
+
+ return errmsg;
+}
+
+static const char* format_authz_result(authz_status result)
+{
+ return ((result == AUTHZ_DENIED)
+ ? "denied"
+ : ((result == AUTHZ_GRANTED)
+ ? "granted"
+ : ((result == AUTHZ_DENIED_NO_USER)
+ ? "denied (no authenticated user yet)"
+ : "neutral")));
+}
+
+static const char* format_authz_command(apr_pool_t *p,
+ authz_section_conf *section)
+{
+ return (section->provider
+ ? apr_pstrcat(p, "Require ", (section->negate ? "not " : ""),
+ section->provider_name, " ",
+ section->provider_args, NULL)
+ : apr_pstrcat(p, section->is_merged ? "AuthMerging " : "<Require",
+ ((section->op == AUTHZ_LOGIC_AND)
+ ? (section->negate ? "NotAll" : "All")
+ : (section->negate ? "None" : "Any")),
+ section->is_merged ? "" : ">", NULL));
+}
+
+static authz_section_conf* create_default_section(apr_pool_t *p)
+{
+ authz_section_conf *section = apr_pcalloc(p, sizeof(*section));
+
+ section->op = AUTHZ_LOGIC_OR;
+
+ return section;
+}
+
+static const char *add_authz_provider(cmd_parms *cmd, void *config,
+ const char *args)
+{
+ authz_core_dir_conf *conf = (authz_core_dir_conf*)config;
+ authz_section_conf *section = apr_pcalloc(cmd->pool, sizeof(*section));
+ authz_section_conf *child;
+
+ section->provider_name = ap_getword_conf(cmd->pool, &args);
+
+ if (!strcasecmp(section->provider_name, "not")) {
+ section->provider_name = ap_getword_conf(cmd->pool, &args);
+ section->negate = 1;
+ }
+
+ section->provider_args = args;
+
+ /* lookup and cache the actual provider now */
+ section->provider = ap_lookup_provider(AUTHZ_PROVIDER_GROUP,
+ section->provider_name,
+ AUTHZ_PROVIDER_VERSION);
+
+ /* by the time the config file is used, the provider should be loaded
+ * and registered with us.
+ */
+ if (!section->provider) {
+ return apr_psprintf(cmd->pool,
+ "Unknown Authz provider: %s",
+ section->provider_name);
+ }
+
+ /* if the provider doesn't provide the appropriate function, reject it */
+ if (!section->provider->check_authorization) {
+ return apr_psprintf(cmd->pool,
+ "The '%s' Authz provider is not supported by any "
+ "of the loaded authorization modules",
+ section->provider_name);
+ }
+
+ section->limited = cmd->limited;
+
+ if (section->provider->parse_require_line) {
+ const char *err;
+ apr_pool_userdata_setn(section->provider_name,
+ AUTHZ_PROVIDER_NAME_NOTE,
+ apr_pool_cleanup_null,
+ cmd->temp_pool);
+ err = section->provider->parse_require_line(cmd, args,
+ &section->provider_parsed_args);
+
+ if (err)
+ return err;
+ }
+
+ if (!conf->section) {
+ conf->section = create_default_section(cmd->pool);
+ }
+
+ if (section->negate && conf->section->op == AUTHZ_LOGIC_OR) {
+ return apr_psprintf(cmd->pool, "negative %s directive has no effect "
+ "in %s directive",
+ cmd->cmd->name,
+ format_authz_command(cmd->pool, conf->section));
+ }
+
+ conf->section->limited |= section->limited;
+
+ child = conf->section->first;
+
+ if (child) {
+ while (child->next) {
+ child = child->next;
+ }
+
+ child->next = section;
+ }
+ else {
+ conf->section->first = section;
+ }
+
+ return NULL;
+}
+
+static const char *add_authz_section(cmd_parms *cmd, void *mconfig,
+ const char *args)
+{
+ authz_core_dir_conf *conf = mconfig;
+ const char *endp = ap_strrchr_c(args, '>');
+ authz_section_conf *old_section = conf->section;
+ authz_section_conf *section;
+ int old_overrides = cmd->override;
+ apr_int64_t old_limited = cmd->limited;
+ const char *errmsg;
+
+ if (endp == NULL) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive missing closing '>'", NULL);
+ }
+
+ args = apr_pstrndup(cmd->temp_pool, args, endp - args);
+
+ if (args[0]) {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name,
+ "> directive doesn't take additional arguments",
+ NULL);
+ }
+
+ section = apr_pcalloc(cmd->pool, sizeof(*section));
+
+ if (!strcasecmp(cmd->cmd->name, "<RequireAll")) {
+ section->op = AUTHZ_LOGIC_AND;
+ }
+ else if (!strcasecmp(cmd->cmd->name, "<RequireAny")) {
+ section->op = AUTHZ_LOGIC_OR;
+ }
+ else if (!strcasecmp(cmd->cmd->name, "<RequireNotAll")) {
+ section->op = AUTHZ_LOGIC_AND;
+ section->negate = 1;
+ }
+ else {
+ section->op = AUTHZ_LOGIC_OR;
+ section->negate = 1;
+ }
+
+ conf->section = section;
+
+ /* trigger NOT_IN_LIMIT errors as if this were a <Limit> directive */
+ cmd->limited &= ~(AP_METHOD_BIT << (METHODS - 1));
+
+ cmd->override = OR_AUTHCFG;
+ errmsg = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
+ cmd->override = old_overrides;
+
+ cmd->limited = old_limited;
+
+ conf->section = old_section;
+
+ if (errmsg) {
+ return errmsg;
+ }
+
+ if (section->first) {
+ authz_section_conf *child;
+
+ if (!old_section) {
+ old_section = conf->section = create_default_section(cmd->pool);
+ }
+
+ if (section->negate && old_section->op == AUTHZ_LOGIC_OR) {
+ return apr_psprintf(cmd->pool, "%s directive has "
+ "no effect in %s directive",
+ format_authz_command(cmd->pool, section),
+ format_authz_command(cmd->pool, old_section));
+ }
+
+ old_section->limited |= section->limited;
+
+ if (!section->negate && section->op == old_section->op) {
+ /* be associative */
+ section = section->first;
+ }
+
+ child = old_section->first;
+
+ if (child) {
+ while (child->next) {
+ child = child->next;
+ }
+
+ child->next = section;
+ }
+ else {
+ old_section->first = section;
+ }
+ }
+ else {
+ return apr_pstrcat(cmd->pool,
+ format_authz_command(cmd->pool, section),
+ " directive contains no authorization directives",
+ NULL);
+ }
+
+ return NULL;
+}
+
+static const char *authz_merge_sections(cmd_parms *cmd, void *mconfig,
+ const char *arg)
+{
+ authz_core_dir_conf *conf = mconfig;
+
+ if (!strcasecmp(arg, "Off")) {
+ conf->op = AUTHZ_LOGIC_OFF;
+ }
+ else if (!strcasecmp(arg, "And")) {
+ conf->op = AUTHZ_LOGIC_AND;
+ }
+ else if (!strcasecmp(arg, "Or")) {
+ conf->op = AUTHZ_LOGIC_OR;
+ }
+ else {
+ return apr_pstrcat(cmd->pool, cmd->cmd->name, " must be one of: "
+ "Off | And | Or", NULL);
+ }
+
+ return NULL;
+}
+
+static int authz_core_check_section(apr_pool_t *p, server_rec *s,
+ authz_section_conf *section, int is_conf)
+{
+ authz_section_conf *prev = NULL;
+ authz_section_conf *child = section->first;
+ int ret = !OK;
+
+ while (child) {
+ if (child->first) {
+ if (authz_core_check_section(p, s, child, 0) != OK) {
+ return !OK;
+ }
+
+ if (child->negate && child->op != section->op) {
+ authz_section_conf *next = child->next;
+
+ /* avoid one level of recursion when De Morgan permits */
+ child = child->first;
+
+ if (prev) {
+ prev->next = child;
+ }
+ else {
+ section->first = child;
+ }
+
+ do {
+ child->negate = !child->negate;
+ } while (child->next && (child = child->next));
+
+ child->next = next;
+ }
+ }
+
+ prev = child;
+ child = child->next;
+ }
+
+ child = section->first;
+
+ while (child) {
+ if (!child->negate) {
+ ret = OK;
+ break;
+ }
+
+ child = child->next;
+ }
+
+ if (ret != OK) {
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_STARTUP, APR_SUCCESS, s, APLOGNO(01624)
+ "%s directive contains only negative authorization directives",
+ is_conf ? "<Directory>, <Location>, or similar"
+ : format_authz_command(p, section));
+ }
+
+ return ret;
+}
+
+static int authz_core_pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ authz_core_first_dir_conf = NULL;
+
+ return OK;
+}
+
+static int authz_core_check_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ authz_core_dir_conf *conf = authz_core_first_dir_conf;
+
+ while (conf) {
+ if (conf->section) {
+ if (authz_core_check_section(p, s, conf->section, 1) != OK) {
+ return !OK;
+ }
+ }
+
+ conf = conf->next;
+ }
+
+ return OK;
+}
+
+static const command_rec authz_cmds[] =
+{
+ AP_INIT_RAW_ARGS("<AuthzProviderAlias", authz_require_alias_section,
+ NULL, RSRC_CONF,
+ "container for grouping an authorization provider's "
+ "directives under a provider alias"),
+ AP_INIT_RAW_ARGS("Require", add_authz_provider, NULL, OR_AUTHCFG,
+ "specifies authorization directives "
+ "which one must pass (or not) for a request to suceeed"),
+ AP_INIT_RAW_ARGS("<RequireAll", add_authz_section, NULL, OR_AUTHCFG,
+ "container for grouping authorization directives "
+ "of which none must fail and at least one must pass "
+ "for a request to succeed"),
+ AP_INIT_RAW_ARGS("<RequireAny", add_authz_section, NULL, OR_AUTHCFG,
+ "container for grouping authorization directives "
+ "of which one must pass "
+ "for a request to succeed"),
+#ifdef AUTHZ_EXTRA_CONFIGS
+ AP_INIT_RAW_ARGS("<RequireNotAll", add_authz_section, NULL, OR_AUTHCFG,
+ "container for grouping authorization directives "
+ "of which some must fail or none must pass "
+ "for a request to succeed"),
+#endif
+ AP_INIT_RAW_ARGS("<RequireNone", add_authz_section, NULL, OR_AUTHCFG,
+ "container for grouping authorization directives "
+ "of which none must pass "
+ "for a request to succeed"),
+ AP_INIT_TAKE1("AuthMerging", authz_merge_sections, NULL, OR_AUTHCFG,
+ "controls how a <Directory>, <Location>, or similar "
+ "directive's authorization directives are combined with "
+ "those of its predecessor"),
+ AP_INIT_FLAG("AuthzSendForbiddenOnFailure", ap_set_flag_slot_char,
+ (void *)APR_OFFSETOF(authz_core_dir_conf, authz_forbidden_on_fail),
+ OR_AUTHCFG,
+ "Controls if an authorization failure should result in a "
+ "'403 FORBIDDEN' response instead of the HTTP-conforming "
+ "'401 UNAUTHORIZED'"),
+ {NULL}
+};
+
+static authz_status apply_authz_sections(request_rec *r,
+ authz_section_conf *section,
+ authz_logic_op parent_op)
+{
+ authz_status auth_result;
+
+ /* check to make sure that the request method requires authorization */
+ if (!(section->limited & (AP_METHOD_BIT << r->method_number))) {
+ auth_result =
+ (parent_op == AUTHZ_LOGIC_AND) ? AUTHZ_GRANTED : AUTHZ_NEUTRAL;
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01625)
+ "authorization result of %s: %s "
+ "(directive limited to other methods)",
+ format_authz_command(r->pool, section),
+ format_authz_result(auth_result));
+
+ return auth_result;
+ }
+
+ if (section->provider) {
+ apr_table_setn(r->notes, AUTHZ_PROVIDER_NAME_NOTE,
+ section->provider_name);
+
+ auth_result =
+ section->provider->check_authorization(r, section->provider_args,
+ section->provider_parsed_args);
+
+ apr_table_unset(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
+ }
+ else {
+ authz_section_conf *child = section->first;
+
+ auth_result = AUTHZ_NEUTRAL;
+
+ while (child) {
+ authz_status child_result;
+
+ child_result = apply_authz_sections(r, child, section->op);
+
+ if (child_result == AUTHZ_GENERAL_ERROR) {
+ return AUTHZ_GENERAL_ERROR;
+ }
+
+ if (child_result != AUTHZ_NEUTRAL) {
+ /*
+ * Handling of AUTHZ_DENIED/AUTHZ_DENIED_NO_USER: Return
+ * AUTHZ_DENIED_NO_USER if providing a user may change the
+ * result, AUTHZ_DENIED otherwise.
+ */
+ if (section->op == AUTHZ_LOGIC_AND) {
+ if (child_result == AUTHZ_DENIED) {
+ auth_result = child_result;
+ break;
+ }
+ if ((child_result == AUTHZ_DENIED_NO_USER
+ && auth_result != AUTHZ_DENIED)
+ || (auth_result == AUTHZ_NEUTRAL)) {
+ auth_result = child_result;
+ }
+ }
+ else {
+ /* AUTHZ_LOGIC_OR */
+ if (child_result == AUTHZ_GRANTED) {
+ auth_result = child_result;
+ break;
+ }
+ if ((child_result == AUTHZ_DENIED_NO_USER
+ && auth_result == AUTHZ_DENIED)
+ || (auth_result == AUTHZ_NEUTRAL)) {
+ auth_result = child_result;
+ }
+ }
+ }
+
+ child = child->next;
+ }
+ }
+
+ if (section->negate) {
+ if (auth_result == AUTHZ_GRANTED) {
+ auth_result = AUTHZ_DENIED;
+ }
+ else if (auth_result == AUTHZ_DENIED ||
+ auth_result == AUTHZ_DENIED_NO_USER) {
+ /* For negated directives, if the original result was denied
+ * then the new result is neutral since we can not grant
+ * access simply because authorization was not rejected.
+ */
+ auth_result = AUTHZ_NEUTRAL;
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01626)
+ "authorization result of %s: %s",
+ format_authz_command(r->pool, section),
+ format_authz_result(auth_result));
+
+ return auth_result;
+}
+
+static int authorize_user_core(request_rec *r, int after_authn)
+{
+ authz_core_dir_conf *conf;
+ authz_status auth_result;
+
+ conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
+
+ if (!conf->section) {
+ if (ap_auth_type(r)) {
+ /* there's an AuthType configured, but no authorization
+ * directives applied to support it
+ */
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01627)
+ "AuthType configured with no corresponding "
+ "authorization directives");
+
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01628)
+ "authorization result: granted (no directives)");
+
+ return OK;
+ }
+
+ auth_result = apply_authz_sections(r, conf->section, AUTHZ_LOGIC_AND);
+
+ if (auth_result == AUTHZ_GRANTED) {
+ return OK;
+ }
+ else if (auth_result == AUTHZ_DENIED_NO_USER) {
+ if (after_authn) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01629)
+ "authorization failure (no authenticated user): %s",
+ r->uri);
+ /*
+ * If we're returning 401 to an authenticated user, tell them to
+ * try again. If unauthenticated, note_auth_failure has already
+ * been called during auth.
+ */
+ if (r->user)
+ ap_note_auth_failure(r);
+
+ return HTTP_UNAUTHORIZED;
+ }
+ else {
+ /*
+ * We need a user before we can decide what to do.
+ * Get out of the way and proceed with authentication.
+ */
+ return DECLINED;
+ }
+ }
+ else if (auth_result == AUTHZ_DENIED || auth_result == AUTHZ_NEUTRAL) {
+ if (!after_authn || ap_auth_type(r) == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01630)
+ "client denied by server configuration: %s%s",
+ r->filename ? "" : "uri ",
+ r->filename ? r->filename : r->uri);
+
+ return HTTP_FORBIDDEN;
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r, APLOGNO(01631)
+ "user %s: authorization failure for \"%s\": ",
+ r->user, r->uri);
+
+ if (conf->authz_forbidden_on_fail > 0) {
+ return HTTP_FORBIDDEN;
+ }
+ else {
+ /*
+ * If we're returning 401 to an authenticated user, tell them to
+ * try again. If unauthenticated, note_auth_failure has already
+ * been called during auth.
+ */
+ if (r->user)
+ ap_note_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+ }
+ }
+ }
+ else {
+ /* We'll assume that the module has already said what its
+ * error was in the logs.
+ */
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+}
+
+static int authorize_userless(request_rec *r)
+{
+ return authorize_user_core(r, 0);
+}
+
+static int authorize_user(request_rec *r)
+{
+ return authorize_user_core(r, 1);
+}
+
+static int authz_some_auth_required(request_rec *r)
+{
+ authz_core_dir_conf *conf;
+
+ conf = ap_get_module_config(r->per_dir_config, &authz_core_module);
+
+ if (conf->section
+ && (conf->section->limited & (AP_METHOD_BIT << r->method_number))) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * env authz provider
+ */
+
+static authz_status env_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *t, *w;
+
+ /* The 'env' provider will allow the configuration to specify a list of
+ env variables to check rather than a single variable. This is different
+ from the previous host based syntax. */
+ t = require_line;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ if (apr_table_get(r->subprocess_env, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+
+ return AUTHZ_DENIED;
+}
+
+static const authz_provider authz_env_provider =
+{
+ &env_check_authorization,
+ NULL,
+};
+
+
+/*
+ * all authz provider
+ */
+
+static authz_status all_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ if (parsed_require_line) {
+ return AUTHZ_GRANTED;
+ }
+ return AUTHZ_DENIED;
+}
+
+static const char *all_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ /*
+ * If the argument to the 'all' provider is 'granted' then just let
+ * everybody in. This would be equivalent to the previous syntax of
+ * 'allow from all'. If the argument is 'denied' we reject everybody,
+ * which is equivalent to 'deny from all'.
+ */
+ if (strcasecmp(require_line, "granted") == 0) {
+ *parsed_require_line = (void *)1;
+ return NULL;
+ }
+ else if (strcasecmp(require_line, "denied") == 0) {
+ /* *parsed_require_line is already NULL */
+ return NULL;
+ }
+ else {
+ return "Argument for 'Require all' must be 'granted' or 'denied'";
+ }
+}
+
+static const authz_provider authz_all_provider =
+{
+ &all_check_authorization,
+ &all_parse_config,
+};
+
+
+/*
+ * method authz provider
+ */
+
+static authz_status method_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const apr_int64_t *allowed = parsed_require_line;
+ if (*allowed & (AP_METHOD_BIT << r->method_number))
+ return AUTHZ_GRANTED;
+ else
+ return AUTHZ_DENIED;
+}
+
+static const char *method_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *w, *t;
+ apr_int64_t *allowed = apr_pcalloc(cmd->pool, sizeof(apr_int64_t));
+
+ t = require_line;
+
+ while ((w = ap_getword_conf(cmd->temp_pool, &t)) && w[0]) {
+ int m = ap_method_number_of(w);
+ if (m == M_INVALID) {
+ return apr_pstrcat(cmd->pool, "Invalid Method '", w, "'", NULL);
+ }
+
+ *allowed |= (AP_METHOD_BIT << m);
+ }
+
+ *parsed_require_line = allowed;
+ return NULL;
+}
+
+static const authz_provider authz_method_provider =
+{
+ &method_check_authorization,
+ &method_parse_config,
+};
+
+/*
+ * expr authz provider
+ */
+
+#define REQUIRE_EXPR_NOTE "Require_expr_info"
+struct require_expr_info {
+ ap_expr_info_t *expr;
+ int want_user;
+};
+
+static int expr_lookup_fn(ap_expr_lookup_parms *parms)
+{
+ if (parms->type == AP_EXPR_FUNC_VAR
+ && strcasecmp(parms->name, "REMOTE_USER") == 0) {
+ struct require_expr_info *info;
+ apr_pool_userdata_get((void**)&info, REQUIRE_EXPR_NOTE, parms->ptemp);
+ AP_DEBUG_ASSERT(info != NULL);
+ info->want_user = 1;
+ }
+ return ap_expr_lookup_default(parms);
+}
+
+static const char *expr_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ struct require_expr_info *info = apr_pcalloc(cmd->pool, sizeof(*info));
+
+ /* if the expression happens to be surrounded by quotes, skip them */
+ if (require_line[0] == '"') {
+ apr_size_t len = strlen(require_line);
+
+ if (require_line[len-1] == '"')
+ require_line = apr_pstrndup(cmd->temp_pool,
+ require_line + 1,
+ len - 2);
+ }
+
+ apr_pool_userdata_setn(info, REQUIRE_EXPR_NOTE, apr_pool_cleanup_null,
+ cmd->temp_pool);
+ info->expr = ap_expr_parse_cmd(cmd, require_line, 0, &expr_err,
+ expr_lookup_fn);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = info;
+
+ return NULL;
+}
+
+static authz_status expr_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *err = NULL;
+ const struct require_expr_info *info = parsed_require_line;
+ int rc = ap_expr_exec(r, info->expr, &err);
+
+ if (rc < 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02320)
+ "Error evaluating expression in 'Require expr': %s",
+ err);
+ return AUTHZ_GENERAL_ERROR;
+ }
+ else if (rc == 0) {
+ if (info->want_user)
+ return AUTHZ_DENIED_NO_USER;
+ else
+ return AUTHZ_DENIED;
+ }
+ else {
+ return AUTHZ_GRANTED;
+ }
+}
+
+static const authz_provider authz_expr_provider =
+{
+ &expr_check_authorization,
+ &expr_parse_config,
+};
+
+
+static void register_hooks(apr_pool_t *p)
+{
+ APR_REGISTER_OPTIONAL_FN(authz_some_auth_required);
+
+ ap_hook_pre_config(authz_core_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_check_config(authz_core_check_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_check_authz(authorize_user, NULL, NULL, APR_HOOK_LAST,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_check_access_ex(authorize_userless, NULL, NULL, APR_HOOK_LAST,
+ AP_AUTH_INTERNAL_PER_CONF);
+
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "env",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_env_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "all",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_all_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "method",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_method_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "expr",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authz_core) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authz_core_dir_config, /* dir config creater */
+ merge_authz_core_dir_config, /* dir merger */
+ create_authz_core_svr_config, /* server config */
+ merge_authz_core_svr_config , /* merge server config */
+ authz_cmds,
+ register_hooks /* register hooks */
+};
+
diff --git a/modules/aaa/mod_authz_core.dep b/modules/aaa/mod_authz_core.dep
new file mode 100644
index 0000000..04300cc
--- /dev/null
+++ b/modules/aaa/mod_authz_core.dep
@@ -0,0 +1,60 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_core.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_core.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authz_core.dsp b/modules/aaa/mod_authz_core.dsp
new file mode 100644
index 0000000..8e9f124
--- /dev/null
+++ b/modules/aaa/mod_authz_core.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_core" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_core - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_core.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_core.mak" CFG="mod_authz_core - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_core_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_core_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_core.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_core - Win32 Release"
+# Name "mod_authz_core - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_core.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_core.mak b/modules/aaa/mod_authz_core.mak
new file mode 100644
index 0000000..7351f67
--- /dev/null
+++ b/modules/aaa/mod_authz_core.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_core.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_core - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_core - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_core - Win32 Release" && "$(CFG)" != "mod_authz_core - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_core.mak" CFG="mod_authz_core - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_core - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_core - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_core.obj"
+ -@erase "$(INTDIR)\mod_authz_core.res"
+ -@erase "$(INTDIR)\mod_authz_core_src.idb"
+ -@erase "$(INTDIR)\mod_authz_core_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_core.exp"
+ -@erase "$(OUTDIR)\mod_authz_core.lib"
+ -@erase "$(OUTDIR)\mod_authz_core.pdb"
+ -@erase "$(OUTDIR)\mod_authz_core.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_core_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_core.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_core.pdb" /debug /out:"$(OUTDIR)\mod_authz_core.so" /implib:"$(OUTDIR)\mod_authz_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_core.obj" \
+ "$(INTDIR)\mod_authz_core.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_core.so"
+ if exist .\Release\mod_authz_core.so.manifest mt.exe -manifest .\Release\mod_authz_core.so.manifest -outputresource:.\Release\mod_authz_core.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_core.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_core.obj"
+ -@erase "$(INTDIR)\mod_authz_core.res"
+ -@erase "$(INTDIR)\mod_authz_core_src.idb"
+ -@erase "$(INTDIR)\mod_authz_core_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_core.exp"
+ -@erase "$(OUTDIR)\mod_authz_core.lib"
+ -@erase "$(OUTDIR)\mod_authz_core.pdb"
+ -@erase "$(OUTDIR)\mod_authz_core.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_core_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_core.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_core.pdb" /debug /out:"$(OUTDIR)\mod_authz_core.so" /implib:"$(OUTDIR)\mod_authz_core.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_core.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_core.obj" \
+ "$(INTDIR)\mod_authz_core.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_core.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_core.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_core.so"
+ if exist .\Debug\mod_authz_core.so.manifest mt.exe -manifest .\Debug\mod_authz_core.so.manifest -outputresource:.\Debug\mod_authz_core.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_core.dep")
+!INCLUDE "mod_authz_core.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_core.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release" || "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_core - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_core.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_core - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_core.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_core.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_core.so" /d LONG_NAME="authz_core_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_core.c
+
+"$(INTDIR)\mod_authz_core.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_dbd.c b/modules/aaa/mod_authz_dbd.c
new file mode 100644
index 0000000..e1bb623
--- /dev/null
+++ b/modules/aaa/mod_authz_dbd.c
@@ -0,0 +1,409 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "httpd.h"
+#include "http_log.h"
+#include "http_config.h"
+#include "ap_provider.h"
+#include "http_request.h"
+#include "http_protocol.h"
+#include "http_core.h"
+#include "apr_dbd.h"
+#include "mod_dbd.h"
+#include "apr_strings.h"
+#include "mod_authz_dbd.h"
+
+#include "mod_auth.h"
+
+
+module AP_MODULE_DECLARE_DATA authz_dbd_module;
+
+/* Export a hook for modules that manage clientside sessions
+ * (e.g. mod_auth_cookie)
+ * to deal with those when we successfully login/logout at the server
+ *
+ * XXX: WHY would this be specific to dbd_authz? Why wouldn't we track
+ * this across all authz user providers in a lower level mod, such as
+ * mod_auth_basic/digest?
+ */
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(authz_dbd, AUTHZ_DBD, int, client_login,
+ (request_rec *r, int code, const char *action),
+ (r, code, action), OK, DECLINED)
+
+
+typedef struct {
+ const char *query;
+ const char *redir_query;
+ int redirect;
+} authz_dbd_cfg ;
+
+static ap_dbd_t *(*dbd_handle)(request_rec*) = NULL;
+static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
+
+static const char *const noerror = "???";
+
+static void *authz_dbd_cr_cfg(apr_pool_t *pool, char *dummy)
+{
+ authz_dbd_cfg *ret = apr_pcalloc(pool, sizeof(authz_dbd_cfg));
+ ret->redirect = -1;
+ return ret;
+}
+
+static void *authz_dbd_merge_cfg(apr_pool_t *pool, void *BASE, void *ADD)
+{
+ authz_dbd_cfg *base = BASE;
+ authz_dbd_cfg *add = ADD;
+ authz_dbd_cfg *ret = apr_palloc(pool, sizeof(authz_dbd_cfg));
+
+ ret->query = (add->query == NULL) ? base->query : add->query;
+ ret->redir_query = (add->redir_query == NULL)
+ ? base->redir_query : add->redir_query;
+ ret->redirect = (add->redirect == -1) ? base->redirect : add->redirect;
+ return ret;
+}
+
+static const char *authz_dbd_prepare(cmd_parms *cmd, void *cfg,
+ const char *query)
+{
+ static unsigned int label_num = 0;
+ char *label;
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
+ if (err)
+ return err;
+
+ if (dbd_prepare == NULL) {
+ dbd_prepare = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_prepare);
+ if (dbd_prepare == NULL) {
+ return "You must load mod_dbd to enable AuthzDBD functions";
+ }
+ dbd_handle = APR_RETRIEVE_OPTIONAL_FN(ap_dbd_acquire);
+ }
+ label = apr_psprintf(cmd->pool, "authz_dbd_%d", ++label_num);
+
+ dbd_prepare(cmd->server, query, label);
+
+ /* save the label here for our own use */
+ return ap_set_string_slot(cmd, cfg, label);
+}
+
+static const command_rec authz_dbd_cmds[] = {
+ AP_INIT_FLAG("AuthzDBDLoginToReferer", ap_set_flag_slot,
+ (void*)APR_OFFSETOF(authz_dbd_cfg, redirect), ACCESS_CONF,
+ "Whether to redirect to referer on successful login"),
+ AP_INIT_TAKE1("AuthzDBDQuery", authz_dbd_prepare,
+ (void*)APR_OFFSETOF(authz_dbd_cfg, query), ACCESS_CONF,
+ "SQL query for DBD Authz or login"),
+ AP_INIT_TAKE1("AuthzDBDRedirectQuery", authz_dbd_prepare,
+ (void*)APR_OFFSETOF(authz_dbd_cfg, redir_query), ACCESS_CONF,
+ "SQL query to get per-user redirect URL after login"),
+ {NULL}
+};
+
+static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg,
+ const char *action)
+{
+ int rv;
+ const char *newuri = NULL;
+ int nrows;
+ const char *message;
+ ap_dbd_t *dbd;
+ apr_dbd_prepared_t *query;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+
+ if (cfg->query == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642)
+ "No query configured for %s!", action);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ dbd = dbd_handle(r);
+ if (dbd == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02902)
+ "No db handle available for %s! "
+ "Check your database access",
+ action);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
+ if (query == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643)
+ "Error retrieving Query for %s!", action);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows,
+ query, r->user, NULL);
+ if (rv == 0) {
+ if (nrows != 1) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644)
+ "authz_dbd: %s of user %s updated %d rows",
+ action, r->user, nrows);
+ }
+ }
+ else {
+ message = apr_dbd_error(dbd->driver, dbd->handle, rv);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01645)
+ "authz_dbd: query for %s failed; user %s [%s]",
+ action, r->user, message?message:noerror);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ if (cfg->redirect == 1) {
+ newuri = apr_table_get(r->headers_in, "Referer");
+ }
+
+ if (!newuri && cfg->redir_query) {
+ query = apr_hash_get(dbd->prepared, cfg->redir_query,
+ APR_HASH_KEY_STRING);
+ if (query == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01646)
+ "authz_dbd: no redirect query!");
+ /* OK, this is non-critical; we can just not-redirect */
+ }
+ else if ((rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle,
+ &res, query, 0, r->user, NULL)) == 0) {
+ for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
+ rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
+ if (rv != 0) {
+ message = apr_dbd_error(dbd->driver, dbd->handle, rv);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01647)
+ "authz_dbd in get_row; action=%s user=%s [%s]",
+ action, r->user, message?message:noerror);
+ }
+ else if (newuri == NULL) {
+ newuri =
+ apr_pstrdup(r->pool,
+ apr_dbd_get_entry(dbd->driver, row, 0));
+ }
+ /* we can't break out here or row won't get cleaned up */
+ }
+ }
+ else {
+ message = apr_dbd_error(dbd->driver, dbd->handle, rv);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01648)
+ "authz_dbd/redirect for %s of %s [%s]",
+ action, r->user, message?message:noerror);
+ }
+ }
+ if (newuri != NULL) {
+ r->status = HTTP_MOVED_TEMPORARILY;
+ apr_table_set(r->err_headers_out, "Location", newuri);
+ }
+ authz_dbd_run_client_login(r, OK, action);
+ return OK;
+}
+
+static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg,
+ apr_array_header_t *groups)
+{
+ /* SELECT group FROM authz WHERE user = %s */
+ int rv;
+ const char *message;
+ ap_dbd_t *dbd;
+ apr_dbd_prepared_t *query;
+ apr_dbd_results_t *res = NULL;
+ apr_dbd_row_t *row = NULL;
+
+ if (cfg->query == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01649)
+ "No query configured for dbd-group!");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ dbd = dbd_handle(r);
+ if (dbd == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02903)
+ "No db handle available for dbd-query! "
+ "Check your database access");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING);
+ if (query == NULL) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650)
+ "Error retrieving query for dbd-group!");
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ rv = apr_dbd_pvselect(dbd->driver, r->pool, dbd->handle, &res,
+ query, 0, r->user, NULL);
+ if (rv == 0) {
+ for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1);
+ rv != -1;
+ rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) {
+ if (rv == 0) {
+ APR_ARRAY_PUSH(groups, const char *) =
+ apr_pstrdup(r->pool,
+ apr_dbd_get_entry(dbd->driver, row, 0));
+ }
+ else {
+ message = apr_dbd_error(dbd->driver, dbd->handle, rv);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01651)
+ "authz_dbd in get_row; group query for user=%s [%s]",
+ r->user, message?message:noerror);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+ }
+ else {
+ message = apr_dbd_error(dbd->driver, dbd->handle, rv);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01652)
+ "authz_dbd, in groups query for %s [%s]",
+ r->user, message?message:noerror);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ return OK;
+}
+
+static authz_status dbdgroup_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ int rv;
+ const char *w;
+ apr_array_header_t *groups;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+ authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
+ &authz_dbd_module);
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ groups = apr_array_make(r->pool, 4, sizeof(const char*));
+ rv = authz_dbd_group_query(r, cfg, groups);
+ if (rv != OK) {
+ return AUTHZ_GENERAL_ERROR;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02590)
+ "authz_dbd authorize: require dbd-group: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+ while (t[0]) {
+ w = ap_getword_white(r->pool, &t);
+ if (ap_array_str_contains(groups, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status dbdlogin_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
+ &authz_dbd_module);
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ return (authz_dbd_login(r, cfg, "login") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
+}
+
+static authz_status dbdlogout_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config,
+ &authz_dbd_module);
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ return (authz_dbd_login(r, cfg, "logout") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED);
+}
+
+static const char *dbd_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err) {
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+ }
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+static const authz_provider authz_dbdgroup_provider =
+{
+ &dbdgroup_check_authorization,
+ &dbd_parse_config,
+};
+
+static const authz_provider authz_dbdlogin_provider =
+{
+ &dbdlogin_check_authorization,
+ NULL,
+};
+
+static const authz_provider authz_dbdlogout_provider =
+{
+ &dbdlogout_check_authorization,
+ NULL,
+};
+
+static void authz_dbd_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_dbdgroup_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-login",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_dbdlogin_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-logout",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_dbdlogout_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authz_dbd) =
+{
+ STANDARD20_MODULE_STUFF,
+ authz_dbd_cr_cfg,
+ authz_dbd_merge_cfg,
+ NULL,
+ NULL,
+ authz_dbd_cmds,
+ authz_dbd_hooks
+};
diff --git a/modules/aaa/mod_authz_dbd.dep b/modules/aaa/mod_authz_dbd.dep
new file mode 100644
index 0000000..6f0138b
--- /dev/null
+++ b/modules/aaa/mod_authz_dbd.dep
@@ -0,0 +1,61 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_dbd.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_dbd.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_dbd.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ "..\database\mod_dbd.h"\
+ ".\mod_authz_dbd.h"\
+
diff --git a/modules/aaa/mod_authz_dbd.dsp b/modules/aaa/mod_authz_dbd.dsp
new file mode 100644
index 0000000..abba141
--- /dev/null
+++ b/modules/aaa/mod_authz_dbd.dsp
@@ -0,0 +1,119 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_dbd" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_dbd - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbd.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbd.mak" CFG="mod_authz_dbd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_dbd_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_dbd.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_dbd - Win32 Release"
+# Name "mod_authz_dbd - Win32 Debug"
+# Begin Source File
+
+SOURCE=..\database\mod_dbd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_authz_dbd.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mod_authz_dbd.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_dbd.h b/modules/aaa/mod_authz_dbd.h
new file mode 100644
index 0000000..5d55a8e
--- /dev/null
+++ b/modules/aaa/mod_authz_dbd.h
@@ -0,0 +1,44 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOD_AUTHZ_DBD_H
+#define MOD_AUTHZ_DBD_H
+#include "httpd.h"
+
+/* Create a set of AUTHZ_DBD_DECLARE(type), AUTHZ_DBD_DECLARE_NONSTD(type) and
+ * AUTHZ_DBD_DECLARE_DATA with appropriate export and import tags
+ */
+#if !defined(WIN32)
+#define AUTHZ_DBD_DECLARE(type) type
+#define AUTHZ_DBD_DECLARE_NONSTD(type) type
+#define AUTHZ_DBD_DECLARE_DATA
+#elif defined(AUTHZ_DBD_DECLARE_STATIC)
+#define AUTHZ_DBD_DECLARE(type) type __stdcall
+#define AUTHZ_DBD_DECLARE_NONSTD(type) type
+#define AUTHZ_DBD_DECLARE_DATA
+#elif defined(AUTHZ_DBD_DECLARE_EXPORT)
+#define AUTHZ_DBD_DECLARE(type) __declspec(dllexport) type __stdcall
+#define AUTHZ_DBD_DECLARE_NONSTD(type) __declspec(dllexport) type
+#define AUTHZ_DBD_DECLARE_DATA __declspec(dllexport)
+#else
+#define AUTHZ_DBD_DECLARE(type) __declspec(dllimport) type __stdcall
+#define AUTHZ_DBD_DECLARE_NONSTD(type) __declspec(dllimport) type
+#define AUTHZ_DBD_DECLARE_DATA __declspec(dllimport)
+#endif
+
+APR_DECLARE_EXTERNAL_HOOK(authz_dbd, AUTHZ_DBD, int, client_login,
+ (request_rec *r, int code, const char *action))
+#endif
diff --git a/modules/aaa/mod_authz_dbd.mak b/modules/aaa/mod_authz_dbd.mak
new file mode 100644
index 0000000..da7a453
--- /dev/null
+++ b/modules/aaa/mod_authz_dbd.mak
@@ -0,0 +1,409 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_dbd.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_dbd - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_dbd - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_dbd - Win32 Release" && "$(CFG)" != "mod_authz_dbd - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbd.mak" CFG="mod_authz_dbd - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_dbd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_dbd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_dbd - Win32 Release" "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN" "mod_dbd - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_dbd.obj"
+ -@erase "$(INTDIR)\mod_authz_dbd.res"
+ -@erase "$(INTDIR)\mod_authz_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_authz_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbd.exp"
+ -@erase "$(OUTDIR)\mod_authz_dbd.lib"
+ -@erase "$(OUTDIR)\mod_authz_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbd_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbd.so" /implib:"$(OUTDIR)\mod_authz_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_dbd.obj" \
+ "$(INTDIR)\mod_authz_dbd.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib" \
+ "..\database\Release\mod_dbd.lib"
+
+"$(OUTDIR)\mod_authz_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbd.so"
+ if exist .\Release\mod_authz_dbd.so.manifest mt.exe -manifest .\Release\mod_authz_dbd.so.manifest -outputresource:.\Release\mod_authz_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_dbd - Win32 Debug" "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_dbd.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN" "mod_dbd - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_dbd.obj"
+ -@erase "$(INTDIR)\mod_authz_dbd.res"
+ -@erase "$(INTDIR)\mod_authz_dbd_src.idb"
+ -@erase "$(INTDIR)\mod_authz_dbd_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbd.exp"
+ -@erase "$(OUTDIR)\mod_authz_dbd.lib"
+ -@erase "$(OUTDIR)\mod_authz_dbd.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbd.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../database" /D "AUTHZ_DBD_DECLARE_EXPORT" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbd_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbd.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbd.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbd.so" /implib:"$(OUTDIR)\mod_authz_dbd.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbd.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_dbd.obj" \
+ "$(INTDIR)\mod_authz_dbd.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib" \
+ "..\database\Debug\mod_dbd.lib"
+
+"$(OUTDIR)\mod_authz_dbd.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_dbd.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbd.so"
+ if exist .\Debug\mod_authz_dbd.so.manifest mt.exe -manifest .\Debug\mod_authz_dbd.so.manifest -outputresource:.\Debug\mod_authz_dbd.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_dbd.dep")
+!INCLUDE "mod_authz_dbd.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_dbd.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release" || "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+"mod_dbd - Win32 Release" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release"
+ cd "..\aaa"
+
+"mod_dbd - Win32 ReleaseCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Release" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+"mod_dbd - Win32 Debug" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug"
+ cd "..\aaa"
+
+"mod_dbd - Win32 DebugCLEAN" :
+ cd ".\..\database"
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_dbd.mak" CFG="mod_dbd - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\aaa"
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_dbd - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_dbd - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_dbd.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbd.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_dbd.so" /d LONG_NAME="authz_dbd_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_dbd.c
+
+"$(INTDIR)\mod_authz_dbd.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_dbm.c b/modules/aaa/mod_authz_dbm.c
new file mode 100644
index 0000000..843d9a8
--- /dev/null
+++ b/modules/aaa/mod_authz_dbm.c
@@ -0,0 +1,336 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define APR_WANT_STRFUNC
+#include "apr_want.h"
+#include "apr_strings.h"
+#include "apr_dbm.h"
+#include "apr_md5.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "ap_provider.h"
+#include "http_core.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/
+
+#include "mod_auth.h"
+#include "mod_authz_owner.h"
+
+typedef struct {
+ const char *grpfile;
+ const char *dbmtype;
+} authz_dbm_config_rec;
+
+
+/* This should go into APR; perhaps with some nice
+ * caching/locking/flocking of the open dbm file.
+ */
+static char *get_dbm_entry_as_str(apr_pool_t *pool, apr_dbm_t *f, char *key)
+{
+ apr_datum_t d, q;
+ q.dptr = key;
+
+#ifndef NETSCAPE_DBM_COMPAT
+ q.dsize = strlen(q.dptr);
+#else
+ q.dsize = strlen(q.dptr) + 1;
+#endif
+
+ if (apr_dbm_fetch(f, q, &d) == APR_SUCCESS && d.dptr) {
+ return apr_pstrmemdup(pool, d.dptr, d.dsize);
+ }
+
+ return NULL;
+}
+
+static void *create_authz_dbm_dir_config(apr_pool_t *p, char *d)
+{
+ authz_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ conf->grpfile = NULL;
+ conf->dbmtype = "default";
+
+ return conf;
+}
+
+static const command_rec authz_dbm_cmds[] =
+{
+ AP_INIT_TAKE1("AuthDBMGroupFile", ap_set_file_slot,
+ (void *)APR_OFFSETOF(authz_dbm_config_rec, grpfile),
+ OR_AUTHCFG, "database file containing group names and member user IDs"),
+ AP_INIT_TAKE1("AuthzDBMType", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authz_dbm_config_rec, dbmtype),
+ OR_AUTHCFG, "what type of DBM file the group file is"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authz_dbm_module;
+
+/* We do something strange with the group file. If the group file
+ * contains any : we assume the format is
+ * key=username value=":"groupname [":"anything here is ignored]
+ * otherwise we now (0.8.14+) assume that the format is
+ * key=username value=groupname
+ * The first allows the password and group files to be the same
+ * physical DBM file; key=username value=password":"groupname[":"anything]
+ *
+ * mark@telescope.org, 22Sep95
+ */
+
+static apr_status_t get_dbm_grp(request_rec *r, char *key1, char *key2,
+ const char *dbmgrpfile, const char *dbtype,
+ const char ** out)
+{
+ char *grp_colon, *val;
+ apr_status_t retval;
+ apr_dbm_t *f;
+
+ retval = apr_dbm_open_ex(&f, dbtype, dbmgrpfile, APR_DBM_READONLY,
+ APR_OS_DEFAULT, r->pool);
+
+ if (retval != APR_SUCCESS) {
+ return retval;
+ }
+
+ /* Try key2 only if key1 failed */
+ if (!(val = get_dbm_entry_as_str(r->pool, f, key1))) {
+ val = get_dbm_entry_as_str(r->pool, f, key2);
+ }
+
+ apr_dbm_close(f);
+
+ if (val && (grp_colon = ap_strchr(val, ':')) != NULL) {
+ char *grp_colon2 = ap_strchr(++grp_colon, ':');
+
+ if (grp_colon2) {
+ *grp_colon2 = '\0';
+ }
+ *out = grp_colon;
+ }
+ else {
+ *out = val;
+ }
+
+ return retval;
+}
+
+static authz_status dbmgroup_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authz_dbm_module);
+ char *user = r->user;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t;
+ char *w;
+ const char *orig_groups = NULL;
+ const char *realm = ap_auth_name(r);
+ const char *groups;
+ char *v;
+
+ if (!user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!conf->grpfile) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01798)
+ "No group file was specified in the configuration");
+ return AUTHZ_DENIED;
+ }
+
+ /* fetch group data from dbm file only once. */
+ if (!orig_groups) {
+ apr_status_t status;
+
+ status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
+ user, conf->grpfile, conf->dbmtype, &groups);
+
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01799)
+ "could not open dbm (type %s) group access "
+ "file: %s", conf->dbmtype, conf->grpfile);
+ return AUTHZ_GENERAL_ERROR;
+ }
+
+ if (groups == NULL) {
+ /* no groups available, so exit immediately */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01800)
+ "Authorization of user %s to access %s failed, reason: "
+ "user doesn't appear in DBM group file (%s).",
+ r->user, r->uri, conf->grpfile);
+ return AUTHZ_DENIED;
+ }
+
+ orig_groups = groups;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02591)
+ "authz_dbm authorize: require dbm-group: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+ while ((w = ap_getword_white(r->pool, &t)) && w[0]) {
+ groups = orig_groups;
+ while (groups[0]) {
+ v = ap_getword(r->pool, &groups, ',');
+ if (!strcmp(v, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01801)
+ "Authorization of user %s to access %s failed, reason: "
+ "user is not part of the 'require'ed group(s).",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group;
+
+static authz_status dbmfilegroup_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authz_dbm_module);
+ char *user = r->user;
+ const char *realm = ap_auth_name(r);
+ const char *filegroup = NULL;
+ apr_status_t status;
+ const char *groups;
+ char *v;
+
+ if (!user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!conf->grpfile) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01802)
+ "No group file was specified in the configuration");
+ return AUTHZ_DENIED;
+ }
+
+ /* fetch group data from dbm file. */
+ status = get_dbm_grp(r, apr_pstrcat(r->pool, user, ":", realm, NULL),
+ user, conf->grpfile, conf->dbmtype, &groups);
+
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01803)
+ "could not open dbm (type %s) group access "
+ "file: %s", conf->dbmtype, conf->grpfile);
+ return AUTHZ_DENIED;
+ }
+
+ if (groups == NULL) {
+ /* no groups available, so exit immediately */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01804)
+ "Authorization of user %s to access %s failed, reason: "
+ "user doesn't appear in DBM group file (%s).",
+ r->user, r->uri, conf->grpfile);
+ return AUTHZ_DENIED;
+ }
+
+ filegroup = authz_owner_get_file_group(r);
+
+ if (filegroup) {
+ while (groups[0]) {
+ v = ap_getword(r->pool, &groups, ',');
+ if (!strcmp(v, filegroup)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01805)
+ "Authorization of user %s to access %s failed, reason: "
+ "user is not part of the 'require'ed group(s).",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static const char *dbm_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+static const authz_provider authz_dbmgroup_provider =
+{
+ &dbmgroup_check_authorization,
+ &dbm_parse_config,
+};
+
+static const authz_provider authz_dbmfilegroup_provider =
+{
+ &dbmfilegroup_check_authorization,
+ NULL,
+};
+
+static void authz_dbm_getfns(void)
+{
+ authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group);
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_dbmgroup_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-file-group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_dbmfilegroup_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_optional_fn_retrieve(authz_dbm_getfns, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authz_dbm) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authz_dbm_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authz_dbm_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authz_dbm.dep b/modules/aaa/mod_authz_dbm.dep
new file mode 100644
index 0000000..1b4bf3a
--- /dev/null
+++ b/modules/aaa/mod_authz_dbm.dep
@@ -0,0 +1,62 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_dbm.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_dbm.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_dbm.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_authz_owner.h"\
+
diff --git a/modules/aaa/mod_authz_dbm.dsp b/modules/aaa/mod_authz_dbm.dsp
new file mode 100644
index 0000000..9ac2993
--- /dev/null
+++ b/modules/aaa/mod_authz_dbm.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_dbm" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_dbm - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbm.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbm.mak" CFG="mod_authz_dbm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_dbm_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_dbm_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_dbm.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_dbm - Win32 Release"
+# Name "mod_authz_dbm - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_dbm.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_dbm.mak b/modules/aaa/mod_authz_dbm.mak
new file mode 100644
index 0000000..4be17d5
--- /dev/null
+++ b/modules/aaa/mod_authz_dbm.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_dbm.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_dbm - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_dbm - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_dbm - Win32 Release" && "$(CFG)" != "mod_authz_dbm - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_dbm.mak" CFG="mod_authz_dbm - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_dbm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_dbm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_dbm.obj"
+ -@erase "$(INTDIR)\mod_authz_dbm.res"
+ -@erase "$(INTDIR)\mod_authz_dbm_src.idb"
+ -@erase "$(INTDIR)\mod_authz_dbm_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbm.exp"
+ -@erase "$(OUTDIR)\mod_authz_dbm.lib"
+ -@erase "$(OUTDIR)\mod_authz_dbm.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbm.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbm_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbm.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbm.so" /implib:"$(OUTDIR)\mod_authz_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_dbm.obj" \
+ "$(INTDIR)\mod_authz_dbm.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbm.so"
+ if exist .\Release\mod_authz_dbm.so.manifest mt.exe -manifest .\Release\mod_authz_dbm.so.manifest -outputresource:.\Release\mod_authz_dbm.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_dbm.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_dbm.obj"
+ -@erase "$(INTDIR)\mod_authz_dbm.res"
+ -@erase "$(INTDIR)\mod_authz_dbm_src.idb"
+ -@erase "$(INTDIR)\mod_authz_dbm_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbm.exp"
+ -@erase "$(OUTDIR)\mod_authz_dbm.lib"
+ -@erase "$(OUTDIR)\mod_authz_dbm.pdb"
+ -@erase "$(OUTDIR)\mod_authz_dbm.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_dbm_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_dbm.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_dbm.pdb" /debug /out:"$(OUTDIR)\mod_authz_dbm.so" /implib:"$(OUTDIR)\mod_authz_dbm.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_dbm.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_dbm.obj" \
+ "$(INTDIR)\mod_authz_dbm.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_dbm.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_dbm.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_dbm.so"
+ if exist .\Debug\mod_authz_dbm.so.manifest mt.exe -manifest .\Debug\mod_authz_dbm.so.manifest -outputresource:.\Debug\mod_authz_dbm.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_dbm.dep")
+!INCLUDE "mod_authz_dbm.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_dbm.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release" || "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_dbm - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_dbm.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_dbm - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_dbm.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_dbm.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_dbm.so" /d LONG_NAME="authz_dbm_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_dbm.c
+
+"$(INTDIR)\mod_authz_dbm.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_groupfile.c b/modules/aaa/mod_authz_groupfile.c
new file mode 100644
index 0000000..76957f7
--- /dev/null
+++ b/modules/aaa/mod_authz_groupfile.c
@@ -0,0 +1,331 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This module is triggered by an
+ *
+ * AuthGroupFile standard /path/to/file
+ *
+ * and the presence of a
+ *
+ * require group <list-of-groups>
+ *
+ * In an applicable limit/directory block for that method.
+ *
+ * If there are no AuthGroupFile directives valid for
+ * the request; we DECLINED.
+ *
+ * If the AuthGroupFile is defined; but somehow not
+ * accessible: we SERVER_ERROR (was DECLINED).
+ *
+ * If there are no 'require ' directives defined for
+ * this request then we DECLINED (was OK).
+ *
+ * If there are no 'require ' directives valid for
+ * this request method then we DECLINED. (was OK)
+ *
+ * If there are any 'require group' blocks and we
+ * are not in any group - we HTTP_UNAUTHORIZE
+ *
+ */
+
+#include "apr_strings.h"
+#include "apr_lib.h" /* apr_isspace */
+
+#include "ap_config.h"
+#include "ap_provider.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_varbuf.h"
+
+#include "mod_auth.h"
+#include "mod_authz_owner.h"
+
+typedef struct {
+ char *groupfile;
+} authz_groupfile_config_rec;
+
+static void *create_authz_groupfile_dir_config(apr_pool_t *p, char *d)
+{
+ authz_groupfile_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ conf->groupfile = NULL;
+ return conf;
+}
+
+static const command_rec authz_groupfile_cmds[] =
+{
+ AP_INIT_TAKE1("AuthGroupFile", ap_set_file_slot,
+ (void *)APR_OFFSETOF(authz_groupfile_config_rec, groupfile),
+ OR_AUTHCFG,
+ "text file containing group names and member user IDs"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authz_groupfile_module;
+
+#define VARBUF_INIT_LEN 512
+#define VARBUF_MAX_LEN (16*1024*1024)
+static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile,
+ apr_table_t ** out)
+{
+ ap_configfile_t *f;
+ apr_table_t *grps = apr_table_make(p, 15);
+ apr_pool_t *sp;
+ struct ap_varbuf vb;
+ const char *group_name, *ll, *w;
+ apr_status_t status;
+ apr_size_t group_len;
+
+ if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) {
+ return status ;
+ }
+
+ apr_pool_create(&sp, p);
+ ap_varbuf_init(p, &vb, VARBUF_INIT_LEN);
+
+ while (!(ap_varbuf_cfg_getline(&vb, f, VARBUF_MAX_LEN))) {
+ if ((vb.buf[0] == '#') || (!vb.buf[0])) {
+ continue;
+ }
+ ll = vb.buf;
+ apr_pool_clear(sp);
+
+ group_name = ap_getword(sp, &ll, ':');
+ group_len = strlen(group_name);
+
+ while (group_len && apr_isspace(*(group_name + group_len - 1))) {
+ --group_len;
+ }
+
+ while (ll[0]) {
+ w = ap_getword_conf(sp, &ll);
+ if (!strcmp(w, user)) {
+ apr_table_setn(grps, apr_pstrmemdup(p, group_name, group_len),
+ "in");
+ break;
+ }
+ }
+ }
+ ap_cfg_closefile(f);
+ apr_pool_destroy(sp);
+ ap_varbuf_free(&vb);
+
+ *out = grps;
+ return APR_SUCCESS;
+}
+
+static authz_status group_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authz_groupfile_module);
+ char *user = r->user;
+
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t, *w;
+ apr_table_t *grpstatus = NULL;
+ apr_status_t status;
+
+ if (!user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ /* If there is no group file - then we are not
+ * configured. So decline.
+ */
+ if (!(conf->groupfile)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01664)
+ "No group file was specified in the configuration");
+ return AUTHZ_DENIED;
+ }
+
+ status = groups_for_user(r->pool, user, conf->groupfile,
+ &grpstatus);
+
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01665)
+ "Could not open group file: %s",
+ conf->groupfile);
+ return AUTHZ_DENIED;
+ }
+
+ if (apr_is_empty_table(grpstatus)) {
+ /* no groups available, so exit immediately */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01666)
+ "Authorization of user %s to access %s failed, reason: "
+ "user doesn't appear in group file (%s).",
+ r->user, r->uri, conf->groupfile);
+ return AUTHZ_DENIED;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02592)
+ "authz_groupfile authorize: require group: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ if (apr_table_get(grpstatus, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01667)
+ "Authorization of user %s to access %s failed, reason: "
+ "user is not part of the 'require'ed group(s).",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group;
+
+static authz_status filegroup_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authz_groupfile_module);
+ char *user = r->user;
+ apr_table_t *grpstatus = NULL;
+ apr_status_t status;
+ const char *filegroup = NULL;
+
+ if (!user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ /* If there is no group file - then we are not
+ * configured. So decline.
+ */
+ if (!(conf->groupfile)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01668)
+ "No group file was specified in the configuration");
+ return AUTHZ_DENIED;
+ }
+
+ status = groups_for_user(r->pool, user, conf->groupfile,
+ &grpstatus);
+ if (status != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01669)
+ "Could not open group file: %s",
+ conf->groupfile);
+ return AUTHZ_DENIED;
+ }
+
+ if (apr_is_empty_table(grpstatus)) {
+ /* no groups available, so exit immediately */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01670)
+ "Authorization of user %s to access %s failed, reason: "
+ "user doesn't appear in group file (%s).",
+ r->user, r->uri, conf->groupfile);
+ return AUTHZ_DENIED;
+ }
+
+ filegroup = authz_owner_get_file_group(r);
+
+ if (filegroup) {
+ if (apr_table_get(grpstatus, filegroup)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+ else {
+ /* No need to emit a error log entry because the call
+ to authz_owner_get_file_group already did it
+ for us.
+ */
+ return AUTHZ_DENIED;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01671)
+ "Authorization of user %s to access %s failed, reason: "
+ "user is not part of the 'require'ed file group.",
+ r->user, r->uri);
+
+ return AUTHZ_DENIED;
+}
+
+static const char *groupfile_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+static const authz_provider authz_group_provider =
+{
+ &group_check_authorization,
+ &groupfile_parse_config,
+};
+
+static const authz_provider authz_filegroup_provider =
+{
+ &filegroup_check_authorization,
+ NULL,
+};
+
+
+static void authz_groupfile_getfns(void)
+{
+ authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group);
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_group_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "file-group",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_filegroup_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_optional_fn_retrieve(authz_groupfile_getfns, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+AP_DECLARE_MODULE(authz_groupfile) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authz_groupfile_dir_config,/* dir config creater */
+ NULL, /* dir merger -- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authz_groupfile_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authz_groupfile.dep b/modules/aaa/mod_authz_groupfile.dep
new file mode 100644
index 0000000..cb09628
--- /dev/null
+++ b/modules/aaa/mod_authz_groupfile.dep
@@ -0,0 +1,61 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_groupfile.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_groupfile.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\include\util_varbuf.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_lib.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_authz_owner.h"\
+
diff --git a/modules/aaa/mod_authz_groupfile.dsp b/modules/aaa/mod_authz_groupfile.dsp
new file mode 100644
index 0000000..efea169
--- /dev/null
+++ b/modules/aaa/mod_authz_groupfile.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_groupfile" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_groupfile - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_groupfile.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_groupfile.mak" CFG="mod_authz_groupfile - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_groupfile - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_groupfile - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_groupfile_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_groupfile.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_groupfile_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_groupfile.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_groupfile.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_groupfile - Win32 Release"
+# Name "mod_authz_groupfile - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_groupfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_groupfile.mak b/modules/aaa/mod_authz_groupfile.mak
new file mode 100644
index 0000000..37d729c
--- /dev/null
+++ b/modules/aaa/mod_authz_groupfile.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_groupfile.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_groupfile - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_groupfile - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_groupfile - Win32 Release" && "$(CFG)" != "mod_authz_groupfile - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_groupfile.mak" CFG="mod_authz_groupfile - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_groupfile - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_groupfile - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_groupfile.obj"
+ -@erase "$(INTDIR)\mod_authz_groupfile.res"
+ -@erase "$(INTDIR)\mod_authz_groupfile_src.idb"
+ -@erase "$(INTDIR)\mod_authz_groupfile_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.exp"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.lib"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.pdb"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_groupfile_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_groupfile.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_groupfile.pdb" /debug /out:"$(OUTDIR)\mod_authz_groupfile.so" /implib:"$(OUTDIR)\mod_authz_groupfile.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_groupfile.obj" \
+ "$(INTDIR)\mod_authz_groupfile.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_groupfile.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_groupfile.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_groupfile.so"
+ if exist .\Release\mod_authz_groupfile.so.manifest mt.exe -manifest .\Release\mod_authz_groupfile.so.manifest -outputresource:.\Release\mod_authz_groupfile.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_groupfile.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_groupfile.obj"
+ -@erase "$(INTDIR)\mod_authz_groupfile.res"
+ -@erase "$(INTDIR)\mod_authz_groupfile_src.idb"
+ -@erase "$(INTDIR)\mod_authz_groupfile_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.exp"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.lib"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.pdb"
+ -@erase "$(OUTDIR)\mod_authz_groupfile.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_groupfile_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_groupfile.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_groupfile.pdb" /debug /out:"$(OUTDIR)\mod_authz_groupfile.so" /implib:"$(OUTDIR)\mod_authz_groupfile.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_groupfile.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_groupfile.obj" \
+ "$(INTDIR)\mod_authz_groupfile.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_groupfile.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_groupfile.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_groupfile.so"
+ if exist .\Debug\mod_authz_groupfile.so.manifest mt.exe -manifest .\Debug\mod_authz_groupfile.so.manifest -outputresource:.\Debug\mod_authz_groupfile.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_groupfile.dep")
+!INCLUDE "mod_authz_groupfile.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_groupfile.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release" || "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_groupfile - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_groupfile.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_groupfile - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_groupfile.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_groupfile.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_groupfile.so" /d LONG_NAME="authz_groupfile_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_groupfile.c
+
+"$(INTDIR)\mod_authz_groupfile.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_host.c b/modules/aaa/mod_authz_host.c
new file mode 100644
index 0000000..b43414f
--- /dev/null
+++ b/modules/aaa/mod_authz_host.c
@@ -0,0 +1,410 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Security options etc.
+ *
+ * Module derived from code originally written by Rob McCool
+ *
+ */
+
+#include "apr_strings.h"
+#include "apr_network_io.h"
+#include "apr_md5.h"
+#include "apr_hash.h"
+
+#define APR_WANT_STRFUNC
+#define APR_WANT_BYTEFUNC
+#include "apr_want.h"
+
+#include "ap_config.h"
+#include "ap_provider.h"
+#include "httpd.h"
+#include "http_core.h"
+#include "http_config.h"
+#include "http_log.h"
+#include "http_protocol.h"
+#include "http_request.h"
+
+#include "mod_auth.h"
+
+#if APR_HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+/*
+ * To save memory if the same subnets are used in hundres of vhosts, we store
+ * each subnet only once and use this temporary hash to find it again.
+ */
+static apr_hash_t *parsed_subnets;
+
+static apr_ipsubnet_t *localhost_v4;
+#if APR_HAVE_IPV6
+static apr_ipsubnet_t *localhost_v6;
+#endif
+
+static int in_domain(const char *domain, const char *what)
+{
+ int dl = strlen(domain);
+ int wl = strlen(what);
+
+ if ((wl - dl) >= 0) {
+ if (strcasecmp(domain, &what[wl - dl]) != 0) {
+ return 0;
+ }
+
+ /* Make sure we matched an *entire* subdomain --- if the user
+ * said 'allow from good.com', we don't want people from nogood.com
+ * to be able to get in.
+ */
+
+ if (wl == dl) {
+ return 1; /* matched whole thing */
+ }
+ else {
+ return (domain[0] == '.' || what[wl - dl - 1] == '.');
+ }
+ }
+ else {
+ return 0;
+ }
+}
+
+static const char *ip_parse_config(cmd_parms *cmd,
+ const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *t, *w;
+ int count = 0;
+ apr_ipsubnet_t **ip;
+ apr_pool_t *ptemp = cmd->temp_pool;
+ apr_pool_t *p = cmd->pool;
+
+ /* The 'ip' provider will allow the configuration to specify a list of
+ ip addresses to check rather than a single address. This is different
+ from the previous host based syntax. */
+
+ t = require_line;
+ while ((w = ap_getword_conf(ptemp, &t)) && w[0])
+ count++;
+
+ if (count == 0)
+ return "'require ip' requires an argument";
+
+ ip = apr_pcalloc(p, sizeof(apr_ipsubnet_t *) * (count + 1));
+ *parsed_require_line = ip;
+
+ t = require_line;
+ while ((w = ap_getword_conf(ptemp, &t)) && w[0]) {
+ char *addr = apr_pstrdup(ptemp, w);
+ char *mask;
+ apr_status_t rv;
+
+ if (parsed_subnets &&
+ (*ip = apr_hash_get(parsed_subnets, w, APR_HASH_KEY_STRING)) != NULL)
+ {
+ /* we already have parsed this subnet */
+ ip++;
+ continue;
+ }
+
+ if ((mask = ap_strchr(addr, '/')))
+ *mask++ = '\0';
+
+ rv = apr_ipsubnet_create(ip, addr, mask, p);
+
+ if(APR_STATUS_IS_EINVAL(rv)) {
+ /* looked nothing like an IP address */
+ return apr_psprintf(p, "ip address '%s' appears to be invalid", w);
+ }
+ else if (rv != APR_SUCCESS) {
+ return apr_psprintf(p, "ip address '%s' appears to be invalid: %pm",
+ w, &rv);
+ }
+
+ if (parsed_subnets)
+ apr_hash_set(parsed_subnets, w, APR_HASH_KEY_STRING, *ip);
+ ip++;
+ }
+
+ return NULL;
+}
+
+static authz_status ip_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ /* apr_ipsubnet_test should accept const but doesn't */
+ apr_ipsubnet_t **ip = (apr_ipsubnet_t **)parsed_require_line;
+
+ while (*ip) {
+ if (apr_ipsubnet_test(*ip, r->useragent_addr))
+ return AUTHZ_GRANTED;
+ ip++;
+ }
+
+ /* authz_core will log the require line and the result at DEBUG */
+ return AUTHZ_DENIED;
+}
+
+static authz_status host_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *t, *w;
+ const char *remotehost = NULL;
+ int remotehost_is_ip;
+
+ remotehost = ap_get_useragent_host(r, REMOTE_DOUBLE_REV, &remotehost_is_ip);
+
+ if ((remotehost == NULL) || remotehost_is_ip) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01753)
+ "access check of '%s' to %s failed, reason: unable to get the "
+ "remote host name", require_line, r->uri);
+ }
+ else {
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_line;
+ const char *require;
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02593)
+ "authz_host authorize: require host: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ /* The 'host' provider will allow the configuration to specify a list of
+ host names to check rather than a single name. This is different
+ from the previous host based syntax. */
+ t = require;
+
+ /* '#' is not a valid hostname character and admin could
+ * specify 'Require host localhost# Add example.com later'. We
+ * should not grant access to 'example.com' in that case. */
+ w = ap_strchr_c(t, '#');
+ if (w) {
+ if (w == t) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10120)
+ "authz_host authorize: dubious empty "
+ "'Require host %s' with only comment", t);
+ return AUTHZ_DENIED;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10121)
+ "authz_host authorize: ignoring comment in "
+ "'Require host %s'", t);
+
+ /* Truncate the string at the #. */
+ t = apr_pstrmemdup(r->pool, t, w - t);
+ }
+
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ if (in_domain(w, remotehost)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+ }
+
+ /* authz_core will log the require line and the result at DEBUG */
+ return AUTHZ_DENIED;
+}
+
+static authz_status
+forward_dns_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_line;
+ const char *require, *t;
+ char *w;
+
+ /* the require line is an expression, which is evaluated now. */
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03354)
+ "authz_host authorize: require forward-dns: "
+ "Can't evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ /* tokenize expected list of names */
+ t = require;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+
+ apr_sockaddr_t *sa;
+ apr_status_t rv;
+ char *hash_ptr;
+
+ /* stop on apache configuration file comments */
+ if ((hash_ptr = ap_strchr(w, '#'))) {
+ if (hash_ptr == w) {
+ break;
+ }
+ *hash_ptr = '\0';
+ }
+
+ /* does the client ip match one of the names? */
+ rv = apr_sockaddr_info_get(&sa, w, APR_UNSPEC, 0, 0, r->pool);
+ if (rv == APR_SUCCESS) {
+
+ while (sa) {
+ int match = apr_sockaddr_equal(sa, r->useragent_addr);
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03355)
+ "access check for %s as '%s': %s",
+ r->useragent_ip, w, match? "yes": "no");
+ if (match) {
+ return AUTHZ_GRANTED;
+ }
+
+ sa = sa->next;
+ }
+ }
+ else {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03356)
+ "No sockaddr info for \"%s\"", w);
+ }
+
+ /* stop processing, we are in a comment */
+ if (hash_ptr) {
+ break;
+ }
+ }
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status local_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ if ( apr_sockaddr_equal(r->connection->local_addr,
+ r->useragent_addr)
+ || apr_ipsubnet_test(localhost_v4, r->useragent_addr)
+#if APR_HAVE_IPV6
+ || apr_ipsubnet_test(localhost_v6, r->useragent_addr)
+#endif
+ )
+ {
+ return AUTHZ_GRANTED;
+ }
+
+ return AUTHZ_DENIED;
+}
+
+static const char *host_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+static const authz_provider authz_ip_provider =
+{
+ &ip_check_authorization,
+ &ip_parse_config,
+};
+
+static const authz_provider authz_host_provider =
+{
+ &host_check_authorization,
+ &host_parse_config,
+};
+
+static const authz_provider authz_forward_dns_provider =
+{
+ &forward_dns_check_authorization,
+ &host_parse_config,
+};
+
+static const authz_provider authz_local_provider =
+{
+ &local_check_authorization,
+ NULL,
+};
+
+
+static int authz_host_pre_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp)
+{
+ /* we only use this hash in the parse config phase, ptemp is enough */
+ parsed_subnets = apr_hash_make(ptemp);
+
+ apr_ipsubnet_create(&localhost_v4, "127.0.0.0", "8", p);
+ apr_hash_set(parsed_subnets, "127.0.0.0/8", APR_HASH_KEY_STRING, localhost_v4);
+
+#if APR_HAVE_IPV6
+ apr_ipsubnet_create(&localhost_v6, "::1", NULL, p);
+ apr_hash_set(parsed_subnets, "::1", APR_HASH_KEY_STRING, localhost_v6);
+#endif
+
+ return OK;
+}
+
+static int authz_host_post_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ /* make sure we don't use this during .htaccess parsing */
+ parsed_subnets = NULL;
+
+ return OK;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_hook_pre_config(authz_host_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config(authz_host_post_config, NULL, NULL, APR_HOOK_MIDDLE);
+
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ip",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_ip_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "host",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_host_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "forward-dns",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_forward_dns_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "local",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_local_provider, AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authz_host) =
+{
+ STANDARD20_MODULE_STUFF,
+ NULL, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ NULL,
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authz_host.dep b/modules/aaa/mod_authz_host.dep
new file mode 100644
index 0000000..fe5ce09
--- /dev/null
+++ b/modules/aaa/mod_authz_host.dep
@@ -0,0 +1,60 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_host.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_host.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_md5.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apr_xlate.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authz_host.dsp b/modules/aaa/mod_authz_host.dsp
new file mode 100644
index 0000000..e417687
--- /dev/null
+++ b/modules/aaa/mod_authz_host.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_host" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_host - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_host.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_host.mak" CFG="mod_authz_host - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_host - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_host - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_host_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_host.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_host_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_host.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_host.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_host - Win32 Release"
+# Name "mod_authz_host - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_host.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_host.mak b/modules/aaa/mod_authz_host.mak
new file mode 100644
index 0000000..1ad9e85
--- /dev/null
+++ b/modules/aaa/mod_authz_host.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_host.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_host - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_host - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_host - Win32 Release" && "$(CFG)" != "mod_authz_host - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_host.mak" CFG="mod_authz_host - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_host - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_host - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_host.obj"
+ -@erase "$(INTDIR)\mod_authz_host.res"
+ -@erase "$(INTDIR)\mod_authz_host_src.idb"
+ -@erase "$(INTDIR)\mod_authz_host_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_host.exp"
+ -@erase "$(OUTDIR)\mod_authz_host.lib"
+ -@erase "$(OUTDIR)\mod_authz_host.pdb"
+ -@erase "$(OUTDIR)\mod_authz_host.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_host_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_host.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_host.pdb" /debug /out:"$(OUTDIR)\mod_authz_host.so" /implib:"$(OUTDIR)\mod_authz_host.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_host.obj" \
+ "$(INTDIR)\mod_authz_host.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_host.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_host.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_host.so"
+ if exist .\Release\mod_authz_host.so.manifest mt.exe -manifest .\Release\mod_authz_host.so.manifest -outputresource:.\Release\mod_authz_host.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_host.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_host.obj"
+ -@erase "$(INTDIR)\mod_authz_host.res"
+ -@erase "$(INTDIR)\mod_authz_host_src.idb"
+ -@erase "$(INTDIR)\mod_authz_host_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_host.exp"
+ -@erase "$(OUTDIR)\mod_authz_host.lib"
+ -@erase "$(OUTDIR)\mod_authz_host.pdb"
+ -@erase "$(OUTDIR)\mod_authz_host.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_host_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_host.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_host.pdb" /debug /out:"$(OUTDIR)\mod_authz_host.so" /implib:"$(OUTDIR)\mod_authz_host.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_host.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_host.obj" \
+ "$(INTDIR)\mod_authz_host.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_host.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_host.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_host.so"
+ if exist .\Debug\mod_authz_host.so.manifest mt.exe -manifest .\Debug\mod_authz_host.so.manifest -outputresource:.\Debug\mod_authz_host.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_host.dep")
+!INCLUDE "mod_authz_host.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_host.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release" || "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_host - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_host.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_host - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_host.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_host.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_host.so" /d LONG_NAME="authz_host_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_host.c
+
+"$(INTDIR)\mod_authz_host.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_owner.c b/modules/aaa/mod_authz_owner.c
new file mode 100644
index 0000000..4fd0b2a
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.c
@@ -0,0 +1,189 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+#include "apr_file_info.h"
+#include "apr_user.h"
+
+#include "ap_config.h"
+#include "ap_provider.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 "mod_auth.h"
+#include "mod_authz_owner.h"
+
+static const command_rec authz_owner_cmds[] =
+{
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authz_owner_module;
+
+static authz_status fileowner_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ char *reason = NULL;
+ apr_status_t status = 0;
+
+#if !APR_HAS_USER
+ reason = "'Require file-owner' is not supported on this platform.";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01632)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+#else /* APR_HAS_USER */
+ char *owner = NULL;
+ apr_finfo_t finfo;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ if (!r->filename) {
+ reason = "no filename available";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01633)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+ }
+
+ status = apr_stat(&finfo, r->filename, APR_FINFO_USER, r->pool);
+ if (status != APR_SUCCESS) {
+ reason = apr_pstrcat(r->pool, "could not stat file ",
+ r->filename, NULL);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01634)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+ }
+
+ if (!(finfo.valid & APR_FINFO_USER)) {
+ reason = "no file owner information available";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01635)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+ }
+
+ status = apr_uid_name_get(&owner, finfo.user, r->pool);
+ if (status != APR_SUCCESS || !owner) {
+ reason = "could not get name of file owner";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01636)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+ }
+
+ if (strcmp(owner, r->user)) {
+ reason = apr_psprintf(r->pool, "file owner %s does not match.",
+ owner);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01637)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return AUTHZ_DENIED;
+ }
+
+ /* this user is authorized */
+ return AUTHZ_GRANTED;
+#endif /* APR_HAS_USER */
+}
+
+static char *authz_owner_get_file_group(request_rec *r)
+{
+ /* file-group only figures out the file's group and lets
+ * other modules do the actual authorization (against a group file/db).
+ * Thus, these modules have to hook themselves after
+ * mod_authz_owner and of course recognize 'file-group', too.
+ */
+#if !APR_HAS_USER
+ return NULL;
+#else /* APR_HAS_USER */
+ char *reason = NULL;
+ char *group = NULL;
+ apr_finfo_t finfo;
+ apr_status_t status = 0;
+
+ if (!r->filename) {
+ reason = "no filename available";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01638)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return NULL;
+ }
+
+ status = apr_stat(&finfo, r->filename, APR_FINFO_GROUP, r->pool);
+ if (status != APR_SUCCESS) {
+ reason = apr_pstrcat(r->pool, "could not stat file ",
+ r->filename, NULL);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01639)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return NULL;
+ }
+
+ if (!(finfo.valid & APR_FINFO_GROUP)) {
+ reason = "no file group information available";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01640)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return NULL;
+ }
+
+ status = apr_gid_name_get(&group, finfo.group, r->pool);
+ if (status != APR_SUCCESS || !group) {
+ reason = "could not get name of file group";
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(01641)
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+ return NULL;
+ }
+
+ return group;
+#endif /* APR_HAS_USER */
+}
+
+static const authz_provider authz_fileowner_provider =
+{
+ &fileowner_check_authorization,
+ NULL,
+};
+
+static void register_hooks(apr_pool_t *p)
+{
+ APR_REGISTER_OPTIONAL_FN(authz_owner_get_file_group);
+
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "file-owner",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_fileowner_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authz_owner) =
+{
+ STANDARD20_MODULE_STUFF,
+ NULL, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authz_owner_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authz_owner.dep b/modules/aaa/mod_authz_owner.dep
new file mode 100644
index 0000000..42a1056
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.dep
@@ -0,0 +1,59 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_owner.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_owner.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+ ".\mod_authz_owner.h"\
+
diff --git a/modules/aaa/mod_authz_owner.dsp b/modules/aaa/mod_authz_owner.dsp
new file mode 100644
index 0000000..e026a28
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_owner" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_owner - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_owner.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_owner.mak" CFG="mod_authz_owner - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_owner - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_owner - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_owner_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_owner.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_owner_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_owner.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_owner.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_owner - Win32 Release"
+# Name "mod_authz_owner - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_owner.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_owner.h b/modules/aaa/mod_authz_owner.h
new file mode 100644
index 0000000..799f336
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.h
@@ -0,0 +1,27 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOD_AUTHZ_OWNER_H
+#define MOD_AUTHZ_OWNER_H
+
+#include "http_request.h"
+
+/* mod_authz_owner exports an optional function which retrieves the
+ * group name of the file identified by r->filename, if available, or
+ * else returns NULL. */
+APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r));
+
+#endif /* MOD_AUTHZ_OWNER_H */
diff --git a/modules/aaa/mod_authz_owner.mak b/modules/aaa/mod_authz_owner.mak
new file mode 100644
index 0000000..850a1f7
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_owner.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_owner - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_owner - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_owner - Win32 Release" && "$(CFG)" != "mod_authz_owner - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_owner.mak" CFG="mod_authz_owner - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_owner - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_owner - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_owner.obj"
+ -@erase "$(INTDIR)\mod_authz_owner.res"
+ -@erase "$(INTDIR)\mod_authz_owner_src.idb"
+ -@erase "$(INTDIR)\mod_authz_owner_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_owner.exp"
+ -@erase "$(OUTDIR)\mod_authz_owner.lib"
+ -@erase "$(OUTDIR)\mod_authz_owner.pdb"
+ -@erase "$(OUTDIR)\mod_authz_owner.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_owner_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_owner.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_owner.pdb" /debug /out:"$(OUTDIR)\mod_authz_owner.so" /implib:"$(OUTDIR)\mod_authz_owner.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_owner.obj" \
+ "$(INTDIR)\mod_authz_owner.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_owner.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_owner.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_owner.so"
+ if exist .\Release\mod_authz_owner.so.manifest mt.exe -manifest .\Release\mod_authz_owner.so.manifest -outputresource:.\Release\mod_authz_owner.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_owner.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_owner.obj"
+ -@erase "$(INTDIR)\mod_authz_owner.res"
+ -@erase "$(INTDIR)\mod_authz_owner_src.idb"
+ -@erase "$(INTDIR)\mod_authz_owner_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_owner.exp"
+ -@erase "$(OUTDIR)\mod_authz_owner.lib"
+ -@erase "$(OUTDIR)\mod_authz_owner.pdb"
+ -@erase "$(OUTDIR)\mod_authz_owner.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_owner_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_owner.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_owner.pdb" /debug /out:"$(OUTDIR)\mod_authz_owner.so" /implib:"$(OUTDIR)\mod_authz_owner.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_owner.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_owner.obj" \
+ "$(INTDIR)\mod_authz_owner.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_owner.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_owner.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_owner.so"
+ if exist .\Debug\mod_authz_owner.so.manifest mt.exe -manifest .\Debug\mod_authz_owner.so.manifest -outputresource:.\Debug\mod_authz_owner.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_owner.dep")
+!INCLUDE "mod_authz_owner.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_owner.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release" || "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_owner - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_owner.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_owner - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_owner.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_owner.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_owner.so" /d LONG_NAME="authz_owner_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_owner.c
+
+"$(INTDIR)\mod_authz_owner.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+
diff --git a/modules/aaa/mod_authz_user.c b/modules/aaa/mod_authz_user.c
new file mode 100644
index 0000000..881f77f
--- /dev/null
+++ b/modules/aaa/mod_authz_user.c
@@ -0,0 +1,146 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_strings.h"
+
+#include "ap_config.h"
+#include "ap_provider.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 "mod_auth.h"
+
+typedef struct {
+ int dummy; /* just here to stop compiler warnings for now. */
+} authz_user_config_rec;
+
+static void *create_authz_user_dir_config(apr_pool_t *p, char *d)
+{
+ authz_user_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ return conf;
+}
+
+static const command_rec authz_user_cmds[] =
+{
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authz_user_module;
+
+static authz_status user_check_authorization(request_rec *r,
+ const char *require_args,
+ const void *parsed_require_args)
+{
+ const char *err = NULL;
+ const ap_expr_info_t *expr = parsed_require_args;
+ const char *require;
+
+ const char *t, *w;
+
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ require = ap_expr_str_exec(r, expr, &err);
+ if (err) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02594)
+ "authz_user authorize: require user: Can't "
+ "evaluate require expression: %s", err);
+ return AUTHZ_DENIED;
+ }
+
+ t = require;
+ while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+ if (!strcmp(r->user, w)) {
+ return AUTHZ_GRANTED;
+ }
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01663)
+ "access to %s failed, reason: user '%s' does not meet "
+ "'require'ments for user to be allowed access",
+ r->uri, r->user);
+
+ return AUTHZ_DENIED;
+}
+
+static authz_status validuser_check_authorization(request_rec *r,
+ const char *require_line,
+ const void *parsed_require_line)
+{
+ if (!r->user) {
+ return AUTHZ_DENIED_NO_USER;
+ }
+
+ return AUTHZ_GRANTED;
+}
+
+static const char *user_parse_config(cmd_parms *cmd, const char *require_line,
+ const void **parsed_require_line)
+{
+ const char *expr_err = NULL;
+ ap_expr_info_t *expr;
+
+ expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
+ &expr_err, NULL);
+
+ if (expr_err)
+ return apr_pstrcat(cmd->temp_pool,
+ "Cannot parse expression in require line: ",
+ expr_err, NULL);
+
+ *parsed_require_line = expr;
+
+ return NULL;
+}
+
+static const authz_provider authz_user_provider =
+{
+ &user_check_authorization,
+ &user_parse_config,
+};
+static const authz_provider authz_validuser_provider =
+{
+ &validuser_check_authorization,
+ NULL,
+};
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "user",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_user_provider, AP_AUTH_INTERNAL_PER_CONF);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "valid-user",
+ AUTHZ_PROVIDER_VERSION,
+ &authz_validuser_provider,
+ AP_AUTH_INTERNAL_PER_CONF);
+}
+
+AP_DECLARE_MODULE(authz_user) =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authz_user_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authz_user_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};
diff --git a/modules/aaa/mod_authz_user.dep b/modules/aaa/mod_authz_user.dep
new file mode 100644
index 0000000..648fa02
--- /dev/null
+++ b/modules/aaa/mod_authz_user.dep
@@ -0,0 +1,58 @@
+# Microsoft Developer Studio Generated Dependency File, included by mod_authz_user.mak
+
+..\..\build\win32\httpd.rc : \
+ "..\..\include\ap_release.h"\
+
+
+.\mod_authz_user.c : \
+ "..\..\include\ap_config.h"\
+ "..\..\include\ap_config_layout.h"\
+ "..\..\include\ap_expr.h"\
+ "..\..\include\ap_hooks.h"\
+ "..\..\include\ap_mmn.h"\
+ "..\..\include\ap_provider.h"\
+ "..\..\include\ap_regex.h"\
+ "..\..\include\ap_release.h"\
+ "..\..\include\apache_noprobes.h"\
+ "..\..\include\http_config.h"\
+ "..\..\include\http_core.h"\
+ "..\..\include\http_log.h"\
+ "..\..\include\http_protocol.h"\
+ "..\..\include\http_request.h"\
+ "..\..\include\httpd.h"\
+ "..\..\include\mod_auth.h"\
+ "..\..\include\os.h"\
+ "..\..\include\util_cfgtree.h"\
+ "..\..\include\util_filter.h"\
+ "..\..\srclib\apr-util\include\apr_buckets.h"\
+ "..\..\srclib\apr-util\include\apr_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_optional.h"\
+ "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
+ "..\..\srclib\apr-util\include\apr_uri.h"\
+ "..\..\srclib\apr-util\include\apu.h"\
+ "..\..\srclib\apr\include\apr.h"\
+ "..\..\srclib\apr\include\apr_allocator.h"\
+ "..\..\srclib\apr\include\apr_dso.h"\
+ "..\..\srclib\apr\include\apr_errno.h"\
+ "..\..\srclib\apr\include\apr_file_info.h"\
+ "..\..\srclib\apr\include\apr_file_io.h"\
+ "..\..\srclib\apr\include\apr_general.h"\
+ "..\..\srclib\apr\include\apr_global_mutex.h"\
+ "..\..\srclib\apr\include\apr_hash.h"\
+ "..\..\srclib\apr\include\apr_inherit.h"\
+ "..\..\srclib\apr\include\apr_mmap.h"\
+ "..\..\srclib\apr\include\apr_network_io.h"\
+ "..\..\srclib\apr\include\apr_poll.h"\
+ "..\..\srclib\apr\include\apr_pools.h"\
+ "..\..\srclib\apr\include\apr_portable.h"\
+ "..\..\srclib\apr\include\apr_proc_mutex.h"\
+ "..\..\srclib\apr\include\apr_ring.h"\
+ "..\..\srclib\apr\include\apr_shm.h"\
+ "..\..\srclib\apr\include\apr_strings.h"\
+ "..\..\srclib\apr\include\apr_tables.h"\
+ "..\..\srclib\apr\include\apr_thread_mutex.h"\
+ "..\..\srclib\apr\include\apr_thread_proc.h"\
+ "..\..\srclib\apr\include\apr_time.h"\
+ "..\..\srclib\apr\include\apr_user.h"\
+ "..\..\srclib\apr\include\apr_want.h"\
+
diff --git a/modules/aaa/mod_authz_user.dsp b/modules/aaa/mod_authz_user.dsp
new file mode 100644
index 0000000..91d80a6
--- /dev/null
+++ b/modules/aaa/mod_authz_user.dsp
@@ -0,0 +1,111 @@
+# Microsoft Developer Studio Project File - Name="mod_authz_user" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=mod_authz_user - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_user.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_user.mak" CFG="mod_authz_user - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_user - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_user - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Release\mod_authz_user_src" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /fo"Release/mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so /opt:ref
+# Begin Special Build Tool
+TargetPath=.\Release\mod_authz_user.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c
+# ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fd"Debug\mod_authz_user_src" /FD /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /fo"Debug/mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so
+# ADD LINK32 kernel32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Debug\mod_authz_user.so" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so
+# Begin Special Build Tool
+TargetPath=.\Debug\mod_authz_user.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "mod_authz_user - Win32 Release"
+# Name "mod_authz_user - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\mod_authz_user.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\build\win32\httpd.rc
+# End Source File
+# End Target
+# End Project
diff --git a/modules/aaa/mod_authz_user.mak b/modules/aaa/mod_authz_user.mak
new file mode 100644
index 0000000..0989f6e
--- /dev/null
+++ b/modules/aaa/mod_authz_user.mak
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on mod_authz_user.dsp
+!IF "$(CFG)" == ""
+CFG=mod_authz_user - Win32 Debug
+!MESSAGE No configuration specified. Defaulting to mod_authz_user - Win32 Debug.
+!ENDIF
+
+!IF "$(CFG)" != "mod_authz_user - Win32 Release" && "$(CFG)" != "mod_authz_user - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "mod_authz_user.mak" CFG="mod_authz_user - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "mod_authz_user - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "mod_authz_user - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Release" "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN" "mod_auth_basic - Win32 ReleaseCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_user.obj"
+ -@erase "$(INTDIR)\mod_authz_user.res"
+ -@erase "$(INTDIR)\mod_authz_user_src.idb"
+ -@erase "$(INTDIR)\mod_authz_user_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_user.exp"
+ -@erase "$(OUTDIR)\mod_authz_user.lib"
+ -@erase "$(OUTDIR)\mod_authz_user.pdb"
+ -@erase "$(OUTDIR)\mod_authz_user.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_user_src" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_user.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_user.pdb" /debug /out:"$(OUTDIR)\mod_authz_user.so" /implib:"$(OUTDIR)\mod_authz_user.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so /opt:ref
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_user.obj" \
+ "$(INTDIR)\mod_authz_user.res" \
+ "..\..\srclib\apr\Release\libapr-1.lib" \
+ "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
+ "..\..\Release\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_user.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Release\mod_authz_user.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Release
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_user.so"
+ if exist .\Release\mod_authz_user.so.manifest mt.exe -manifest .\Release\mod_authz_user.so.manifest -outputresource:.\Release\mod_authz_user.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+!IF "$(RECURSE)" == "0"
+
+ALL : "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
+
+!ELSE
+
+ALL : "mod_auth_basic - Win32 Debug" "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_authz_user.so" "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+!IF "$(RECURSE)" == "1"
+CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN" "mod_auth_basic - Win32 DebugCLEAN"
+!ELSE
+CLEAN :
+!ENDIF
+ -@erase "$(INTDIR)\mod_authz_user.obj"
+ -@erase "$(INTDIR)\mod_authz_user.res"
+ -@erase "$(INTDIR)\mod_authz_user_src.idb"
+ -@erase "$(INTDIR)\mod_authz_user_src.pdb"
+ -@erase "$(OUTDIR)\mod_authz_user.exp"
+ -@erase "$(OUTDIR)\mod_authz_user.lib"
+ -@erase "$(OUTDIR)\mod_authz_user.pdb"
+ -@erase "$(OUTDIR)\mod_authz_user.so"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_authz_user_src" /FD /EHsc /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o /win32 "NUL"
+RSC=rc.exe
+RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_authz_user.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_authz_user.pdb" /debug /out:"$(OUTDIR)\mod_authz_user.so" /implib:"$(OUTDIR)\mod_authz_user.lib" /base:@..\..\os\win32\BaseAddr.ref,mod_authz_user.so
+LINK32_OBJS= \
+ "$(INTDIR)\mod_authz_user.obj" \
+ "$(INTDIR)\mod_authz_user.res" \
+ "..\..\srclib\apr\Debug\libapr-1.lib" \
+ "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
+ "..\..\Debug\libhttpd.lib" \
+ "$(OUTDIR)\mod_auth_basic.lib"
+
+"$(OUTDIR)\mod_authz_user.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+TargetPath=.\Debug\mod_authz_user.so
+SOURCE="$(InputPath)"
+PostBuild_Desc=Embed .manifest
+DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
+
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_authz_user.so"
+ if exist .\Debug\mod_authz_user.so.manifest mt.exe -manifest .\Debug\mod_authz_user.so.manifest -outputresource:.\Debug\mod_authz_user.so;2
+ echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("mod_authz_user.dep")
+!INCLUDE "mod_authz_user.dep"
+!ELSE
+!MESSAGE Warning: cannot find "mod_authz_user.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release" || "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+"libapr - Win32 Release" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+"libapr - Win32 Debug" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libapr - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+"libaprutil - Win32 Release" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 ReleaseCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+"libaprutil - Win32 Debug" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
+ cd "..\..\modules\aaa"
+
+"libaprutil - Win32 DebugCLEAN" :
+ cd ".\..\..\srclib\apr-util"
+ $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
+ cd "..\..\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+"libhttpd - Win32 Release" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 ReleaseCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+"libhttpd - Win32 Debug" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
+ cd ".\modules\aaa"
+
+"libhttpd - Win32 DebugCLEAN" :
+ cd ".\..\.."
+ $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
+ cd ".\modules\aaa"
+
+!ENDIF
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+"mod_auth_basic - Win32 Release" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release"
+ cd "."
+
+"mod_auth_basic - Win32 ReleaseCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Release" RECURSE=1 CLEAN
+ cd "."
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+"mod_auth_basic - Win32 Debug" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug"
+ cd "."
+
+"mod_auth_basic - Win32 DebugCLEAN" :
+ cd "."
+ $(MAKE) /$(MAKEFLAGS) /F ".\mod_auth_basic.mak" CFG="mod_auth_basic - Win32 Debug" RECURSE=1 CLEAN
+ cd "."
+
+!ENDIF
+
+SOURCE=..\..\build\win32\httpd.rc
+
+!IF "$(CFG)" == "mod_authz_user - Win32 Release"
+
+
+"$(INTDIR)\mod_authz_user.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "NDEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "mod_authz_user - Win32 Debug"
+
+
+"$(INTDIR)\mod_authz_user.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x409 /fo"$(INTDIR)\mod_authz_user.res" /i "../../include" /i "../../srclib/apr/include" /i "../../build\win32" /d "_DEBUG" /d BIN_NAME="mod_authz_user.so" /d LONG_NAME="authz_user_module for Apache" $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mod_authz_user.c
+
+"$(INTDIR)\mod_authz_user.obj" : $(SOURCE) "$(INTDIR)"
+
+
+
+!ENDIF
+