mirror of
https://github.com/apache/httpd.git
synced 2025-08-07 04:02:58 +03:00
Add specified user attributes to the environment when using
mod_auth_ldap. This allows you to use mod_include to embed specified user attributes in a page like so: Hello <!--#echo var="AUTHENTICATE_CN"-->, how are you? PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90775 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,5 +1,11 @@
|
|||||||
Changes with Apache 2.0.25-dev
|
Changes with Apache 2.0.25-dev
|
||||||
|
|
||||||
|
*) Add specified user attributes to the environment when using
|
||||||
|
mod_auth_ldap. This allows you to use mod_include to embed specified
|
||||||
|
user attributes in a page like so:
|
||||||
|
Hello <!--#echo var="AUTHENTICATE_CN"-->, how are you?
|
||||||
|
[Graham Leggett]
|
||||||
|
|
||||||
*) Fix a performance problem with the worker MPM. We now create
|
*) Fix a performance problem with the worker MPM. We now create
|
||||||
transaction pools once, and re-use them for each connection.
|
transaction pools once, and re-use them for each connection.
|
||||||
[Aaron Bannert <aaron@clove.org>]
|
[Aaron Bannert <aaron@clove.org>]
|
||||||
|
@@ -232,19 +232,21 @@ int util_ldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
* @param url The URL of the LDAP connection - used for deciding which cache to use.
|
* @param url The URL of the LDAP connection - used for deciding which cache to use.
|
||||||
* @param basedn The Base DN to search for the user in.
|
* @param basedn The Base DN to search for the user in.
|
||||||
* @param scope LDAP scope of the search.
|
* @param scope LDAP scope of the search.
|
||||||
|
* @param attrs LDAP attributes to return in search.
|
||||||
* @param filter The user to search for in the form of an LDAP filter. This filter must return
|
* @param filter The user to search for in the form of an LDAP filter. This filter must return
|
||||||
* exactly one user for the check to be successful.
|
* exactly one user for the check to be successful.
|
||||||
* @param bindpw The user password to bind as.
|
* @param bindpw The user password to bind as.
|
||||||
* @param binddn The DN of the user will be returned in this variable.
|
* @param binddn The DN of the user will be returned in this variable.
|
||||||
|
* @param retvals The values corresponding to the attributes requested in the attrs array.
|
||||||
* @tip The filter supplied will be searched for. If a single entry is returned, an attempt
|
* @tip The filter supplied will be searched for. If a single entry is returned, an attempt
|
||||||
* is made to bind as that user. If this bind succeeds, the user is not validated.
|
* is made to bind as that user. If this bind succeeds, the user is not validated.
|
||||||
* @deffunc int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
* @deffunc int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
||||||
* char *url, const char *basedn, int scope,
|
* char *url, const char *basedn, int scope, char **attrs,
|
||||||
* char *filter, char *bindpw, char **binddn)
|
* char *filter, char *bindpw, char **binddn, char ***retvals)
|
||||||
*/
|
*/
|
||||||
int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
||||||
const char *url, const char *basedn, int scope,
|
const char *url, const char *basedn, int scope, char **attrs,
|
||||||
const char *filter, const char *bindpw, const char **binddn);
|
const char *filter, const char *bindpw, const char **binddn, const char ***retvals);
|
||||||
|
|
||||||
/* from apr_ldap_cache.c */
|
/* from apr_ldap_cache.c */
|
||||||
|
|
||||||
|
@@ -68,6 +68,8 @@
|
|||||||
/* for getpid() */
|
/* for getpid() */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "http_config.h"
|
#include "http_config.h"
|
||||||
#include "http_core.h"
|
#include "http_core.h"
|
||||||
@@ -90,6 +92,7 @@ typedef struct {
|
|||||||
int port; /* Port of the LDAP server */
|
int port; /* Port of the LDAP server */
|
||||||
char *basedn; /* Base DN to do all searches from */
|
char *basedn; /* Base DN to do all searches from */
|
||||||
char *attribute; /* Attribute to search for */
|
char *attribute; /* Attribute to search for */
|
||||||
|
char **attributes; /* Array of all the attributes to return */
|
||||||
int scope; /* Scope of the search */
|
int scope; /* Scope of the search */
|
||||||
char *filter; /* Filter to further limit the search */
|
char *filter; /* Filter to further limit the search */
|
||||||
deref_options deref; /* how to handle alias dereferening */
|
deref_options deref; /* how to handle alias dereferening */
|
||||||
@@ -202,6 +205,7 @@ void mod_auth_ldap_build_filter(char *filtbuf,
|
|||||||
*/
|
*/
|
||||||
int mod_auth_ldap_check_user_id(request_rec *r)
|
int mod_auth_ldap_check_user_id(request_rec *r)
|
||||||
{
|
{
|
||||||
|
const char **vals = NULL;
|
||||||
char filtbuf[FILTER_LENGTH];
|
char filtbuf[FILTER_LENGTH];
|
||||||
mod_auth_ldap_config_t *sec =
|
mod_auth_ldap_config_t *sec =
|
||||||
(mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, &auth_ldap_module);
|
(mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, &auth_ldap_module);
|
||||||
@@ -254,7 +258,8 @@ int mod_auth_ldap_check_user_id(request_rec *r)
|
|||||||
mod_auth_ldap_build_filter(filtbuf, r, sec);
|
mod_auth_ldap_build_filter(filtbuf, r, sec);
|
||||||
|
|
||||||
/* do the user search */
|
/* do the user search */
|
||||||
result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope, filtbuf, sent_pw, &dn);
|
result = util_ldap_cache_checkuserid(r, ldc, sec->url, sec->basedn, sec->scope,
|
||||||
|
sec->attributes, filtbuf, sent_pw, &dn, &vals);
|
||||||
util_ldap_connection_close(ldc);
|
util_ldap_connection_close(ldc);
|
||||||
|
|
||||||
if (result != LDAP_SUCCESS) {
|
if (result != LDAP_SUCCESS) {
|
||||||
@@ -278,6 +283,24 @@ int mod_auth_ldap_check_user_id(request_rec *r)
|
|||||||
r->user = req->dn;
|
r->user = req->dn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add environment variables */
|
||||||
|
if (sec->attributes && vals) {
|
||||||
|
apr_table_t *e = r->subprocess_env;
|
||||||
|
int i = 0;
|
||||||
|
while (sec->attributes[i]) {
|
||||||
|
char *str = apr_pstrcat(r->pool, "AUTHENTICATE_", sec->attributes[i], NULL);
|
||||||
|
int j = 13;
|
||||||
|
while (str[j]) {
|
||||||
|
if (str[j] >= 'a' && str[j] <= 'z') {
|
||||||
|
str[j] = str[j] - ('a' - 'A');
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
apr_table_setn(e, str, vals[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r,
|
||||||
"[%d] auth_ldap authenticate: accepting %s", getpid(), r->user);
|
"[%d] auth_ldap authenticate: accepting %s", getpid(), r->user);
|
||||||
|
|
||||||
@@ -639,7 +662,17 @@ static const char *mod_auth_ldap_parse_url(cmd_parms *cmd,
|
|||||||
}
|
}
|
||||||
sec->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
|
sec->basedn = urld->lud_dn? apr_pstrdup(cmd->pool, urld->lud_dn) : "";
|
||||||
if (urld->lud_attrs && urld->lud_attrs[0]) {
|
if (urld->lud_attrs && urld->lud_attrs[0]) {
|
||||||
sec->attribute = apr_pstrdup(cmd->pool, urld->lud_attrs[0]);
|
int i = 1;
|
||||||
|
while (urld->lud_attrs[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
sec->attributes = apr_pcalloc(cmd->pool, sizeof(char *) * (i+1));
|
||||||
|
i = 0;
|
||||||
|
while (urld->lud_attrs[i]) {
|
||||||
|
sec->attributes[i] = apr_pstrdup(cmd->pool, urld->lud_attrs[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
sec->attribute = sec->attributes[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sec->attribute = "uid";
|
sec->attribute = "uid";
|
||||||
|
@@ -720,9 +720,11 @@ start_over:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
||||||
const char *url, const char *basedn, int scope,
|
const char *url, const char *basedn, int scope, char **attrs,
|
||||||
const char *filter, const char *bindpw, const char **binddn)
|
const char *filter, const char *bindpw, const char **binddn,
|
||||||
|
const char ***retvals)
|
||||||
{
|
{
|
||||||
|
const char **vals = NULL;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
LDAPMessage *res, *entry;
|
LDAPMessage *res, *entry;
|
||||||
char *dn;
|
char *dn;
|
||||||
@@ -738,7 +740,6 @@ int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
(util_ldap_state_t *)ap_get_module_config(r->server->module_config,
|
(util_ldap_state_t *)ap_get_module_config(r->server->module_config,
|
||||||
&ldap_module);
|
&ldap_module);
|
||||||
|
|
||||||
|
|
||||||
/* read lock this function */
|
/* read lock this function */
|
||||||
if (!util_ldap_cache_lock) {
|
if (!util_ldap_cache_lock) {
|
||||||
apr_lock_create(&util_ldap_cache_lock, APR_READWRITE, APR_INTRAPROCESS, NULL, st->pool);
|
apr_lock_create(&util_ldap_cache_lock, APR_READWRITE, APR_INTRAPROCESS, NULL, st->pool);
|
||||||
@@ -776,6 +777,7 @@ int util_ldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,
|
|||||||
else {
|
else {
|
||||||
/* ...and entry is valid */
|
/* ...and entry is valid */
|
||||||
*binddn = search_nodep->dn;
|
*binddn = search_nodep->dn;
|
||||||
|
*retvals = search_nodep->vals;
|
||||||
apr_lock_release(util_ldap_cache_lock);
|
apr_lock_release(util_ldap_cache_lock);
|
||||||
ldc->reason = "Authentication successful (cached)";
|
ldc->reason = "Authentication successful (cached)";
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
@@ -803,7 +805,7 @@ start_over:
|
|||||||
/* try do the search */
|
/* try do the search */
|
||||||
if ((result = ldap_search_ext_s(ldc->ldap,
|
if ((result = ldap_search_ext_s(ldc->ldap,
|
||||||
basedn, scope,
|
basedn, scope,
|
||||||
filter, NULL, 1,
|
filter, attrs, 0,
|
||||||
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) {
|
NULL, NULL, NULL, -1, &res)) == LDAP_SERVER_DOWN) {
|
||||||
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
ldc->reason = "ldap_search_ext_s() for user failed with server down";
|
||||||
goto start_over;
|
goto start_over;
|
||||||
@@ -864,7 +866,29 @@ start_over:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ldap_msgfree(res);
|
/*
|
||||||
|
* Get values for the provided attributes.
|
||||||
|
*/
|
||||||
|
if (attrs) {
|
||||||
|
int k = 0;
|
||||||
|
int i = 0;
|
||||||
|
while (attrs[k++]);
|
||||||
|
vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));
|
||||||
|
while (attrs[i]) {
|
||||||
|
char **values;
|
||||||
|
int j = 0;
|
||||||
|
char *str = NULL;
|
||||||
|
/* get values */
|
||||||
|
values = ldap_get_values(ldc->ldap, entry, attrs[i]);
|
||||||
|
while (values && values[j]) {
|
||||||
|
str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL) : apr_pstrdup(r->pool, values[j]);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
vals[i] = str;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
*retvals = vals;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the new username to the search cache.
|
* Add the new username to the search cache.
|
||||||
@@ -874,7 +898,9 @@ start_over:
|
|||||||
the_search_node.dn = *binddn;
|
the_search_node.dn = *binddn;
|
||||||
the_search_node.bindpw = bindpw;
|
the_search_node.bindpw = bindpw;
|
||||||
the_search_node.lastbind = apr_time_now();
|
the_search_node.lastbind = apr_time_now();
|
||||||
|
the_search_node.vals = vals;
|
||||||
util_ald_cache_insert(curl->search_cache, &the_search_node);
|
util_ald_cache_insert(curl->search_cache, &the_search_node);
|
||||||
|
ldap_msgfree(res);
|
||||||
apr_lock_release(util_ldap_cache_lock);
|
apr_lock_release(util_ldap_cache_lock);
|
||||||
|
|
||||||
ldc->reason = "Authentication successful";
|
ldc->reason = "Authentication successful";
|
||||||
|
@@ -127,16 +127,52 @@ void *util_ldap_search_node_copy(void *c)
|
|||||||
{
|
{
|
||||||
util_search_node_t *node = (util_search_node_t *)c;
|
util_search_node_t *node = (util_search_node_t *)c;
|
||||||
util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t));
|
util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t));
|
||||||
newnode->username = util_ald_strdup(node->username);
|
|
||||||
newnode->dn = util_ald_strdup(node->dn);
|
/* safety check */
|
||||||
newnode->bindpw = util_ald_strdup(node->bindpw);
|
if (newnode) {
|
||||||
newnode->lastbind = node->lastbind;
|
|
||||||
|
/* copy vals */
|
||||||
|
if (node->vals) {
|
||||||
|
int k = 0;
|
||||||
|
int i = 0;
|
||||||
|
while (node->vals[k++]);
|
||||||
|
if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) {
|
||||||
|
util_ldap_search_node_free(newnode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while (node->vals[i]) {
|
||||||
|
if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) {
|
||||||
|
util_ldap_search_node_free(newnode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newnode->vals = NULL;
|
||||||
|
}
|
||||||
|
if (!(newnode->username = util_ald_strdup(node->username)) ||
|
||||||
|
!(newnode->dn = util_ald_strdup(node->dn)) ||
|
||||||
|
!(newnode->bindpw = util_ald_strdup(node->bindpw)) ) {
|
||||||
|
util_ldap_search_node_free(newnode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
newnode->lastbind = node->lastbind;
|
||||||
|
|
||||||
|
}
|
||||||
return (void *)newnode;
|
return (void *)newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void util_ldap_search_node_free(void *n)
|
void util_ldap_search_node_free(void *n)
|
||||||
{
|
{
|
||||||
|
int i = 0;
|
||||||
util_search_node_t *node = (util_search_node_t *)n;
|
util_search_node_t *node = (util_search_node_t *)n;
|
||||||
|
if (node->vals) {
|
||||||
|
while (node->vals[i]) {
|
||||||
|
util_ald_free(node->vals[i++]);
|
||||||
|
}
|
||||||
|
util_ald_free(node->vals);
|
||||||
|
}
|
||||||
util_ald_free(node->username);
|
util_ald_free(node->username);
|
||||||
util_ald_free(node->dn);
|
util_ald_free(node->dn);
|
||||||
util_ald_free(node->bindpw);
|
util_ald_free(node->bindpw);
|
||||||
|
@@ -139,9 +139,10 @@ typedef struct util_url_node_t {
|
|||||||
typedef struct util_search_node_t {
|
typedef struct util_search_node_t {
|
||||||
const char *username; /* Cache key */
|
const char *username; /* Cache key */
|
||||||
const char *dn; /* DN returned from search */
|
const char *dn; /* DN returned from search */
|
||||||
const char *bindpw; /* The most recently used bind password;
|
const char *bindpw; /* The most recently used bind password;
|
||||||
NULL if the bind failed */
|
NULL if the bind failed */
|
||||||
apr_time_t lastbind; /* Time of last successful bind */
|
apr_time_t lastbind; /* Time of last successful bind */
|
||||||
|
const char **vals; /* Values of queried attributes */
|
||||||
} util_search_node_t;
|
} util_search_node_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -116,12 +116,15 @@ void util_ald_free(const void *ptr)
|
|||||||
{
|
{
|
||||||
#if APR_HAS_SHARED_MEMORY
|
#if APR_HAS_SHARED_MEMORY
|
||||||
if (util_ldap_shm) {
|
if (util_ldap_shm) {
|
||||||
apr_shm_free(util_ldap_shm, (void *)ptr);
|
if (ptr)
|
||||||
|
apr_shm_free(util_ldap_shm, (void *)ptr);
|
||||||
} else {
|
} else {
|
||||||
free((void *)ptr);
|
if (ptr)
|
||||||
|
free((void *)ptr);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
free((void *)ptr);
|
if (ptr)
|
||||||
|
free((void *)ptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,12 +132,12 @@ void *util_ald_alloc(int size)
|
|||||||
{
|
{
|
||||||
#if APR_HAS_SHARED_MEMORY
|
#if APR_HAS_SHARED_MEMORY
|
||||||
if (util_ldap_shm) {
|
if (util_ldap_shm) {
|
||||||
return (void *)apr_shm_malloc(util_ldap_shm, size);
|
return (void *)apr_shm_calloc(util_ldap_shm, size);
|
||||||
} else {
|
} else {
|
||||||
return (void *)malloc(size);
|
return (void *)calloc(sizeof(char), size);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return (void *)malloc(size);
|
return (void *)calloc(size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user