Resolve server names only once during configuration

main
Jiri Hruska 12 years ago
parent 89f0f75592
commit a043544e2d
  1. 138
      ngx_http_auth_ldap_module.c

@ -47,17 +47,15 @@ typedef struct {
} ngx_http_auth_ldap_server_t; } ngx_http_auth_ldap_server_t;
typedef struct { typedef struct {
ngx_str_t realm; ngx_array_t *servers; /* array of ngx_http_auth_ldap_server_t */
ngx_array_t *servers; } ngx_http_auth_ldap_main_conf_t;
} ngx_http_auth_ldap_loc_conf_t;
typedef struct { typedef struct {
ngx_array_t *servers; /* array of ngx_http_auth_ldap_server_t */ ngx_str_t realm;
ngx_hash_t srv; ngx_array_t *servers; /* array of ngx_http_auth_ldap_server_t* */
} ngx_http_auth_ldap_conf_t; } ngx_http_auth_ldap_loc_conf_t;
static void * ngx_http_auth_ldap_create_conf(ngx_conf_t *cf); static void * ngx_http_auth_ldap_create_main_conf(ngx_conf_t *cf);
static char * ngx_http_auth_ldap_ldap_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char * ngx_http_auth_ldap_ldap_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char * ngx_http_auth_ldap_parse_url(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server); static char * ngx_http_auth_ldap_parse_url(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server);
static char * ngx_http_auth_ldap_parse_require(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server); static char * ngx_http_auth_ldap_parse_require(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server);
@ -70,9 +68,9 @@ static char * ngx_http_auth_ldap_merge_loc_conf(ngx_conf_t *, void *, void *);
static ngx_int_t ngx_http_auth_ldap_authenticate_against_server(ngx_http_request_t *r, ngx_http_auth_ldap_server_t *server, static ngx_int_t ngx_http_auth_ldap_authenticate_against_server(ngx_http_request_t *r, ngx_http_auth_ldap_server_t *server,
ngx_http_auth_ldap_loc_conf_t *conf); ngx_http_auth_ldap_loc_conf_t *conf);
static ngx_int_t ngx_http_auth_ldap_set_realm(ngx_http_request_t *r, ngx_str_t *realm); static ngx_int_t ngx_http_auth_ldap_set_realm(ngx_http_request_t *r, ngx_str_t *realm);
static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http_auth_ldap_loc_conf_t *conf, static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http_auth_ldap_loc_conf_t *conf);
ngx_http_auth_ldap_conf_t *mconf);
static char * ngx_http_auth_ldap(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char * ngx_http_auth_ldap(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char * ngx_http_auth_ldap_servers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static ngx_command_t ngx_http_auth_ldap_commands[] = { static ngx_command_t ngx_http_auth_ldap_commands[] = {
{ {
@ -94,9 +92,9 @@ static ngx_command_t ngx_http_auth_ldap_commands[] = {
{ {
ngx_string("auth_ldap_servers"), ngx_string("auth_ldap_servers"),
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_ANY, NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_ANY,
ngx_conf_set_str_array_slot, ngx_http_auth_ldap_servers,
NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_auth_ldap_loc_conf_t, servers), 0,
NULL NULL
}, },
ngx_null_command ngx_null_command
@ -105,7 +103,7 @@ static ngx_command_t ngx_http_auth_ldap_commands[] = {
static ngx_http_module_t ngx_http_auth_ldap_module_ctx = { static ngx_http_module_t ngx_http_auth_ldap_module_ctx = {
NULL, /* preconfiguration */ NULL, /* preconfiguration */
ngx_http_auth_ldap_init, /* postconfiguration */ ngx_http_auth_ldap_init, /* postconfiguration */
ngx_http_auth_ldap_create_conf, /* create main configuration */ ngx_http_auth_ldap_create_main_conf, /* create main configuration */
NULL, /* init main configuration */ NULL, /* init main configuration */
NULL, //ngx_http_auth_ldap_create_server_conf, /* create server configuration */ NULL, //ngx_http_auth_ldap_create_server_conf, /* create server configuration */
NULL, //ngx_http_auth_ldap_merge_server_conf, /* merge server configuration */ NULL, //ngx_http_auth_ldap_merge_server_conf, /* merge server configuration */
@ -135,11 +133,11 @@ ngx_module_t ngx_http_auth_ldap_module = {
static char * static char *
ngx_http_auth_ldap_ldap_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_http_auth_ldap_ldap_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ {
char *rv; char *rv;
ngx_str_t *value, name; ngx_str_t *value, name;
ngx_conf_t save; ngx_conf_t save;
ngx_http_auth_ldap_server_t server, *s; ngx_http_auth_ldap_server_t server, *s;
ngx_http_auth_ldap_conf_t *cnf = conf; ngx_http_auth_ldap_main_conf_t *cnf = conf;
value = cf->args->elts; value = cf->args->elts;
@ -189,7 +187,7 @@ ngx_http_auth_ldap_ldap_server(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
ngx_str_t *value; ngx_str_t *value;
ngx_http_auth_ldap_server_t *server; ngx_http_auth_ldap_server_t *server;
ngx_http_auth_ldap_conf_t *cnf = conf; ngx_http_auth_ldap_main_conf_t *cnf = conf;
// It should be safe to just use latest server from array // It should be safe to just use latest server from array
server = ((ngx_http_auth_ldap_server_t*)cnf->servers->elts + (cnf->servers->nelts - 1)); server = ((ngx_http_auth_ldap_server_t*)cnf->servers->elts + (cnf->servers->nelts - 1));
@ -246,6 +244,57 @@ ngx_http_auth_ldap(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
return NGX_CONF_OK; return NGX_CONF_OK;
} }
/**
* Parse auth_ldap_servers directive
*/
static char *
ngx_http_auth_ldap_servers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
ngx_http_auth_ldap_loc_conf_t *cnf;
ngx_http_auth_ldap_main_conf_t *mconf;
ngx_http_auth_ldap_server_t *server, *s, **target;
ngx_str_t *value;
ngx_uint_t i, j;
cnf = conf;
mconf = ngx_http_conf_get_module_main_conf(cf, ngx_http_auth_ldap_module);
for (i = 1; i < cf->args->nelts; i++) {
value = &((ngx_str_t *) cf->args->elts)[i];
server = NULL;
for (j = 0; j < mconf->servers->nelts; j++) {
s = &((ngx_http_auth_ldap_server_t *) mconf->servers->elts)[j];
if (s->alias.len == value->len && ngx_memcmp(s->alias.data, value->data, s->alias.len) == 0) {
server = s;
break;
}
}
if (server == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "LDAP server \"%V\" is not defined!", value);
return NGX_CONF_ERROR;
}
if (cnf->servers == NGX_CONF_UNSET_PTR) {
cnf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_http_auth_ldap_server_t *));
if (cnf->servers == NULL) {
return NGX_CONF_ERROR;
}
}
target = (ngx_http_auth_ldap_server_t **) ngx_array_push(cnf->servers);
if (target == NULL) {
return NGX_CONF_ERROR;
}
*target = server;
}
return NGX_CONF_OK;
}
/** /**
* Parse URL conf parameter * Parse URL conf parameter
*/ */
@ -391,11 +440,11 @@ ngx_http_auth_ldap_parse_satisfy(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *se
* Create main config which will store ldap_servers array * Create main config which will store ldap_servers array
*/ */
static void * static void *
ngx_http_auth_ldap_create_conf(ngx_conf_t *cf) ngx_http_auth_ldap_create_main_conf(ngx_conf_t *cf)
{ {
ngx_http_auth_ldap_conf_t *conf; ngx_http_auth_ldap_main_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_ldap_conf_t)); conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_ldap_main_conf_t));
if (conf == NULL) { if (conf == NULL) {
return NULL; return NULL;
} }
@ -442,39 +491,29 @@ static ngx_int_t ngx_http_auth_ldap_handler(ngx_http_request_t *r) {
ngx_http_auth_ldap_loc_conf_t *alcf; ngx_http_auth_ldap_loc_conf_t *alcf;
alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_ldap_module); alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_ldap_module);
if (alcf->realm.len == 0) { if (alcf->realm.len == 0) {
return NGX_DECLINED; return NGX_DECLINED;
} }
ngx_http_auth_ldap_conf_t *cnf;
cnf = ngx_http_get_module_main_conf(r, ngx_http_auth_ldap_module);
rc = ngx_http_auth_basic_user(r); rc = ngx_http_auth_basic_user(r);
if (rc == NGX_DECLINED) { if (rc == NGX_DECLINED) {
return ngx_http_auth_ldap_set_realm(r, &alcf->realm); return ngx_http_auth_ldap_set_realm(r, &alcf->realm);
} }
if (rc == NGX_ERROR) { if (rc == NGX_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
} }
return ngx_http_auth_ldap_authenticate(r, alcf, cnf); return ngx_http_auth_ldap_authenticate(r, alcf);
} }
/** /**
* Read user credentials from request, set LDAP parameters and call authentication against required servers * Read user credentials from request, set LDAP parameters and call authentication against required servers
*/ */
static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http_auth_ldap_loc_conf_t *conf, static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http_auth_ldap_loc_conf_t *conf) {
ngx_http_auth_ldap_conf_t *mconf) {
ngx_http_auth_ldap_server_t *server, *servers; ngx_http_auth_ldap_server_t *server;
servers = mconf->servers->elts;
int rc; int rc;
ngx_uint_t i, k; ngx_uint_t i;
ngx_str_t *alias;
int version = LDAP_VERSION3; int version = LDAP_VERSION3;
int reqcert = LDAP_OPT_X_TLS_ALLOW; int reqcert = LDAP_OPT_X_TLS_ALLOW;
@ -498,27 +537,12 @@ static ngx_int_t ngx_http_auth_ldap_authenticate(ngx_http_request_t *r, ngx_http
ldap_err2string(rc)); ldap_err2string(rc));
} }
// TODO: We might be using hash here, cause this loops is quite ugly, but it is simple and it works for (i = 0; i < conf->servers->nelts; i++) {
int found; server = ((ngx_http_auth_ldap_server_t **) conf->servers->elts)[i];
for (k = 0; k < conf->servers->nelts; k++) { pass = ngx_http_auth_ldap_authenticate_against_server(r, server, conf);
alias = ((ngx_str_t*)conf->servers->elts + k); if (pass == 1) {
found = 0; return NGX_OK;
for (i = 0; i < mconf->servers->nelts; i++) { } else if (pass == NGX_HTTP_INTERNAL_SERVER_ERROR) {
server = &servers[i];
if (server->alias.len == alias->len && ngx_strncmp(server->alias.data, alias->data, server->alias.len) == 0) {
found = 1;
pass = ngx_http_auth_ldap_authenticate_against_server(r, server, conf);
if (pass == 1) {
return NGX_OK;
} else if (pass == NGX_HTTP_INTERNAL_SERVER_ERROR) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
}
}
// If requested ldap server is not found, return 500 and write to log
if (found == 0) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "LDAP: Server \"%s\" is not defined!", alias->data);
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
} }
} }

Loading…
Cancel
Save