Package: libpam-pgsql Version: 0.5.2-9+b1 Severity: normal Tags: patch Hi,
the current libpam-pgsql library escapes the SQL options table name and various column names specified from within the pam configuration file or the pam_pgsql.conf. This prevents more complex SQL constructs within those parameters (such as nested SQL statements instead of a simple table or view name) without providing any real additional security, as the options' source should be trustworthy anyway (only system administrators can modify the PAM configuration or pam_pgsql.conf files). Nothing was changed regarding user provided input (such as the user name). The attached patch removes the unnecessary escaping and is tested on our systems. Please apply. Greetings, Fabian -- System Information: Debian Release: 4.0 APT prefers stable APT policy: (800, 'stable'), (3, 'testing'), (2, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.18-4-k7 Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Versions of packages libpam-pgsql depends on: ii libc6 2.3.6.ds1-13 GNU C Library: Shared libraries ii libmhash2 0.9.7-1 Library for cryptographic hashing ii libpam0g 0.79-4 Pluggable Authentication Modules l ii libpq4 8.1.8-1 PostgreSQL C client library libpam-pgsql recommends no packages. -- no debconf information
This patch removes unnecessary SQL escaping of the options table name and column names. This allows more complex SQL constructs within the aforementioned options when specified via the configuration file. -- Fabian Knittel <[EMAIL PROTECTED]> diff -urN pam-pgsql-0.5.2.orig/pam_pgsql.c pam-pgsql-0.5.2/pam_pgsql.c --- pam-pgsql-0.5.2.orig/pam_pgsql.c 2007-05-14 18:35:20.000000000 +0200 +++ pam-pgsql-0.5.2/pam_pgsql.c 2007-05-14 20:07:23.000000000 +0200 @@ -425,9 +425,6 @@ PGconn *conn; int rc, esclen; char *user_s; - char *pwd_column_s; - char *table_s; - char *user_column_s; #define CRYPT_LEN 13 if(!(conn = pg_connect(options))) @@ -439,28 +436,13 @@ sqlescape(user, user_s, strlen(user)); DBGLOG("%s", user_s); - esclen = strlen(options->pwd_column)*2+1; - pwd_column_s = malloc(esclen); - sqlescape(options->pwd_column, pwd_column_s, strlen(options->pwd_column)); - - esclen = strlen(options->table)*2+1; - table_s = malloc(esclen); - sqlescape(options->table, table_s, strlen(options->table)); - - esclen = strlen(options->user_column)*2+1; - user_column_s = malloc(esclen); - sqlescape(options->user_column, user_column_s, strlen(options->user_column)); - - DBGLOG("query: SELECT %s FROM %s WHERE %s='%s'", pwd_column_s, table_s, user_column_s, user_s); + DBGLOG("query: SELECT %s FROM %s WHERE %s='%s'", options->pwd_column, options->table, options->user_column, user_s); if(pg_exec(options, conn, &res, "SELECT %s FROM %s WHERE %s='%s'", - pwd_column_s, - table_s, - user_column_s, + options->pwd_column, + options->table, + options->user_column, user_s) != 0) { free(user_s); - free(table_s); - free(user_column_s); - free(pwd_column_s); PQclear(res); PQfinish(conn); @@ -518,9 +500,6 @@ PQclear(res); PQfinish(conn); free(user_s); - free(table_s); - free(user_column_s); - free(pwd_column_s); return rc; } @@ -570,10 +549,6 @@ struct module_options *options; const char *user; char *user_s; - char *table_s; - char *expired_column_s; - char *user_column_s; - char *newtok_column_s; int rc, esclen; PGconn *conn; PGresult *res; @@ -606,38 +581,17 @@ sqlescape(user, user_s, strlen(user)); - esclen = strlen(options->expired_column)*2+1; - expired_column_s = malloc(esclen); - sqlescape(options->expired_column, expired_column_s, strlen(options->expired_column)); - - esclen = strlen(options->table)*2+1; - table_s = malloc(esclen); - sqlescape(options->table, table_s, strlen(options->table)); - - esclen = strlen(options->user_column)*2+1; - user_column_s = malloc(esclen); - sqlescape(options->user_column, user_column_s, strlen(options->user_column)); - - esclen = strlen(options->newtok_column)*2+1; - newtok_column_s = malloc(esclen); - sqlescape(options->newtok_column, newtok_column_s, strlen(options->newtok_column)); - - /* if account has expired then expired_column = '1' or 'y' */ if(options->expired_column) { - DBGLOG("query: SELECT 1 FROM %s WHERE %s='%s' AND %s='y' OR %s='1'", table_s, user_column_s, user_s, expired_column_s, expired_column_s); + DBGLOG("query: SELECT 1 FROM %s WHERE %s='%s' AND %s='y' OR %s='1'", options->table, options->user_column, user_s, options->expired_column, options->expired_column); if(pg_exec(options, conn, &res, "SELECT 1 FROM %s WHERE %s='%s' AND (%s='y' OR %s='1')" , - table_s, - user_column_s, + options->table, + options->user_column, user_s, - expired_column_s, - expired_column_s) != 0) { + options->expired_column, + options->expired_column) != 0) { free(user_s); - free(table_s); - free(newtok_column_s); - free(user_column_s); - free(expired_column_s); PQclear(res); PQfinish(conn); @@ -646,10 +600,6 @@ } if(PQntuples(res) > 0) { free(user_s); - free(table_s); - free(newtok_column_s); - free(user_column_s); - free(expired_column_s); PQclear(res); PQfinish(conn); @@ -661,19 +611,15 @@ /* if new password is required then newtok_column = 'y' or '1' */ if(options->newtok_column) { - DBGLOG("query: SELECT 1 FROM %s WHERE %s='%s' AND %s='y' OR %s='1'", table_s, user_column_s, user_s, newtok_column_s, newtok_column_s); + DBGLOG("query: SELECT 1 FROM %s WHERE %s='%s' AND %s='y' OR %s='1'", options->table, options->user_column, user_s, options->newtok_column, options->newtok_column); if(pg_exec(options, conn, &res, "SELECT 1 FROM %s WHERE %s='%s' AND (%s='y' OR %s='1')", - table_s, - user_column_s, + options->table, + options->user_column, user_s, - newtok_column_s, - newtok_column_s) != 0) { + options->newtok_column, + options->newtok_column) != 0) { free(user_s); - free(table_s); - free(newtok_column_s); - free(user_column_s); - free(expired_column_s); PQclear(res); PQfinish(conn); @@ -682,10 +628,6 @@ } if(PQntuples(res) > 0) { free(user_s); - free(table_s); - free(newtok_column_s); - free(user_column_s); - free(expired_column_s); PQclear(res); PQfinish(conn); @@ -697,10 +639,6 @@ PQfinish(conn); free(user_s); - free(table_s); - free(newtok_column_s); - free(user_column_s); - free(expired_column_s); free_module_options(options); return PAM_SUCCESS; } @@ -713,11 +651,7 @@ int rc, std_flags, esclen; const char *user, *pass, *newpass; char *newpass_crypt, *user_s; - char *table_s; char *newpass_crypt_s; - char *user_column_s; - char *pwd_column_s; - char *newtok_column_s; PGconn *conn; PGresult *res; @@ -811,44 +745,23 @@ sqlescape(user, user_s, strlen(user)); - esclen = strlen(options->pwd_column)*2+1; - pwd_column_s = malloc(esclen); - sqlescape(options->pwd_column, pwd_column_s, strlen(options->pwd_column)); - - esclen = strlen(options->table)*2+1; - table_s = malloc(esclen); - sqlescape(options->table, table_s, strlen(options->table)); - - esclen = strlen(options->user_column)*2+1; - user_column_s = malloc(esclen); - sqlescape(options->user_column, user_column_s, strlen(options->user_column)); - esclen = strlen(newpass_crypt)*2+1; newpass_crypt_s = malloc(esclen); sqlescape(newpass_crypt, newpass_crypt_s, strlen(newpass_crypt)); - esclen = strlen(options->newtok_column)*2+1; - newtok_column_s = malloc(esclen); - sqlescape(options->newtok_column, newtok_column_s, strlen(options->newtok_column)); - - - DBGLOG("query: UPDATE %s SET %s='%s' WHERE %s='%s'", table_s, pwd_column_s, "******", user_column_s, user_s); + DBGLOG("query: UPDATE %s SET %s='%s' WHERE %s='%s'", options->table, options->pwd_column, "******", options->user_column, user_s); if (!options->newtok_column) { if(pg_exec(options, conn, &res, "UPDATE %s SET %s='%s' WHERE %s='%s'", - table_s, - pwd_column_s, + options->table, + options->pwd_column, newpass_crypt_s, - user_column_s, + options->user_column, user_s) != 0) { free(newpass_crypt); free(newpass_crypt_s); free(user_s); - free(pwd_column_s); - free(user_column_s); - free(newtok_column_s); - free(table_s); free_module_options(options); PQclear(res); PQfinish(conn); @@ -857,19 +770,14 @@ } else { if(pg_exec(options, conn, &res, "UPDATE %s SET %s='%s', %s='0' WHERE %s='%s'", - table_s, - pwd_column_s, + options->table, + options->pwd_column, newpass_crypt_s, - newtok_column_s, - user_column_s, + options->user_column, user_s) != 0) { free(newpass_crypt); free(newpass_crypt_s); free(user_s); - free(pwd_column_s); - free(user_column_s); - free(newtok_column_s); - free(table_s); free_module_options(options); PQclear(res); PQfinish(conn); @@ -881,10 +789,6 @@ free(newpass_crypt); free(newpass_crypt_s); free(user_s); - free(pwd_column_s); - free(user_column_s); - free(newtok_column_s); - free(table_s); PQclear(res); PQfinish(conn); }
signature.asc
Description: Digital signature