[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] Make mod_authz_svn to apply the authz checks against upper/lowercased usernames

From: Kamesh Jayachandran <kamesh_at_collab.net>
Date: Fri, 07 Mar 2008 21:32:14 +0530

Hi All,

People using mod_auth_sspi(windows domain authentication apache module)
face the 'Authorization Failed' error while
accessing SVN with mixed case usernames which does not match in *exact
case* with their authz rules.

http://blog.michaelcheng.idv.hk/ explains it in detail.

mod_auth_sspi has a directive by name 'SSPIUsernameCase' with possible
values being 'Lower/Upper'.

I am not sure whether it really uses it to compare the
lowered/uppercased username.

I feel we should have similar directive in mod_authz_svn, to author the
*sane* authz rules in these mixed
case username scenarios.

Attached patch accomplishes that.

Want to know what community thinks about it.

With regards
Kamesh Jayachandran

[[[
Make mod_authz_svn to apply the authz checks against upper/lowercased
usernames.

* subversion/mod_authz_svn/mod_authz_svn.c
  (): Include 'apr_lib.h' and 'strings.h'.
  (struct authz_svn_config_rec): New member 'usernamecase'.
  (authz_svn_cmds): Populate 'authz_svn_config_rec.usernamecase'
   from configuration directive 'AuthzUsernameCase'.
  (convert_to_uppercase_string,
   convert_to_lowercase_string,
   get_username_to_authorize): New functions.
  (req_check_access, subreq_bypass): Apply authz check against
   upper/lowercased usernames.
]]]

Index: subversion/mod_authz_svn/mod_authz_svn.c
===================================================================
--- subversion/mod_authz_svn/mod_authz_svn.c (revision 29765)
+++ subversion/mod_authz_svn/mod_authz_svn.c (working copy)
@@ -28,6 +28,8 @@
 #include <ap_config.h>
 #include <ap_provider.h>
 #include <apr_uri.h>
+#include <apr_lib.h>
+#include <strings.h>
 #include <mod_dav.h>
 
 #include "mod_dav_svn.h"
@@ -46,6 +48,7 @@
     int no_auth_when_anon_ok;
     const char *base_path;
     const char *access_file;
+ const char *usernamecase;
 } authz_svn_config_rec;
 
 /*
@@ -90,6 +93,11 @@
                  "Set to 'On' to suppress authentication and authorization "
                  "for requests which anonymous users are allowed to perform. "
                  "(default is Off.)"),
+ AP_INIT_TAKE1("AuthzUsernameCase", ap_set_string_slot,
+ (void *)APR_OFFSETOF(authz_svn_config_rec, usernamecase),
+ OR_AUTHCFG,
+ "Set to 'Upper' or 'Lower' to convert the username before "
+ "checking for authorization."),
     { NULL }
 };
 
@@ -135,6 +143,40 @@
     return access_conf;
 }
 
+/* Converts STR_TO_CONVERT to upper case.*/
+static void convert_to_uppercase_string(char *str_to_convert)
+{
+ char *c = str_to_convert;
+ while (*c) {
+ *c = apr_toupper(*c);
+ ++c;
+ }
+}
+
+/* Converts STR_TO_CONVERT to lower case.*/
+static void convert_to_lowercase_string(char *str_to_convert)
+{
+ char *c = str_to_convert;
+ while (*c) {
+ *c = apr_tolower(*c);
+ ++c;
+ }
+}
+
+static char* get_username_to_authorize(request_rec *r,
+ authz_svn_config_rec *conf)
+{
+ char *username_to_authorize = r->user;
+ if (conf->usernamecase) {
+ username_to_authorize = apr_pstrdup(r->pool, r->user);
+ if (strcasecmp(conf->usernamecase, "upper") == 0)
+ convert_to_uppercase_string(username_to_authorize);
+ else
+ convert_to_lowercase_string(username_to_authorize);
+ }
+ return username_to_authorize;
+}
+
 /* Check if the current request R is allowed. Upon exit *REPOS_PATH_REF
  * will contain the path and repository name that an operation was requested
  * on in the form 'name:path'. *DEST_REPOS_PATH_REF will contain the
@@ -162,6 +204,7 @@
     svn_authz_t *access_conf = NULL;
     svn_error_t *svn_err;
     char errbuf[256];
+ const char *username_to_authorize = get_username_to_authorize(r, conf);
 
     switch (r->method_number) {
     /* All methods requiring read access to all subtrees of r->uri */
@@ -307,7 +350,8 @@
         || (!repos_path && (authz_svn_type & svn_authz_write)))
       {
         svn_err = svn_repos_authz_check_access(access_conf, repos_name,
- repos_path, r->user,
+ repos_path,
+ username_to_authorize,
                                                authz_svn_type,
                                                &authz_access_granted,
                                                r->pool);
@@ -353,7 +397,7 @@
         svn_err = svn_repos_authz_check_access(access_conf,
                                                dest_repos_name,
                                                dest_repos_path,
- r->user,
+ username_to_authorize,
                                                svn_authz_write
                                                |svn_authz_recursive,
                                                &authz_access_granted,
@@ -437,9 +481,11 @@
     authz_svn_config_rec *conf = NULL;
     svn_boolean_t authz_access_granted = FALSE;
     char errbuf[256];
+ const char *username_to_authorize;
 
     conf = ap_get_module_config(r->per_dir_config,
                                 &authz_svn_module);
+ username_to_authorize = get_username_to_authorize(r, conf);
 
     /* If configured properly, this should never be true, but just in case. */
     if (!conf->anonymous || !conf->access_file) {
@@ -457,7 +503,8 @@
      */
     if (repos_path) {
         svn_err = svn_repos_authz_check_access(access_conf, repos_name,
- repos_path, r->user,
+ repos_path,
+ username_to_authorize,
                                                svn_authz_none|svn_authz_read,
                                                &authz_access_granted,
                                                r->pool);

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-03-07 17:03:00 CET

This is an archived mail posted to the Subversion Dev mailing list.