Lines 109-115
Link Here
|
109 |
{NULL} |
109 |
{NULL} |
110 |
}; |
110 |
}; |
111 |
|
111 |
|
|
|
112 |
static int evaluate_query_parameters(request_rec *r, |
113 |
const apr_array_header_t *parsed_require_args, |
114 |
const void **query_parameters) |
115 |
{ |
116 |
int i; |
117 |
apr_array_header_t *qp; |
118 |
|
119 |
const ap_expr_info_t *expr = NULL; |
120 |
const char *parameter; |
121 |
|
122 |
const char *err = NULL; |
123 |
|
124 |
/* evaluate the query parameters in parsed_require_args */ |
125 |
qp = apr_array_make(r->pool, |
126 |
parsed_require_args->nelts, |
127 |
sizeof (char *)); |
128 |
|
129 |
for (i = 0; i < parsed_require_args->nelts; i++) { |
130 |
|
131 |
expr = ((const ap_expr_info_t **)parsed_require_args->elts)[i]; |
132 |
parameter = ap_expr_str_exec(r, expr, &err); |
133 |
|
134 |
if (err) { |
135 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
136 |
"authz_dbd in evaluate query_parameters: Can't " |
137 |
"evaluate require expression: %s", err); |
138 |
return HTTP_INTERNAL_SERVER_ERROR; |
139 |
} |
140 |
|
141 |
*(const char **)apr_array_push(qp) = parameter; |
142 |
} |
143 |
|
144 |
*query_parameters = (void *)qp; |
145 |
|
146 |
return OK; |
147 |
} |
148 |
|
112 |
static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, |
149 |
static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, |
|
|
150 |
const void *parsed_require_args, |
113 |
const char *action) |
151 |
const char *action) |
114 |
{ |
152 |
{ |
115 |
int rv; |
153 |
int rv; |
Lines 120-131
Link Here
|
120 |
apr_dbd_prepared_t *query; |
158 |
apr_dbd_prepared_t *query; |
121 |
apr_dbd_results_t *res = NULL; |
159 |
apr_dbd_results_t *res = NULL; |
122 |
apr_dbd_row_t *row = NULL; |
160 |
apr_dbd_row_t *row = NULL; |
|
|
161 |
apr_array_header_t *query_parameters; |
123 |
|
162 |
|
124 |
if (cfg->query == NULL) { |
163 |
if (cfg->query == NULL) { |
125 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642) |
164 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01642) |
126 |
"No query configured for %s!", action); |
165 |
"No query configured for %s!", action); |
127 |
return HTTP_INTERNAL_SERVER_ERROR; |
166 |
return HTTP_INTERNAL_SERVER_ERROR; |
128 |
} |
167 |
} |
|
|
168 |
if (dbd == NULL) { |
169 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
170 |
"No db handle available for %s! Check your database access", action); |
171 |
return HTTP_INTERNAL_SERVER_ERROR; |
172 |
} |
129 |
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
173 |
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
130 |
if (query == NULL) { |
174 |
if (query == NULL) { |
131 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643) |
175 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643) |
Lines 133-140
Link Here
|
133 |
return HTTP_INTERNAL_SERVER_ERROR; |
177 |
return HTTP_INTERNAL_SERVER_ERROR; |
134 |
} |
178 |
} |
135 |
|
179 |
|
136 |
rv = apr_dbd_pvquery(dbd->driver, r->pool, dbd->handle, &nrows, |
180 |
rv = evaluate_query_parameters(r, parsed_require_args, (void *)&query_parameters); |
137 |
query, r->user, NULL); |
181 |
if (rv != OK) { |
|
|
182 |
return HTTP_INTERNAL_SERVER_ERROR; |
183 |
} |
184 |
|
185 |
rv = apr_dbd_pquery(dbd->driver, r->pool, dbd->handle, &nrows, |
186 |
query, |
187 |
query_parameters->nelts, |
188 |
(const char **)query_parameters->elts); |
138 |
if (rv == 0) { |
189 |
if (rv == 0) { |
139 |
if (nrows != 1) { |
190 |
if (nrows != 1) { |
140 |
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644) |
191 |
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01644) |
Lines 194-199
Link Here
|
194 |
return OK; |
245 |
return OK; |
195 |
} |
246 |
} |
196 |
|
247 |
|
|
|
248 |
static int authz_dbd_query(request_rec *r, authz_dbd_cfg *cfg, |
249 |
const apr_array_header_t *query_parameters, |
250 |
apr_array_header_t *query_result_rows) |
251 |
{ |
252 |
/* SELECT group FROM authz WHERE col = %s, col = %s, ... */ |
253 |
int rv; |
254 |
const char *message; |
255 |
ap_dbd_t *dbd = dbd_handle(r); |
256 |
apr_dbd_prepared_t *query; |
257 |
apr_dbd_results_t *res = NULL; |
258 |
apr_dbd_row_t *row = NULL; |
259 |
const char **query_result_row; |
260 |
|
261 |
if (cfg->query == NULL) { |
262 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
263 |
"No query configured for dbd-query!"); |
264 |
return HTTP_INTERNAL_SERVER_ERROR; |
265 |
} |
266 |
if (dbd == NULL) { |
267 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
268 |
"No db handle available for dbd-query! Check your database access"); |
269 |
return HTTP_INTERNAL_SERVER_ERROR; |
270 |
} |
271 |
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
272 |
if (query == NULL) { |
273 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
274 |
"Error retrieving query for dbd-query!"); |
275 |
return HTTP_INTERNAL_SERVER_ERROR; |
276 |
} |
277 |
|
278 |
rv = apr_dbd_pselect(dbd->driver, r->pool, dbd->handle, &res, |
279 |
query, 0, |
280 |
query_parameters->nelts, |
281 |
(const char **)query_parameters->elts); |
282 |
|
283 |
if (rv == 0) { |
284 |
for (rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1); |
285 |
rv != -1; |
286 |
rv = apr_dbd_get_row(dbd->driver, r->pool, res, &row, -1)) { |
287 |
if (rv == 0) { |
288 |
query_result_row = apr_array_push(query_result_rows); |
289 |
*query_result_row = apr_dbd_get_entry(dbd->driver, row, 0); |
290 |
} |
291 |
else { |
292 |
message = apr_dbd_error(dbd->driver, dbd->handle, rv); |
293 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
294 |
"authz_dbd dbd_query in get_row; query for user=%s [%s]", |
295 |
r->user, message?message:noerror); |
296 |
return HTTP_INTERNAL_SERVER_ERROR; |
297 |
} |
298 |
} |
299 |
} |
300 |
else { |
301 |
message = apr_dbd_error(dbd->driver, dbd->handle, rv); |
302 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
303 |
"authz_dbd, in dbd_query query for %s [%s]", |
304 |
r->user, message?message:noerror); |
305 |
return HTTP_INTERNAL_SERVER_ERROR; |
306 |
} |
307 |
return OK; |
308 |
} |
309 |
|
197 |
static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg, |
310 |
static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg, |
198 |
apr_array_header_t *groups) |
311 |
apr_array_header_t *groups) |
199 |
{ |
312 |
{ |
Lines 211-216
Link Here
|
211 |
"No query configured for dbd-group!"); |
324 |
"No query configured for dbd-group!"); |
212 |
return HTTP_INTERNAL_SERVER_ERROR; |
325 |
return HTTP_INTERNAL_SERVER_ERROR; |
213 |
} |
326 |
} |
|
|
327 |
if (dbd == NULL) { |
328 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() |
329 |
"No db handle available for dbd-group! Check your database access"); |
330 |
return HTTP_INTERNAL_SERVER_ERROR; |
331 |
} |
214 |
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
332 |
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
215 |
if (query == NULL) { |
333 |
if (query == NULL) { |
216 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650) |
334 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650) |
Lines 246-251
Link Here
|
246 |
return OK; |
364 |
return OK; |
247 |
} |
365 |
} |
248 |
|
366 |
|
|
|
367 |
static authz_status dbdquery_check_authorization(request_rec *r, |
368 |
const char *require_args, |
369 |
const void *parsed_require_args) |
370 |
{ |
371 |
int rv; |
372 |
|
373 |
const apr_array_header_t *parsed_require_args_array = parsed_require_args; |
374 |
apr_array_header_t *query_parameters; |
375 |
apr_array_header_t *query_result_rows = NULL; |
376 |
|
377 |
authz_dbd_cfg *cfg = ap_get_module_config(r->per_dir_config, |
378 |
&authz_dbd_module); |
379 |
|
380 |
if (!r->user) { |
381 |
return AUTHZ_DENIED_NO_USER; |
382 |
} |
383 |
|
384 |
rv = evaluate_query_parameters(r, parsed_require_args, (void *)&query_parameters); |
385 |
if (rv != OK) { |
386 |
return HTTP_INTERNAL_SERVER_ERROR; |
387 |
} |
388 |
|
389 |
query_result_rows = apr_array_make(r->pool, 4, sizeof(const char*)); |
390 |
rv = authz_dbd_query(r, cfg, query_parameters, query_result_rows); |
391 |
if (rv != OK) { |
392 |
return HTTP_INTERNAL_SERVER_ERROR; |
393 |
} |
394 |
|
395 |
/* if we get at least one row result, consider the request is granted */ |
396 |
if (query_result_rows->nelts) { |
397 |
return AUTHZ_GRANTED; |
398 |
} |
399 |
|
400 |
return AUTHZ_DENIED; |
401 |
} |
402 |
|
249 |
static authz_status dbdgroup_check_authorization(request_rec *r, |
403 |
static authz_status dbdgroup_check_authorization(request_rec *r, |
250 |
const char *require_args, |
404 |
const char *require_args, |
251 |
const void *parsed_require_args) |
405 |
const void *parsed_require_args) |
Lines 305-312
Link Here
|
305 |
if (!r->user) { |
459 |
if (!r->user) { |
306 |
return AUTHZ_DENIED_NO_USER; |
460 |
return AUTHZ_DENIED_NO_USER; |
307 |
} |
461 |
} |
308 |
|
462 |
|
309 |
return (authz_dbd_login(r, cfg, "login") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED); |
463 |
return (authz_dbd_login(r, cfg, parsed_require_args, "login") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED); |
310 |
} |
464 |
} |
311 |
|
465 |
|
312 |
static authz_status dbdlogout_check_authorization(request_rec *r, |
466 |
static authz_status dbdlogout_check_authorization(request_rec *r, |
Lines 320-334
Link Here
|
320 |
return AUTHZ_DENIED_NO_USER; |
474 |
return AUTHZ_DENIED_NO_USER; |
321 |
} |
475 |
} |
322 |
|
476 |
|
323 |
return (authz_dbd_login(r, cfg, "logout") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED); |
477 |
return (authz_dbd_login(r, cfg, parsed_require_args, "logout") == OK ? AUTHZ_GRANTED : AUTHZ_DENIED); |
324 |
} |
478 |
} |
325 |
|
479 |
|
326 |
static const char *dbd_parse_config(cmd_parms *cmd, const char *require_line, |
480 |
static const char *dbd_parse_config_query_parameters(cmd_parms *cmd, |
327 |
const void **parsed_require_line) |
481 |
const char *require_line, |
|
|
482 |
const void **parsed_require_line) |
328 |
{ |
483 |
{ |
329 |
const char *expr_err = NULL; |
484 |
const char *expr_err = NULL; |
330 |
ap_expr_info_t *expr; |
485 |
ap_expr_info_t *expr; |
|
|
486 |
apr_array_header_t *expr_array = NULL; |
487 |
|
488 |
const char *t; |
489 |
char *w; |
490 |
|
491 |
/* parse each element of the require line and store it in an |
492 |
individual table entry. We will evaluate them in that order |
493 |
when passing the parameters to the db query */ |
494 |
t = require_line; |
495 |
while ((w = ap_getword_white(cmd->pool, &t)) && w[0]) { |
496 |
|
497 |
expr = ap_expr_parse_cmd(cmd, w, AP_EXPR_FLAG_STRING_RESULT, |
498 |
&expr_err, NULL); |
499 |
|
500 |
if (expr_err) |
501 |
return apr_pstrcat(cmd->temp_pool, |
502 |
"Cannot parse expression in require line: ", |
503 |
expr_err, NULL); |
504 |
|
505 |
if (expr_array == NULL) { |
506 |
expr_array = apr_array_make(cmd->pool, 1, |
507 |
sizeof(const ap_expr_info_t *)); |
508 |
} |
509 |
*(const ap_expr_info_t **)apr_array_push(expr_array) = expr; |
510 |
} |
511 |
|
512 |
*parsed_require_line = expr_array; |
513 |
|
514 |
return NULL; |
515 |
} |
331 |
|
516 |
|
|
|
517 |
static const char *dbd_parse_config_session(cmd_parms *cmd, |
518 |
const char *require_line, |
519 |
const void **parsed_require_line) |
520 |
{ |
521 |
const char *t; |
522 |
|
523 |
/* to preserve backwards compatibility, if the require line has no |
524 |
arguments, use REMOTE_USER by default. */ |
525 |
if (require_line[0] == '\0') { |
526 |
t = apr_pstrdup (cmd->pool, "%{REMOTE_USER}"); |
527 |
} |
528 |
else { |
529 |
t = require_line; |
530 |
} |
531 |
|
532 |
return dbd_parse_config_query_parameters (cmd, t, parsed_require_line); |
533 |
} |
534 |
|
535 |
static const char *dbd_parse_config_groups(cmd_parms *cmd, const char *require_line, |
536 |
const void **parsed_require_line) |
537 |
{ |
538 |
const char *expr_err = NULL; |
539 |
ap_expr_info_t *expr; |
540 |
|
332 |
expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT, |
541 |
expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT, |
333 |
&expr_err, NULL); |
542 |
&expr_err, NULL); |
334 |
|
543 |
|
Lines 342-368
Link Here
|
342 |
return NULL; |
551 |
return NULL; |
343 |
} |
552 |
} |
344 |
|
553 |
|
|
|
554 |
static const authz_provider authz_dbdquery_provider = |
555 |
{ |
556 |
&dbdquery_check_authorization, |
557 |
&dbd_parse_config_query_parameters, |
558 |
}; |
559 |
|
345 |
static const authz_provider authz_dbdgroup_provider = |
560 |
static const authz_provider authz_dbdgroup_provider = |
346 |
{ |
561 |
{ |
347 |
&dbdgroup_check_authorization, |
562 |
&dbdgroup_check_authorization, |
348 |
&dbd_parse_config, |
563 |
&dbd_parse_config_groups, |
349 |
}; |
564 |
}; |
350 |
|
565 |
|
351 |
static const authz_provider authz_dbdlogin_provider = |
566 |
static const authz_provider authz_dbdlogin_provider = |
352 |
{ |
567 |
{ |
353 |
&dbdlogin_check_authorization, |
568 |
&dbdlogin_check_authorization, |
354 |
NULL, |
569 |
dbd_parse_config_session, |
355 |
}; |
570 |
}; |
356 |
|
571 |
|
357 |
|
572 |
|
358 |
static const authz_provider authz_dbdlogout_provider = |
573 |
static const authz_provider authz_dbdlogout_provider = |
359 |
{ |
574 |
{ |
360 |
&dbdlogout_check_authorization, |
575 |
&dbdlogout_check_authorization, |
361 |
NULL, |
576 |
dbd_parse_config_session, |
362 |
}; |
577 |
}; |
363 |
|
578 |
|
364 |
static void authz_dbd_hooks(apr_pool_t *p) |
579 |
static void authz_dbd_hooks(apr_pool_t *p) |
365 |
{ |
580 |
{ |
|
|
581 |
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-query", |
582 |
AUTHZ_PROVIDER_VERSION, |
583 |
&authz_dbdquery_provider, |
584 |
AP_AUTH_INTERNAL_PER_CONF); |
366 |
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-group", |
585 |
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbd-group", |
367 |
AUTHZ_PROVIDER_VERSION, |
586 |
AUTHZ_PROVIDER_VERSION, |
368 |
&authz_dbdgroup_provider, |
587 |
&authz_dbdgroup_provider, |