Index: server/common/oursrc/httpdmods/Makefile.in
===================================================================
--- server/common/oursrc/httpdmods/Makefile.in	(revision 389)
+++ server/common/oursrc/httpdmods/Makefile.in	(revision 390)
@@ -1,5 +1,5 @@
 APXS = apxs
 
-MODS = mod_auth_sslcert mod_authz_afsgroup
+MODS = mod_auth_sslcert mod_authz_afsgroup mod_auth_optional
 
 all-local: $(patsubst %,.libs/%.so,$(MODS))
Index: server/common/oursrc/httpdmods/mod_auth_optional.c
===================================================================
--- server/common/oursrc/httpdmods/mod_auth_optional.c	(revision 390)
+++ server/common/oursrc/httpdmods/mod_auth_optional.c	(revision 390)
@@ -0,0 +1,80 @@
+/* mod_auth_optional
+ * version 1.0, released 2007-09-01
+ * Anders Kaseorg <andersk@mit.edu>
+ *
+ * This module can pretend that authentication succeeded even if no
+ * authorization module is authoritative, instead of returning a
+ * Forbidden error.
+ */
+
+#include "ap_config.h"
+#include "httpd.h"
+#include "http_config.h"
+#include "http_request.h"
+
+typedef struct {
+    int optional;
+    char *default_user;
+} auth_optional_config_rec;
+
+static void *create_auth_optional_dir_config(apr_pool_t *p, char *d)
+{
+    auth_optional_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
+    conf->optional = 0;
+    conf->default_user = NULL;
+    return conf;
+}
+
+static const command_rec auth_optional_cmds[] =
+{
+    AP_INIT_FLAG("AuthOptional", ap_set_flag_slot,
+                 (void *)APR_OFFSETOF(auth_optional_config_rec, optional),
+                 OR_AUTHCFG,
+                 "Make authentication succeed if no authorization module is authoritative"),
+    AP_INIT_TAKE1("AuthOptionalDefaultUser", ap_set_string_slot,
+                   (void*)APR_OFFSETOF(auth_optional_config_rec, default_user),
+                  OR_AUTHCFG,
+                  "Default username to use if no authorization module is authoritative"),
+    {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA auth_optional_module;
+
+static int auth_optional_check_user_id(request_rec *r)
+{
+    auth_optional_config_rec *conf = ap_get_module_config(r->per_dir_config,
+							  &auth_optional_module);
+    if (!conf->optional)
+	return DECLINED;
+
+    r->user = conf->default_user;
+    return OK;
+}
+
+static int auth_optional_auth_checker(request_rec *r)
+{
+    auth_optional_config_rec *conf = ap_get_module_config(r->per_dir_config,
+							  &auth_optional_module);
+    if (!conf->optional || conf->default_user != NULL)
+	return DECLINED;
+
+    return OK;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+    /* Right before mod_authz_default. */
+    ap_hook_check_user_id(auth_optional_check_user_id, NULL, NULL, APR_HOOK_LAST - 1);
+    ap_hook_auth_checker(auth_optional_auth_checker, NULL, NULL, APR_HOOK_REALLY_FIRST);
+}
+
+module AP_MODULE_DECLARE_DATA auth_optional_module =
+{
+    STANDARD20_MODULE_STUFF,
+    create_auth_optional_dir_config, /* dir config creater */
+    NULL,                            /* dir merger --- default is to override */
+    NULL,                            /* server config */
+    NULL,                            /* merge server config */
+    auth_optional_cmds,              /* command apr_table_t */
+    register_hooks                   /* register hooks */
+};
Index: server/common/oursrc/httpdmods/mod_auth_sslcert.c
===================================================================
--- server/common/oursrc/httpdmods/mod_auth_sslcert.c	(revision 389)
+++ server/common/oursrc/httpdmods/mod_auth_sslcert.c	(revision 390)
@@ -1,5 +1,5 @@
 /* mod_auth_sslcert
- * version 1.0, released 2007-01-04
- * Anders Kaseorg <anders@kaseorg.com>
+ * version 1.1, released 2007-09-01 [NOT RELEASED YET]
+ * Anders Kaseorg <andersk@mit.edu>
  *
  * This module does authentication based on SSL client certificates:
@@ -18,4 +18,5 @@
 #include "http_core.h"
 #include "http_log.h"
+#include "http_request.h"
 
 #include "mod_auth.h"
@@ -25,19 +26,31 @@
 
 typedef struct {
-    char *dir;
     int authoritative;
     char *var;
     char *strip_suffix;
+    int strip_suffix_required;
 } auth_sslcert_config_rec;
 
-static void *create_auth_sslcert_dir_config(apr_pool_t *p, char *d)
+static void *create_auth_sslcert_dir_config(apr_pool_t *p, char *dirspec)
 {
     auth_sslcert_config_rec *conf = apr_pcalloc(p, sizeof(*conf));
 
-    conf->dir = d;
-    /* Any failures are fatal. */
     conf->authoritative = 1;
     conf->var = NULL;
     conf->strip_suffix = NULL;
+    conf->strip_suffix_required = 1;
+
+    return conf;
+}
+
+static void *merge_auth_sslcert_dir_config(apr_pool_t *p, void *parent_conf, void *newloc_conf)
+{
+    auth_sslcert_config_rec *pconf = parent_conf, *nconf = newloc_conf,
+	*conf = apr_pcalloc(p, sizeof(*conf));
+
+    conf->authoritative = nconf->authoritative;
+    conf->var = (nconf->var != NULL) ? nconf->var : pconf->var;
+    conf->strip_suffix = (nconf->var != NULL || nconf->strip_suffix != NULL) ?
+	nconf->strip_suffix : pconf->strip_suffix;
 
     return conf;
@@ -59,4 +72,9 @@
 		  OR_AUTHCFG,
 		  "An optional suffix to strip from the username"),
+    AP_INIT_FLAG("AuthSSLCertStripSuffixRequired", ap_set_flag_slot,
+		 (void *)APR_OFFSETOF(auth_sslcert_config_rec, strip_suffix_required),
+		 OR_AUTHCFG,
+		 "Set to 'Off' to allow certs that don't end with a recognized "
+		 "suffix to still authenticate"),
     {NULL}
 };
@@ -94,8 +112,11 @@
 		    r->user = apr_pstrmemdup(r->pool, user, i);
 		    return OK;
+		} else if (!conf->strip_suffix_required) {
+		    r->user = user;
+		    return OK;
 		} else {
 		    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 				  "SSL username for \"%s\" has wrong suffix: \"%s\"",
-				  r->uri, r->user);
+				  r->uri, user);
 		}
 	    } else {
@@ -107,6 +128,6 @@
 			  "no SSL username for \"%s\"", r->uri);
 	}
-    } else {
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+    } else if (conf->authoritative) {
+	ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
 		      "SSL client not verified for \"%s\"", r->uri);
     }
@@ -130,6 +151,6 @@
 static void register_hooks(apr_pool_t *p)
 {
-    ap_hook_check_user_id(authenticate_sslcert_user,NULL,NULL,APR_HOOK_MIDDLE);
-    ap_hook_optional_fn_retrieve(import_ssl_var_lookup,NULL,NULL,APR_HOOK_MIDDLE);
+    ap_hook_check_user_id(authenticate_sslcert_user, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_optional_fn_retrieve(import_ssl_var_lookup, NULL, NULL, APR_HOOK_MIDDLE);
 }
 
@@ -138,5 +159,5 @@
     STANDARD20_MODULE_STUFF,
     create_auth_sslcert_dir_config,  /* dir config creater */
-    NULL,                            /* dir merger --- default is to override */
+    merge_auth_sslcert_dir_config,   /* dir merger */
     NULL,                            /* server config */
     NULL,                            /* merge server config */
Index: server/fedora/specs/httpdmods.spec
===================================================================
--- server/fedora/specs/httpdmods.spec	(revision 389)
+++ server/fedora/specs/httpdmods.spec	(revision 390)
@@ -17,4 +17,5 @@
  - module to do authentication based on SSL certificates <mod_auth_sslcert>
  - module to do authorization based on Athena AFS groups <mod_authz_afsgroup>
+ - module to enable optional authentication <mod_auth_optional>
 See http://scripts.mit.edu/wiki for more information.
 
@@ -30,4 +31,5 @@
 install -D .libs/mod_auth_sslcert.so $RPM_BUILD_ROOT/usr/lib64/httpd/modules/mod_auth_sslcert.so
 install -D .libs/mod_authz_afsgroup.so $RPM_BUILD_ROOT/usr/lib64/httpd/modules/mod_authz_afsgroup.so
+install -D .libs/mod_auth_optional.so $RPM_BUILD_ROOT/usr/lib64/httpd/modules/mod_auth_optional.so
 
 %clean
@@ -38,4 +40,5 @@
 /usr/lib64/httpd/modules/mod_auth_sslcert.so
 /usr/lib64/httpd/modules/mod_authz_afsgroup.so
+/usr/lib64/httpd/modules/mod_auth_optional.so
 
 %changelog
