diff --git a/ngx_http_auth_ldap_module.c b/ngx_http_auth_ldap_module.c index 2f4e592..01913c9 100644 --- a/ngx_http_auth_ldap_module.c +++ b/ngx_http_auth_ldap_module.c @@ -203,6 +203,7 @@ static char * ngx_http_auth_ldap_parse_url(ngx_conf_t *cf, ngx_http_auth_ldap_se 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_satisfy(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server); static char * ngx_http_auth_ldap_parse_referral(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *server); +static ngx_str_t ngx_http_auth_ldap_escape_filter(ngx_http_request_t *r, ngx_str_t *in); static void * ngx_http_auth_ldap_create_main_conf(ngx_conf_t *cf); static char * ngx_http_auth_ldap_init_main_conf(ngx_conf_t *cf, void *parent); static void * ngx_http_auth_ldap_create_loc_conf(ngx_conf_t *); @@ -749,6 +750,33 @@ ngx_http_auth_ldap_parse_referral(ngx_conf_t *cf, ngx_http_auth_ldap_server_t *s return NGX_CONF_ERROR; } +/** + * Escape value for LDAP filters + */ +static ngx_str_t +ngx_http_auth_ldap_escape_filter(ngx_http_request_t *r, ngx_str_t *in) +{ + struct berval userbv, euserbv; + ngx_str_t out = ngx_null_string; + + if (in == NULL || in->len == 0) { + return out; + } + + userbv.bv_val = in->data; + userbv.bv_len = in->len; + if (ldap_bv2escaped_filter_value(&userbv, &euserbv) != 0) { + return out; + } + + out.len = euserbv.bv_len; + out.data = ngx_pcalloc(r->pool, out.len); + ngx_memcpy(out.data, euserbv.bv_val, out.len); + ber_memfree(euserbv.bv_val); + + return out; +} + /** * Create main config which will store ldap_servers array */ @@ -2062,6 +2090,7 @@ ngx_http_auth_ldap_search(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t *ctx) u_char *filter; char *attrs[2]; ngx_int_t rc; + ngx_str_t user; /* On the first call, initiate the LDAP search operation */ if (ctx->iteration == 0) { @@ -2070,13 +2099,14 @@ ngx_http_auth_ldap_search(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t *ctx) } ludpp = ctx->server->ludpp; + user = ngx_http_auth_ldap_escape_filter(r, &r->headers_in.user); filter = ngx_pcalloc( r->pool, (ludpp->lud_filter != NULL ? ngx_strlen(ludpp->lud_filter) : ngx_strlen("(objectClass=*)")) + - ngx_strlen("(&(=))") + ngx_strlen(ludpp->lud_attrs[0]) + r->headers_in.user.len + 1); + ngx_strlen("(&(=))") + ngx_strlen(ludpp->lud_attrs[0]) + user.len + 1); ngx_sprintf(filter, "(&%s(%s=%V))%Z", ludpp->lud_filter != NULL ? ludpp->lud_filter : "(objectClass=*)", - ludpp->lud_attrs[0], &r->headers_in.user); + ludpp->lud_attrs[0], &user); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http_auth_ldap: Search filter is \"%s\"", (const char *) filter); @@ -2156,7 +2186,7 @@ ngx_http_auth_ldap_check_group(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t * ngx_http_complex_value_t *values; ngx_int_t rc; u_char *filter; - char *user_val; + ngx_str_t user_val; char *attrs[2]; size_t for_filter; @@ -2227,17 +2257,9 @@ ngx_http_auth_ldap_check_group(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t * cn_gr = gr; if (ctx->server->group_attribute_dn == 1) { - user_val = ngx_pcalloc( - r->pool, - ctx->user_dn.len + 1); - ngx_memcpy(user_val, ctx->user_dn.data, ctx->user_dn.len); - user_val[ctx->user_dn.len] = '\0'; + user_val = ngx_http_auth_ldap_escape_filter(r, &ctx->user_dn); } else { - user_val = ngx_pcalloc( - r->pool, - r->headers_in.user.len + 1); - ngx_memcpy(user_val, r->headers_in.user.data, r->headers_in.user.len); - user_val[r->headers_in.user.len] = '\0'; + user_val = ngx_http_auth_ldap_escape_filter(r, &r->headers_in.user); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http_auth_ldap: Search user in group \"%V\"", &val); @@ -2246,11 +2268,11 @@ ngx_http_auth_ldap_check_group(ngx_http_request_t *r, ngx_http_auth_ldap_ctx_t * ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http_auth_ldap: group_attribute.data is \"%V\" so calling a failure here", ctx->server->group_attribute.data); rc = !LDAP_SUCCESS; } else { - for_filter = ngx_strlen(cn_gr) + ctx->server->group_attribute.len + ngx_strlen((const char *) user_val) + ngx_strlen("(&()(=))") + 1; + for_filter = ngx_strlen(cn_gr) + ctx->server->group_attribute.len + user_val.len + ngx_strlen("(&()(=))") + 1; filter = ngx_pcalloc( r->pool, for_filter); - ngx_sprintf(filter, "(&(%s)(%s=%s))", cn_gr, ctx->server->group_attribute.data, user_val); + ngx_sprintf(filter, "(&(%s)(%V=%V))", cn_gr, &ctx->server->group_attribute, &user_val); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http_auth_ldap: Search group filter is \"%s\"", (const char *) filter); attrs[0] = LDAP_NO_ATTRS; attrs[1] = NULL;