Hi,
I'd like to add alias functionality to the authorization
configuration. This is primarily useful in combination with
doing client certificate authentication. You can refer to a
cert subject using &alias, instead of having to replicate it
in multiple places.
An example illustrates this best, but you have to imagine doing
this when you have a bit more than one cert:
[aliases]
striker = /C=US/ST=ExampleState/O=Example Inc/L=ExampleTown/OU=example/CN=Sander Striker/emailAddress=striker@example.com
[groups]
group = &striker,
[/]
* = r
&striker = rw
[/foo]
@group = r
If I hear no objections, I'll commit this trivial change tomorrow.
Sander
Add alias functionality to authorization configuration.
* subversion/libsvn_repos/authz.c
(authz_alias_is_user, authz_validate_alias): New function.
(authz_group_contains_user): Resolve aliases within groups.
(authz_parse_line): Resolve aliases.
(authz_group_walk, authz_validate_rule): Verify existence of referenced
aliases.
(authz_validate_sect): Validate new 'aliases' section.
Index: subversion/libsvn_repos/authz.c
===================================================================
--- subversion/libsvn_repos/authz.c (revision 21926)
+++ subversion/libsvn_repos/authz.c (working copy)
@@ -123,6 +123,28 @@
return FALSE;
}
+/* Return TRUE is USER equals ALIAS. The alias definitions are in the
+ "aliases" sections of CFG. Use POOL for temporary allocations during
+ the lookup. */
+static svn_boolean_t
+authz_alias_is_user(svn_config_t *cfg,
+ const char *alias,
+ const char *user,
+ apr_pool_t *pool)
+{
+ const char *value;
+
+ svn_config_get(cfg, &value, "aliases", alias, NULL);
+ if (!value)
+ return FALSE;
+
+ if (strcmp(value, user) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+
/* Return TRUE if USER is in GROUP. The group definitions are in the
"groups" section of CFG. Use POOL for temporary allocations during
the lookup. */
@@ -152,6 +174,14 @@
return TRUE;
}
+ /* If the 'user' is an alias, verify it. */
+ else if (*group_user == '&')
+ {
+ if (authz_alias_is_user(cfg, &group_user[1],
+ user, pool))
+ return TRUE;
+ }
+
/* If the user matches, stop. */
else if (strcmp(user, group_user) == 0)
return TRUE;
@@ -185,6 +215,14 @@
return TRUE;
}
+ /* Alias rule and user not alias. Stop. */
+ else if (*name == '&')
+ {
+ if (!authz_alias_is_user(b->config, &name[1],
+ b->user, pool))
+ return TRUE;
+ }
+
/* User rule for wrong user. Stop. */
else if (strcmp(name, b->user) != 0)
return TRUE;
@@ -427,16 +465,29 @@
SVN_ERR(authz_group_walk(cfg, &group_user[1],
checked_groups, pool));
}
+ else if (*group_user == '&')
+ {
+ const char *alias;
+
+ svn_config_get(cfg, &alias, "aliases", &group_user[1], NULL);
+ /* Having a non-existent alias in the ACL configuration might be the
+ sign of a typo. Refuse to perform authz on uncertain rules. */
+ if (!alias)
+ return svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,
+ "An authz rule refers to alias '%s', "
+ "which is undefined",
+ &group_user[1]);
+ }
}
return SVN_NO_ERROR;
}
-/* Callback to check whether GROUP is a group name, and if so, whether
- the group definition exists. Return TRUE if the rule has no
- errors. Use BATON for context and error reporting. */
-static svn_boolean_t authz_validate_rule(const char *group,
+/* Callback to check whether NAME is a group or alias name, and if so,
+ whether the group or alias definition exists. Return TRUE if the rule
+ has no errors. Use BATON for context and error reporting. */
+static svn_boolean_t authz_validate_rule(const char *name,
const char *value,
void *baton,
apr_pool_t *pool)
@@ -445,9 +496,9 @@
struct authz_validate_baton *b = baton;
/* If the rule applies to a group, check its existence. */
- if (*group == '@')
+ if (*name == '@')
{
- svn_config_get(b->config, &val, "groups", &group[1], NULL);
+ svn_config_get(b->config, &val, "groups", &name[1], NULL);
/* Having a non-existent group in the ACL configuration might be
the sign of a typo. Refuse to perform authz on uncertain
rules. */
@@ -456,11 +507,25 @@
b->err = svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,
"An authz rule refers to group "
"'%s', which is undefined",
- group);
+ name);
return FALSE;
}
}
+ /* If the rule applies to an alias, check its existence. */
+ if (*name == '&')
+ {
+ svn_config_get (b->config, &val, "aliases", &name[1], NULL);
+ if (!val)
+ {
+ b->err = svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,
+ "An authz rule refers to alias "
+ "'%s', which is undefined",
+ name);
+ return FALSE;
+ }
+ }
+
val = value;
while (*val)
@@ -468,7 +533,7 @@
if (*val != 'r' && *val != 'w' && ! svn_ctype_isspace(*val))
b->err = svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL,
"The character '%c' in rule '%s' is not "
- "allowed in authz rules", *val, group);
+ "allowed in authz rules", *val, name);
++val;
}
@@ -476,7 +541,18 @@
return TRUE;
}
+/* Callback to check ALIAS's definition for validity. Use
+ BATON for context and error reporting. */
+static svn_boolean_t authz_validate_alias(const char *alias,
+ const char *value,
+ void *baton,
+ apr_pool_t *pool)
+{
+ /* No checking at the moment, every alias is valid */
+ return TRUE;
+}
+
/* Callback to check GROUP's definition for cyclic dependancies. Use
BATON for context and error reporting. */
static svn_boolean_t authz_validate_group(const char *group,
@@ -507,6 +583,9 @@
if (strncmp(name, "groups", 6) == 0)
svn_config_enumerate2(b->config, name, authz_validate_group,
baton, pool);
+ else if (strncmp(name, "aliases", 7) == 0)
+ svn_config_enumerate2(b->config, name, authz_validate_alias,
+ baton, pool);
else
svn_config_enumerate2(b->config, name, authz_validate_rule,
baton, pool);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Oct 16 00:38:59 2006