Created
March 22, 2012 01:09
-
-
Save anonymous/2154942 to your computer and use it in GitHub Desktop.
Patch Atlassian mod_authnz_crowd to provide space-delimited list of remote user's groups to CGIs via a user-configurable environment variable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- src/crowd_client.h 2012-03-16 14:05:25.000000000 +0900 | |
+++ src/crowd_client.h 2012-03-16 14:52:02.000000000 +0900 | |
@@ -14,6 +14,7 @@ | |
const char *crowd_app_password; /* Application password used to authenticate with Crowd */ | |
const char *crowd_url; /* Base URL of the Crowd server */ | |
long crowd_timeout; /* Crowd response timeout, in seconds, or 0 for no timeout */ | |
+ const char *groups_env_name; /* Name of the environment variable to store a space-delimited list of groups that the remote user belongs to */ | |
} crowd_config; | |
/** | |
--- src/mod_authnz_crowd.c 2011-03-29 14:51:32.000000000 +0900 | |
+++ src/mod_authnz_crowd.c 2012-03-21 16:11:49.000000000 +0900 | |
@@ -26,6 +26,8 @@ | |
#include "mod_authnz_crowd.h" | |
+#define CROWD_GROUPS_ENV_NAME "CrowdGroupsEnvName" | |
+ | |
typedef struct | |
{ | |
const char *cache_max_entries_string; | |
@@ -205,6 +207,12 @@ | |
return set_flag_once(parms, &(config->create_sso), &(config->create_sso_set), on); | |
} | |
+static const char *set_crowd_groups_env_name(cmd_parms *parms, void *mconfig, const char *w) | |
+{ | |
+ authnz_crowd_dir_config *config = (authnz_crowd_dir_config *) mconfig; | |
+ return set_once(parms, &(config->crowd_config->groups_env_name), w); | |
+} | |
+ | |
static const command_rec commands[] = | |
{ | |
AP_INIT_FLAG("AuthzCrowdAuthoritative", set_authz_crowd_authoritative, NULL, OR_AUTHCFG, | |
@@ -230,6 +238,8 @@ | |
"'On' if single-sign on cookies should be accepted; 'Off' otherwise (default = On)"), | |
AP_INIT_FLAG("CrowdCreateSSO", set_crowd_create_sso, NULL, OR_AUTHCFG, | |
"'On' if single-sign on cookies should be created; 'Off' otherwise (default = On)"), | |
+ AP_INIT_TAKE1(CROWD_GROUPS_ENV_NAME, set_crowd_groups_env_name, NULL, OR_AUTHCFG, | |
+ "Name of the environment variable to store a space-delimited list of groups that the remote user belongs to"), | |
{NULL} | |
}; | |
@@ -287,6 +297,59 @@ | |
return 1; | |
} | |
+#define GRP_ENV_MAX_GROUPS 128 | |
+#define GRP_ENV_DELIMITER " " | |
+#define GRP_ENV_DELIMITER_LEN (sizeof(GRP_ENV_DELIMITER) - sizeof(char)) | |
+static void crowd_set_groups_env_variable(request_rec *r) { | |
+ authnz_crowd_dir_config *config = get_config(r); | |
+ const char *group_env_name = config->crowd_config->groups_env_name; | |
+ if (group_env_name == NULL) { | |
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, CROWD_GROUPS_ENV_NAME " undefined; returning."); | |
+ return; | |
+ } | |
+ | |
+ apr_array_header_t *user_groups = authnz_crowd_user_groups(r->user, r); | |
+ if (user_groups == NULL) { | |
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "While settings groups environment variable '%s': authnz_crowd_user_groups() returned NULL.", group_env_name); | |
+ return; | |
+ } | |
+ | |
+ apr_size_t ngrps = user_groups->nelts; | |
+ if (ngrps >= GRP_ENV_MAX_GROUPS) { | |
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "Groups environment variable '%s' value will be clipped: Number of groups (%d) exceeds MAX_GROUPS (%d).", group_env_name, ngrps, GRP_ENV_MAX_GROUPS); | |
+ ngrps = GRP_ENV_MAX_GROUPS; | |
+ } | |
+ | |
+ apr_size_t nvec = ngrps * 2 - 1; /* Including delimiters: x1 (' ' x2) (' ' x3) ... */ | |
+ if (nvec < 0) { | |
+ nvec = 0; | |
+ } | |
+ struct iovec *iov = apr_pcalloc(r->pool, sizeof(struct iovec) * nvec); | |
+ int i, k; | |
+ for (i = 0, k = 0; i < ngrps; i++) { | |
+ if (i >= 1) { | |
+ /* Join previous entry with a delimiter */ | |
+ iov[k].iov_base = GRP_ENV_DELIMITER; | |
+ iov[k].iov_len = GRP_ENV_DELIMITER_LEN; | |
+ k++; | |
+ } | |
+ | |
+ void *grp = APR_ARRAY_IDX(user_groups, i, void *); | |
+ iov[k].iov_base = grp; | |
+ iov[k].iov_len = strlen(grp); | |
+ k++; | |
+ } | |
+ | |
+ const char *groups = apr_pstrcatv(r->pool, iov, nvec, NULL); | |
+ if (groups == NULL) { | |
+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "While setting groups environment variable '%s': apr_pstrcatv() returned NULL.", group_env_name); | |
+ return; | |
+ } | |
+ | |
+ apr_table_set(r->subprocess_env, group_env_name, groups); | |
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Set groups environment variable '%s' to '%s'", group_env_name, groups); | |
+} | |
+ | |
static int check_user_id(request_rec *r) { | |
authnz_crowd_dir_config *config = get_config(r); | |
if (config == NULL || !(config->accept_sso)) { | |
@@ -299,6 +362,7 @@ | |
} | |
if (crowd_validate_session(r, config->crowd_config, data.token, &r->user) == CROWD_AUTHENTICATE_SUCCESS) { | |
r->ap_auth_type = "Crowd SSO"; | |
+ crowd_set_groups_env_variable(r); | |
return OK; | |
} | |
return DECLINED; | |
@@ -366,6 +430,7 @@ | |
switch (result) { | |
case CROWD_AUTHENTICATE_SUCCESS: | |
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, "Authenticated '%s'.", xlated_user); | |
+ crowd_set_groups_env_variable(r); | |
return AUTH_GRANTED; | |
case CROWD_AUTHENTICATE_FAILURE: | |
break; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment