|
Lines 151-156
typedef struct {
Link Here
|
| 151 |
const char *auth_pg_port; |
151 |
const char *auth_pg_port; |
| 152 |
const char *auth_pg_options; |
152 |
const char *auth_pg_options; |
| 153 |
const char *auth_pg_user; |
153 |
const char *auth_pg_user; |
|
|
154 |
const char *auth_pg_charset; |
| 154 |
const char *auth_pg_pwd; |
155 |
const char *auth_pg_pwd; |
| 155 |
const char *auth_pg_pwd_table; |
156 |
const char *auth_pg_pwd_table; |
| 156 |
const char *auth_pg_uname_field; |
157 |
const char *auth_pg_uname_field; |
|
Lines 181-186
typedef struct {
Link Here
|
| 181 |
|
182 |
|
| 182 |
} pg_auth_config_rec; |
183 |
} pg_auth_config_rec; |
| 183 |
|
184 |
|
|
|
185 |
static PGconn *pg_conn; |
| 186 |
|
| 184 |
static apr_pool_t *auth_pgsql_pool = NULL; |
187 |
static apr_pool_t *auth_pgsql_pool = NULL; |
| 185 |
static apr_pool_t *auth_pgsql_pool_base64 = NULL; |
188 |
static apr_pool_t *auth_pgsql_pool_base64 = NULL; |
| 186 |
|
189 |
|
|
Lines 220-225
static void *create_pg_auth_dir_config(a
Link Here
|
| 220 |
new_rec->auth_pg_port = NULL; |
223 |
new_rec->auth_pg_port = NULL; |
| 221 |
new_rec->auth_pg_options = NULL; |
224 |
new_rec->auth_pg_options = NULL; |
| 222 |
new_rec->auth_pg_user = NULL; |
225 |
new_rec->auth_pg_user = NULL; |
|
|
226 |
new_rec->auth_pg_charset = NULL; |
| 223 |
new_rec->auth_pg_pwd = NULL; |
227 |
new_rec->auth_pg_pwd = NULL; |
| 224 |
new_rec->auth_pg_pwd_table = NULL; |
228 |
new_rec->auth_pg_pwd_table = NULL; |
| 225 |
new_rec->auth_pg_uname_field = NULL; |
229 |
new_rec->auth_pg_uname_field = NULL; |
|
Lines 324-329
static const command_rec pg_auth_cmds[]
Link Here
|
| 324 |
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_user), |
328 |
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_user), |
| 325 |
OR_AUTHCFG, |
329 |
OR_AUTHCFG, |
| 326 |
"user name connect as"), |
330 |
"user name connect as"), |
|
|
331 |
AP_INIT_TAKE1("Auth_PG_charset", ap_set_string_slot, |
| 332 |
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_charset), |
| 333 |
OR_AUTHCFG, |
| 334 |
"charset to use for connection"), |
| 327 |
AP_INIT_TAKE1("Auth_PG_pwd", ap_set_string_slot, |
335 |
AP_INIT_TAKE1("Auth_PG_pwd", ap_set_string_slot, |
| 328 |
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_pwd), |
336 |
(void *) APR_OFFSETOF(pg_auth_config_rec, auth_pg_pwd), |
| 329 |
OR_AUTHCFG, |
337 |
OR_AUTHCFG, |
|
Lines 462-514
static char *auth_pg_base64(char *pw)
Link Here
|
| 462 |
} |
470 |
} |
| 463 |
|
471 |
|
| 464 |
|
472 |
|
|
|
473 |
PGconn *pg_connect(pg_auth_config_rec *sec) |
| 474 |
{ |
| 475 |
PGconn *conn; |
| 465 |
|
476 |
|
| 466 |
/* Got from POstgreSQL 7.2 */ |
477 |
conn = PQsetdbLogin(sec->auth_pg_host, sec->auth_pg_port, |
| 467 |
/* --------------- |
478 |
sec->auth_pg_options, NULL, sec->auth_pg_database, |
| 468 |
* Escaping arbitrary strings to get valid SQL strings/identifiers. |
479 |
sec->auth_pg_user, sec->auth_pg_pwd); |
| 469 |
* |
480 |
if (PQstatus(conn) != CONNECTION_OK) { |
| 470 |
* Replaces "\\" with "\\\\" and "'" with "''". |
481 |
PQreset(conn); |
| 471 |
* length is the length of the buffer pointed to by |
482 |
apr_snprintf(pg_errstr, MAX_STRING_LEN, |
| 472 |
* from. The buffer at to must be at least 2*length + 1 characters |
483 |
"mod_auth_pgsql database connection error resetting %s", |
| 473 |
* long. A terminating NUL character is written. |
484 |
PQerrorMessage(conn)); |
| 474 |
* --------------- |
485 |
if (PQstatus(conn) != CONNECTION_OK) { |
| 475 |
*/ |
486 |
apr_snprintf(pg_errstr, MAX_STRING_LEN, |
|
|
487 |
"mod_auth_pgsql database connection error reset failed %s", |
| 488 |
PQerrorMessage(conn)); |
| 489 |
PQfinish(conn); |
| 490 |
return NULL; |
| 491 |
} |
| 492 |
} |
| 493 |
return conn; |
| 494 |
} |
| 476 |
|
495 |
|
| 477 |
static size_t pg_check_string(char *to, const char *from, size_t length) |
|
|
| 478 |
{ |
| 479 |
const char *source = from; |
| 480 |
char *target = to; |
| 481 |
unsigned int remaining = length; |
| 482 |
|
| 483 |
while (remaining > 0) { |
| 484 |
switch (*source) { |
| 485 |
case '\\': |
| 486 |
*target = '\\'; |
| 487 |
target++; |
| 488 |
*target = '\\'; |
| 489 |
/* target and remaining are updated below. */ |
| 490 |
break; |
| 491 |
|
496 |
|
| 492 |
case '\'': |
497 |
static size_t pg_check_string(char *to, const char *from, size_t length, request_rec * r, pg_auth_config_rec *sec) |
| 493 |
*target = '\''; |
498 |
{ |
| 494 |
target++; |
499 |
int error; |
| 495 |
*target = '\''; |
|
|
| 496 |
/* target and remaining are updated below. */ |
| 497 |
break; |
| 498 |
|
500 |
|
| 499 |
default: |
501 |
if (!pg_conn) { |
| 500 |
*target = *source; |
502 |
if (!(pg_conn = pg_connect(sec))) { |
| 501 |
/* target and remaining are updated below. */ |
503 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database"); |
|
|
504 |
ap_note_basic_auth_failure(r); |
| 505 |
return -1; |
| 502 |
} |
506 |
} |
| 503 |
source++; |
|
|
| 504 |
target++; |
| 505 |
remaining--; |
| 506 |
} |
507 |
} |
| 507 |
|
508 |
|
| 508 |
/* Write the terminating NUL character. */ |
509 |
PQescapeStringConn(pg_conn, to, from, length, &error); |
| 509 |
*target = '\0'; |
|
|
| 510 |
|
510 |
|
| 511 |
return target - to; |
511 |
if (error) { |
|
|
512 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot escape string"); |
| 513 |
ap_note_basic_auth_failure(r); |
| 514 |
return -1; |
| 515 |
} |
| 516 |
|
| 517 |
return 0; |
| 512 |
} |
518 |
} |
| 513 |
|
519 |
|
| 514 |
|
520 |
|
|
Lines 518-524
static size_t pg_check_string(char *to,
Link Here
|
| 518 |
char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec) |
524 |
char *do_pg_query(request_rec * r, char *query, pg_auth_config_rec * sec) |
| 519 |
{ |
525 |
{ |
| 520 |
PGresult *pg_result; |
526 |
PGresult *pg_result; |
| 521 |
PGconn *pg_conn; |
|
|
| 522 |
char *val; |
527 |
char *val; |
| 523 |
char *result = NULL; |
528 |
char *result = NULL; |
| 524 |
|
529 |
|
|
Lines 530-548
char *do_pg_query(request_rec * r, char
Link Here
|
| 530 |
sec->auth_pg_database); |
535 |
sec->auth_pg_database); |
| 531 |
#endif /* DEBUG_AUTH_PGSQL */ |
536 |
#endif /* DEBUG_AUTH_PGSQL */ |
| 532 |
|
537 |
|
| 533 |
pg_conn = PQsetdbLogin(sec->auth_pg_host, sec->auth_pg_port, |
538 |
if (!pg_conn) { |
| 534 |
sec->auth_pg_options, NULL, sec->auth_pg_database, |
539 |
if (!(pg_conn = pg_connect(sec))) { |
| 535 |
sec->auth_pg_user, sec->auth_pg_pwd); |
540 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database"); |
| 536 |
if (PQstatus(pg_conn) != CONNECTION_OK) { |
541 |
ap_note_basic_auth_failure(r); |
| 537 |
PQreset(pg_conn); |
|
|
| 538 |
apr_snprintf(pg_errstr, MAX_STRING_LEN, |
| 539 |
"mod_auth_pgsql database connection error resetting %s", |
| 540 |
PQerrorMessage(pg_conn)); |
| 541 |
if (PQstatus(pg_conn) != CONNECTION_OK) { |
| 542 |
apr_snprintf(pg_errstr, MAX_STRING_LEN, |
| 543 |
"mod_auth_pgsql database connection error reset failed %s", |
| 544 |
PQerrorMessage(pg_conn)); |
| 545 |
PQfinish(pg_conn); |
| 546 |
return NULL; |
542 |
return NULL; |
| 547 |
} |
543 |
} |
| 548 |
} |
544 |
} |
|
Lines 552-557
char *do_pg_query(request_rec * r, char
Link Here
|
| 552 |
query); |
548 |
query); |
| 553 |
#endif /* DEBUG_AUTH_PGSQL */ |
549 |
#endif /* DEBUG_AUTH_PGSQL */ |
| 554 |
|
550 |
|
|
|
551 |
if (sec->auth_pg_charset) { |
| 552 |
const char *check; |
| 553 |
|
| 554 |
PQsetClientEncoding(pg_conn, sec->auth_pg_charset); |
| 555 |
|
| 556 |
check = pg_encoding_to_char(PQclientEncoding(pg_conn)); |
| 557 |
|
| 558 |
if (!check || strcmp(sec->auth_pg_charset, check)) { |
| 559 |
apr_snprintf(pg_errstr, MAX_STRING_LEN, |
| 560 |
"mod_auth_pgsql database character set encoding %s"); |
| 561 |
PQfinish(pg_conn); |
| 562 |
return NULL; |
| 563 |
} |
| 564 |
} |
| 565 |
|
| 555 |
pg_result = PQexec(pg_conn, query); |
566 |
pg_result = PQexec(pg_conn, query); |
| 556 |
|
567 |
|
| 557 |
if (pg_result == NULL) { |
568 |
if (pg_result == NULL) { |
|
Lines 610-616
char *get_pg_pw(request_rec * r, char *u
Link Here
|
| 610 |
int n; |
621 |
int n; |
| 611 |
|
622 |
|
| 612 |
safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user)); |
623 |
safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user)); |
| 613 |
pg_check_string(safe_user, user, strlen(user)); |
624 |
pg_check_string(safe_user, user, strlen(user), r, sec); |
| 614 |
|
625 |
|
| 615 |
#ifdef DEBUG_AUTH_PGSQL |
626 |
#ifdef DEBUG_AUTH_PGSQL |
| 616 |
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
627 |
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, |
|
Lines 685-692
static char *get_pg_grp(request_rec * r,
Link Here
|
| 685 |
#endif /* DEBUG_AUTH_PGSQL */ |
696 |
#endif /* DEBUG_AUTH_PGSQL */ |
| 686 |
|
697 |
|
| 687 |
query[0] = '\0'; |
698 |
query[0] = '\0'; |
| 688 |
pg_check_string(safe_user, user, strlen(user)); |
699 |
pg_check_string(safe_user, user, strlen(user), r, sec); |
| 689 |
pg_check_string(safe_group, group, strlen(group)); |
700 |
pg_check_string(safe_group, group, strlen(group), r, sec); |
| 690 |
|
701 |
|
| 691 |
if ((!sec->auth_pg_grp_table) || |
702 |
if ((!sec->auth_pg_grp_table) || |
| 692 |
(!sec->auth_pg_grp_group_field) || (!sec->auth_pg_grp_user_field)) |
703 |
(!sec->auth_pg_grp_group_field) || (!sec->auth_pg_grp_user_field)) |
|
Lines 777-782
static int pg_authenticate_basic_user(re
Link Here
|
| 777 |
} |
788 |
} |
| 778 |
pg_errstr[0] = '\0'; |
789 |
pg_errstr[0] = '\0'; |
| 779 |
|
790 |
|
|
|
791 |
if (!pg_conn) { |
| 792 |
if (!(pg_conn = pg_connect(sec))) { |
| 793 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database"); |
| 794 |
ap_note_basic_auth_failure(r); |
| 795 |
return HTTP_UNAUTHORIZED; |
| 796 |
} |
| 797 |
} |
| 798 |
|
| 780 |
if (sec->auth_pg_cache_passwords |
799 |
if (sec->auth_pg_cache_passwords |
| 781 |
&& (!apr_is_empty_table(sec->cache_pass_table))) { |
800 |
&& (!apr_is_empty_table(sec->cache_pass_table))) { |
| 782 |
val = (char *) apr_table_get(sec->cache_pass_table, user); |
801 |
val = (char *) apr_table_get(sec->cache_pass_table, user); |
|
Lines 904-909
static int pg_check_auth(request_rec * r
Link Here
|
| 904 |
#endif /* DEBUG_AUTH_PGSQL */ |
923 |
#endif /* DEBUG_AUTH_PGSQL */ |
| 905 |
|
924 |
|
| 906 |
|
925 |
|
|
|
926 |
if (!pg_conn) { |
| 927 |
if (!(pg_conn = pg_connect(sec))) { |
| 928 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - cannot connect to database"); |
| 929 |
ap_note_basic_auth_failure(r); |
| 930 |
return HTTP_UNAUTHORIZED; |
| 931 |
} |
| 932 |
} |
| 907 |
|
933 |
|
| 908 |
/* if we cannot do it; leave it to some other guy |
934 |
/* if we cannot do it; leave it to some other guy |
| 909 |
*/ |
935 |
*/ |
|
Lines 1015-1023
pg_log_auth_user(request_rec * r, pg_aut
Link Here
|
| 1015 |
} |
1041 |
} |
| 1016 |
|
1042 |
|
| 1017 |
/* AUD: MAX_STRING_LEN probably isn't always correct */ |
1043 |
/* AUD: MAX_STRING_LEN probably isn't always correct */ |
| 1018 |
pg_check_string(safe_user, user, strlen(user)); |
1044 |
pg_check_string(safe_user, user, strlen(user), r, sec); |
| 1019 |
pg_check_string(safe_pw, sent_pw, strlen(sent_pw)); |
1045 |
pg_check_string(safe_pw, sent_pw, strlen(sent_pw), r, sec); |
| 1020 |
pg_check_string(safe_req, r->the_request, strlen(r->the_request)); |
1046 |
pg_check_string(safe_req, r->the_request, strlen(r->the_request), r, sec); |
| 1021 |
|
1047 |
|
| 1022 |
|
1048 |
|
| 1023 |
if (sec->auth_pg_lowercaseuid) { |
1049 |
if (sec->auth_pg_lowercaseuid) { |