Merge 2.5.x changes to trunk.

This commit is contained in:
b1v1r 2009-08-25 22:19:33 +00:00
parent 7379a4fb3f
commit 826124b378
17 changed files with 524 additions and 707 deletions

View File

@ -1,6 +1,13 @@
12 Aug 2009 - trunk
24 Aug 2009 - trunk
-------------------
* Added SecAuditLogDirMode and SecAuditLogFileMode to allow fine tuning
auditlog permissions (especially with mpm-itk).
* Cleaned up SecUploadFileMode implementation.
* Cleanup build scripts.
* Fixed crash on configuration if SecMarker is used before any rules.
* Fixed SecRuleUpdateActionById so that it will work on chain starters.

View File

@ -103,5 +103,6 @@ char DSOLOCAL *format_error_log_message(apr_pool_t *mp, error_message *em);
const DSOLOCAL char *get_response_protocol(request_rec *r);
#endif

View File

@ -20,6 +20,7 @@
#include "modsecurity.h"
#include "msc_logging.h"
#include "msc_util.h"
#include "pdf_protect.h"
#include "http_log.h"
@ -69,6 +70,8 @@ void *create_directory_config(apr_pool_t *mp, char *path) {
/* audit log variables */
dcfg->auditlog_flag = NOT_SET;
dcfg->auditlog_type = NOT_SET;
dcfg->auditlog_dirperms = NOT_SET;
dcfg->auditlog_fileperms = NOT_SET;
dcfg->auditlog_name = NOT_SET_P;
dcfg->auditlog2_name = NOT_SET_P;
dcfg->auditlog_fd = NOT_SET_P;
@ -388,6 +391,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child) {
? parent->auditlog_flag : child->auditlog_flag);
merged->auditlog_type = (child->auditlog_type == NOT_SET
? parent->auditlog_type : child->auditlog_type);
merged->auditlog_dirperms = (child->auditlog_dirperms == NOT_SET
? parent->auditlog_dirperms : child->auditlog_dirperms);
merged->auditlog_fileperms = (child->auditlog_fileperms == NOT_SET
? parent->auditlog_fileperms : child->auditlog_fileperms);
if (child->auditlog_fd != NOT_SET_P) {
merged->auditlog_fd = child->auditlog_fd;
merged->auditlog_name = child->auditlog_name;
@ -512,6 +519,8 @@ void init_directory_config(directory_config *dcfg) {
/* audit log variables */
if (dcfg->auditlog_flag == NOT_SET) dcfg->auditlog_flag = 0;
if (dcfg->auditlog_type == NOT_SET) dcfg->auditlog_type = AUDITLOG_SERIAL;
if (dcfg->auditlog_dirperms == NOT_SET) dcfg->auditlog_dirperms = CREATEMODE_DIR;
if (dcfg->auditlog_fileperms == NOT_SET) dcfg->auditlog_fileperms = CREATEMODE;
if (dcfg->auditlog_fd == NOT_SET_P) dcfg->auditlog_fd = NULL;
if (dcfg->auditlog2_fd == NOT_SET_P) dcfg->auditlog2_fd = NULL;
if (dcfg->auditlog_name == NOT_SET_P) dcfg->auditlog_name = NULL;
@ -525,7 +534,7 @@ void init_directory_config(directory_config *dcfg) {
if (dcfg->upload_dir == NOT_SET_P) dcfg->upload_dir = NULL;
if (dcfg->upload_keep_files == NOT_SET) dcfg->upload_keep_files = KEEP_FILES_OFF;
if (dcfg->upload_validates_files == NOT_SET) dcfg->upload_validates_files = 0;
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = 0600;
if (dcfg->upload_filemode == NOT_SET) dcfg->upload_filemode = mode2fileperms(0600);
/* Misc */
if (dcfg->data_dir == NOT_SET_P) dcfg->data_dir = NULL;
@ -1026,6 +1035,46 @@ static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg, const char *p
return NULL;
}
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg, const char *p1) {
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
if (strcasecmp(p1, "default") == 0) {
dcfg->auditlog_dirperms = NOT_SET;
}
else {
long int mode = strtol(p1, NULL, 8); /* expects octal mode */
if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 07777)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecAuditLogDirMode: %s", p1);
}
dcfg->auditlog_dirperms = mode2fileperms((mode_t)mode);
}
return NULL;
}
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg, const char *p1) {
directory_config *dcfg = (directory_config *)_dcfg;
if (dcfg == NULL) return NULL;
if (strcasecmp(p1, "default") == 0) {
dcfg->auditlog_fileperms = NOT_SET;
}
else {
long int mode = strtol(p1, NULL, 8); /* expects octal mode */
if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 07777)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecAuditLogFileMode: %s", p1);
}
dcfg->auditlog_fileperms = mode2fileperms((mode_t)mode);
}
return NULL;
}
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg, const char *p1) {
directory_config *dcfg = _dcfg;
@ -1541,7 +1590,7 @@ static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg, const char *
}
else {
long int mode = strtol(p1, NULL, 8); /* expects octal mode */
if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 0777)) {
if ((mode == LONG_MAX)||(mode == LONG_MIN)||(mode <= 0)||(mode > 07777)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecUploadFileMode: %s", p1);
}
@ -1854,6 +1903,22 @@ const command_rec module_directives[] = {
"path to the audit log storage area; absolute, or relative to the root of the server"
),
AP_INIT_TAKE1 (
"SecAuditLogDirMode",
cmd_audit_log_dirmode,
NULL,
CMD_SCOPE_ANY,
"octal permissions mode for concurrent audit log directories"
),
AP_INIT_TAKE1 (
"SecAuditLogFileMode",
cmd_audit_log_filemode,
NULL,
CMD_SCOPE_ANY,
"octal permissions mode for concurrent audit log files"
),
AP_INIT_TAKE12 (
"SecCacheTransformations",
cmd_cache_transformations,

View File

@ -26,13 +26,13 @@ AC_MSG_CHECKING([for libapr config script])
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
APR_CONFIG="`basename $x`"
apr_path=`echo $x | sed "s/\/\?${APR_CONFIG}\$//"`
APR_CONFIG=$x
apr_path=no
break
fi
dnl # Try known config script names/locations
for APR_CONFIG in apr-1-mt-config apr-1-config apr-mt-config apr-config; do
for APR_CONFIG in apr-1-mt-config apr-1-config apr-config-1 apr-mt-config-1 apr-mt-config apr-config; do
if test -e "${x}/bin/${APR_CONFIG}"; then
apr_path="${x}/bin"
break
@ -49,7 +49,9 @@ for x in ${test_paths}; do
done
if test -n "${apr_path}"; then
APR_CONFIG="${apr_path}/${APR_CONFIG}"
if test "${apr_path}" != "no"; then
APR_CONFIG="${apr_path}/${APR_CONFIG}"
fi
AC_MSG_RESULT([${APR_CONFIG}])
APR_CFLAGS="`${APR_CONFIG} --includes --cppflags --cflags`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr CFLAGS: $APR_CFLAGS); fi

View File

@ -27,12 +27,12 @@ for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
APU_CONFIG="`basename $x`"
apu_path=`echo $x | sed "s/\/\?${APU_CONFIG}\$//"`
apu_path="no"
break
fi
dnl # Try known config script names/locations
for APU_CONFIG in apu-1-mt-config apu-1-config apu-mt-config apu-config; do
for APU_CONFIG in apu-1-mt-config apu-1-config apu-config-1 apu-mt-config-1 apu-mt-config apu-config; do
if test -e "${x}/bin/${APU_CONFIG}"; then
apu_path="${x}/bin"
break
@ -49,7 +49,9 @@ for x in ${test_paths}; do
done
if test -n "${apu_path}"; then
APU_CONFIG="${apu_path}/${APU_CONFIG}"
if test "${apu_path}" != "no"; then
APU_CONFIG="${apu_path}/${APU_CONFIG}"
fi
AC_MSG_RESULT([${APU_CONFIG}])
APU_CFLAGS="`${APU_CONFIG} --includes`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu CFLAGS: $APU_CFLAGS); fi

View File

@ -23,8 +23,8 @@ AC_MSG_CHECKING([for libcurl config script])
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
CURL_CONFIG="`basename $x`"
curl_path=`echo $x | sed "s/\/\?${CURL_CONFIG}\$//"`
CURL_CONFIG=$x
curl_path="no"
break
fi
@ -46,7 +46,9 @@ for x in ${test_paths}; do
done
if test -n "${curl_path}"; then
CURL_CONFIG="${curl_path}/${CURL_CONFIG}"
if test "${curl_path}" != "no"; then
CURL_CONFIG="${curl_path}/${CURL_CONFIG}"
fi
AC_MSG_RESULT([${CURL_CONFIG}])
CURL_CFLAGS="`${CURL_CONFIG} --cflags`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(curl CFLAGS: $CURL_CFLAGS); fi

View File

@ -29,8 +29,8 @@ fi
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
PCRE_CONFIG="`basename $x`"
pcre_path=`echo $x | sed "s/\/\?${PCRE_CONFIG}\$//"`
PCRE_CONFIG=$x
pcre_path="no"
break
fi
@ -54,7 +54,9 @@ done
LDFLAGS=$save_LDFLAGS
if test -n "${pcre_path}"; then
PCRE_CONFIG="${pcre_path}/${PCRE_CONFIG}"
if test "${pcre_path}" != "no"; then
PCRE_CONFIG="${pcre_path}/${PCRE_CONFIG}"
fi
AC_MSG_RESULT([${PCRE_CONFIG}])
PCRE_CFLAGS="`${PCRE_CONFIG} --cflags`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre CFLAGS: $PCRE_CFLAGS); fi

View File

@ -22,8 +22,8 @@ AC_MSG_CHECKING([for libxml2 config script])
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
LIBXML2_CONFIG="`basename $x`"
libxml2_path=`echo $x | sed "s/\/\?${LIBXML2_CONFIG}\$//"`
LIBXML2_CONFIG=$x
libxml2_path="no"
break
fi
@ -47,7 +47,9 @@ done
LDFLAGS=$save_LDFLAGS
if test -n "${libxml2_path}"; then
LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}"
if test "${libxml2_path}" != "no"; then
LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}"
fi
AC_MSG_RESULT([${LIBXML2_CONFIG}])
LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`"
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi

943
apache2/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@ AC_CONFIG_AUX_DIR([build])
# Checks for programs.
AC_PROG_AWK
AC_PROG_CXX
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
@ -27,7 +26,7 @@ AC_PATH_PROGS(ENV_CMD, [env printenv], )
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h])
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h sys/types.h sys/stat.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@ -41,7 +40,7 @@ AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MEMCMP
AC_CHECK_FUNCS([atexit fchmod getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol])
AC_CHECK_FUNCS([atexit getcwd memmove memset strcasecmp strchr strdup strerror strncasecmp strrchr strstr strtol])
# Some directories
MSC_BASE_DIR=`pwd`

View File

@ -3,9 +3,6 @@
/* Define to 1 if you have the `atexit' function. */
#undef HAVE_ATEXIT
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H

View File

@ -392,6 +392,10 @@ struct directory_config {
/* AUDITLOG_SERIAL (single file) or AUDITLOG_CONCURRENT (multiple files) */
int auditlog_type;
/* Mode for audit log directories and files */
apr_fileperms_t auditlog_dirperms;
apr_fileperms_t auditlog_fileperms;
/* The name of the audit log file (for the old type), or the
* name of the index file (for the new audit log type)
*/
@ -425,7 +429,7 @@ struct directory_config {
const char *upload_dir;
int upload_keep_files;
int upload_validates_files;
int upload_filemode;
int upload_filemode; /* int only so NOT_SET works */
/* Used only in the configuration phase. */
msre_rule *tmp_chain_starter;

View File

@ -16,6 +16,9 @@
* directly using the email address support@breach.com.
*
*/
#include <sys/stat.h>
#include "mod_security2_config.h"
#include "re.h"
#include "msc_logging.h"
#include "httpd.h"
@ -443,7 +446,7 @@ void sec_audit_logger(modsec_rec *msr) {
* we could cache the time we last checked and don't check if we know
* the folder is there.
*/
rc = apr_dir_make_recursive(entry_basename, CREATEMODE_DIR, msr->mp);
rc = apr_dir_make_recursive(entry_basename, msr->txcfg->auditlog_dirperms, msr->mp);
if (rc != APR_SUCCESS) {
msr_log(msr, 1, "Audit log: Failed to create subdirectories: %s (%s)",
entry_basename, get_apr_error(msr->mp, rc));
@ -452,7 +455,7 @@ void sec_audit_logger(modsec_rec *msr) {
rc = apr_file_open(&msr->new_auditlog_fd, entry_filename,
APR_WRITE | APR_TRUNCATE | APR_CREATE | APR_BINARY | APR_FILE_NOCLEANUP,
CREATEMODE, msr->mp);
msr->txcfg->auditlog_fileperms, msr->mp);
if (rc != APR_SUCCESS) {
msr_log(msr, 1, "Audit log: Failed to create file: %s (%s)",
entry_filename, get_apr_error(msr->mp, rc));

View File

@ -396,7 +396,7 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
/* construct temporary file name */
msr->mpd->mpp->tmp_file_name = apr_psprintf(msr->mp, "%s/%s-%s-file-XXXXXX",
msr->txcfg->tmp_dir, current_filetime(msr->mp), msr->txid);
msr->mpd->mpp->tmp_file_fd = msc_mkstemp(msr->mpd->mpp->tmp_file_name);
msr->mpd->mpp->tmp_file_fd = msc_mkstemp_ex(msr->mpd->mpp->tmp_file_name, msr->txcfg->upload_filemode);
/* do we have an opened file? */
if (msr->mpd->mpp->tmp_file_fd < 0) {
@ -409,21 +409,6 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
msr_log(msr, 4, "Multipart: Created temporary file: %s",
log_escape_nq(msr->mp, msr->mpd->mpp->tmp_file_name));
}
#ifdef HAVE_FCHMOD
if (msr->txcfg->debuglog_level >= 9) {
msr_log(msr, 9, "Multipart: Changing file mode to %04o: %s", msr->txcfg->upload_filemode, log_escape_nq(msr->mp, msr->mpd->mpp->tmp_file_name));
}
if (fchmod(msr->mpd->mpp->tmp_file_fd, msr->txcfg->upload_filemode) < 0) {
char errbuf[256];
if (msr->txcfg->debuglog_level >= 3) {
msr_log(msr, 3, "Multipart: Could not change mode on \"%s\" (%d): %s",
log_escape_nq(msr->mp, msr->mpd->mpp->tmp_file_name),
errno, apr_strerror(APR_FROM_OS_ERROR(errno), errbuf, 256));
}
}
#endif
}
/* write the reserve first */

View File

@ -418,17 +418,24 @@ char *current_filetime(apr_pool_t *mp) {
/**
*
*/
int msc_mkstemp(char *template) {
int msc_mkstemp_ex(char *template, mode_t mode) {
/* ENH Use apr_file_mktemp instead. */
#if !(defined(WIN32)||defined(NETWARE))
return mkstemp(template);
#else
if (mktemp(template) == NULL) return -1;
return open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, CREATEMODE_UNISTD);
return open(template, O_WRONLY | O_APPEND | O_CREAT | O_BINARY, mode);
#endif
}
/**
*
*/
int msc_mkstemp(char *template) {
return msc_mkstemp_ex(template, CREATEMODE_UNISTD);
}
/**
* Converts the input string to lowercase (in-place).
*/
@ -1351,3 +1358,26 @@ int css_decode_inplace(unsigned char *input, long int input_len) {
return count;
}
/**
* Translate UNIX octal umask/mode to APR apr_fileperms_t
*/
apr_fileperms_t mode2fileperms(mode_t mode) {
apr_fileperms_t perms = 0;
if (mode & S_IXOTH) perms |= APR_WEXECUTE;
if (mode & S_IWOTH) perms |= APR_WWRITE;
if (mode & S_IROTH) perms |= APR_WREAD;
if (mode & S_IXGRP) perms |= APR_GEXECUTE;
if (mode & S_IWGRP) perms |= APR_GWRITE;
if (mode & S_IRGRP) perms |= APR_GREAD;
if (mode & S_IXUSR) perms |= APR_UEXECUTE;
if (mode & S_IWUSR) perms |= APR_UWRITE;
if (mode & S_IRUSR) perms |= APR_UREAD;
if (mode & S_ISVTX) perms |= APR_WSTICKY;
if (mode & S_ISGID) perms |= APR_GSETID;
if (mode & S_ISUID) perms |= APR_USETID;
return perms;
}

View File

@ -19,6 +19,9 @@
#ifndef _UTIL_H_
#define _UTIL_H_
#include <sys/types.h>
#include <apr_file_info.h>
#include "modsecurity.h"
int DSOLOCAL normalise_path_inplace(unsigned char *input, int len, int win, int *changed);
@ -53,6 +56,8 @@ char DSOLOCAL *current_logtime(apr_pool_t *mp);
char DSOLOCAL *current_filetime(apr_pool_t *mp);
int DSOLOCAL msc_mkstemp_ex(char *template, mode_t mode);
int DSOLOCAL msc_mkstemp(char *template);
char DSOLOCAL *strtolower_inplace(unsigned char *str);
@ -94,4 +99,6 @@ char DSOLOCAL *resolve_relative_path(apr_pool_t *pool, const char *parent_filena
int DSOLOCAL css_decode_inplace(unsigned char *input, long int input_len);
apr_fileperms_t DSOLOCAL mode2fileperms(mode_t mode);
#endif

View File

@ -6,7 +6,7 @@
Manual</title>
<articleinfo>
<releaseinfo>Version 2.6.0-trunk (Aug 12, 2009)</releaseinfo>
<releaseinfo>Version 2.6.0-trunk (Aug 24, 2009)</releaseinfo>
<copyright>
<year>2004-2009</year>
@ -698,6 +698,79 @@ SecAuditLogStorageDir logs/audit
audit logging.</para>
</section>
<section>
<title><literal>SecAuditLogDirMode</literal></title>
<para><emphasis>Description:</emphasis> Configures the mode
(permissions) of any directories created for concurrent audit logs using
an octal mode (as used in chmod). See <literal
moreinfo="none">SecAuditLogFileMode</literal> for controlling the mode
of audit log files.</para>
<para><emphasis>Syntax:</emphasis> <literal
moreinfo="none">SecAuditLogDirMode octal_mode|"default"</literal></para>
<para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecAuditLogDirMode 02750</literal></para>
<para><emphasis>Processing Phase:</emphasis> N/A</para>
<para><emphasis>Scope:</emphasis> Any</para>
<para><emphasis>Version:</emphasis> 2.5.10</para>
<para><emphasis>Dependencies/Notes:</emphasis> This feature is not
available on operating systems not supporting octal file modes. The
default mode (0600) only grants read/write access to the account writing
the file. If access from another account is needed (using mpm-itk is a
good example), then this directive may be required. However, use this
directive with caution to avoid exposing potentially sensitive data to
unauthorized users. Using the value "default" will revert back to the
default setting.</para>
<note>
<para>The process umask may still limit the mode if it is being more
restrictive than the mode set using this directive.</para>
</note>
</section>
<section>
<title><literal>SecAuditLogFileMode</literal></title>
<para><emphasis>Description:</emphasis> Configures the mode
(permissions) of any files created for concurrent audit logs using an
octal mode (as used in chmod). See <literal
moreinfo="none">SecAuditLogDirMode</literal> for controlling the mode of
created audit log directories.</para>
<para><emphasis>Syntax:</emphasis> <literal
moreinfo="none">SecAuditLogFileMode
octal_mode|"default"</literal></para>
<para><emphasis>Example Usage:</emphasis> <literal
moreinfo="none">SecAuditLogFileMode 00640</literal></para>
<para><emphasis>Processing Phase:</emphasis> N/A</para>
<para><emphasis>Scope:</emphasis> Any</para>
<para><emphasis>Version:</emphasis> 2.5.10</para>
<para><emphasis>Dependencies/Notes:</emphasis> This feature is not
available on operating systems not supporting octal file modes. The
default mode (0600) only grants read/write access to the account writing
the file. If access from another account is needed (using mpm-itk is a
good example), then this directive may be required. However, use this
directive with caution to avoid exposing potentially sensitive data to
unauthorized users. Using the value "default" will revert back to the
default setting.</para>
<note>
<para>The process umask may still limit the mode if it is being more
restrictive than the mode set using this directive.</para>
</note>
</section>
<section>
<title><literal>SecAuditLogParts</literal></title>
@ -2400,7 +2473,7 @@ SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new m
<title><literal>SecUploadFileMode</literal></title>
<para><emphasis>Description:</emphasis> Configures the mode
(permissions) of any uploaded files using an octal number (as used in
(permissions) of any uploaded files using an octal mode (as used in
chmod).</para>
<para><emphasis>Syntax:</emphasis> <literal
@ -2423,6 +2496,11 @@ SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new m
directive with caution to avoid exposing potentially sensitive data to
unauthorized users. Using the value "default" will revert back to the
default setting.</para>
<note>
<para>The process umask may still limit the mode if it is being more
restrictive than the mode set using this directive.</para>
</note>
</section>
<section>
@ -4757,9 +4835,9 @@ setvar:session.suspicious=1,<emphasis>expirevar:session.suspicious=3600</emphasi
<para><emphasis>Note</emphasis></para>
<para>Normally you will want to use <emphasis>phase:1</emphasis>
along with <emphasis>initcol</emphasis> so that the collection is
available in all phases.</para>
<para>Normally you will want to use <emphasis>phase:1</emphasis> along
with <emphasis>initcol</emphasis> so that the collection is available in
all phases.</para>
<para>Collections are loaded into memory when the initcol action is
encountered. The collection in storage will be persisted (and the