View | Details | Raw Unified | Return to bug 58025
Collapse All | Expand All

(-)/tmp/httpd-trunk/modules/aaa/mod_authz_dbd.c (-10 / +229 lines)
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,

Return to bug 58025