--- orig/pam-pgsql-0.5.2/pam_pgsql.c	Sat Mar 20 02:57:03 2004
+++ pam-pgsql-0.5.2/pam_pgsql.c	Sat Mar 20 03:10:34 2004
@@ -375,47 +375,7 @@
 static size_t 
 sqlescape(const char *from, char *to, size_t len)
 {
-    const char *source = from;
-    char *target = to;
-    unsigned int remaining = len;
-
-    while (remaining > 0 && *source != '\0') {
-        switch (*source) {
-        case '\0':
-            *target = '\\';
-            target++;
-            *target = '0';
-            break;
-
-        case '\\':
-            *target = '\\';
-            target++;
-            *target = '\\';
-            break;
-
-        case '\'':
-            *target = '\\';
-            target++;
-            *target = '\'';
-            break;
-
-        case '"':
-            *target = '\\';
-            target++;
-            *target = '"';
-            break;
-
-        default:
-            *target = *source;
-        }
-        source++;
-        target++;
-        remaining--;
-    }
-
-    *target = '\0';
-
-    return target - to;
+return PQescapeString(to,from,len);
 }
 
 /* private: authenticate user and passwd against database */
@@ -425,24 +385,39 @@
 {
     PGresult *res;
     PGconn *conn;
-    int rc, ulen;
+    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)))
         return PAM_AUTH_ERR;
 
-    ulen = strlen(user)*2+1;
-    user_s = malloc(ulen);
+    esclen = strlen(user)*2+1;
+    user_s = malloc(esclen);
 
     sqlescape(user, user_s, strlen(user));
     DBGLOG("%s", user_s);
 
-    DBGLOG("query: SELECT %s FROM %s WHERE %s='%s'", options->pwd_column, options->table, options->user_column, 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));
+
+    DBGLOG("query: SELECT %s FROM %s WHERE %s='%s'", pwd_column_s, table_s, user_column_s, user_s);
     if(pg_exec(options, conn, &res, "SELECT %s FROM %s WHERE %s='%s'",
-               options->pwd_column,
-               options->table,
-               options->user_column,
+               pwd_column_s,
+               table_s,
+               user_column_s,
                user_s) != 0) {
         PQfinish(conn);
         return PAM_AUTH_ERR;
@@ -498,6 +473,9 @@
     PQclear(res);
     PQfinish(conn);
     free(user_s);
+    free(table_s);
+    free(user_column_s);
+    free(pwd_column_s);
     return rc;
 }
 
@@ -545,7 +523,11 @@
     struct module_options *options;
     const char *user;
     char *user_s;
-    int rc, ulen;
+    char *table_s;
+    char *expired_column_s;
+    char *user_column_s;
+    char *newtok_column_s;
+    int rc, esclen;
     PGconn *conn;
     PGresult *res;
 
@@ -572,21 +554,39 @@
         return PAM_AUTH_ERR;
     }
 
-    ulen = strlen(user)*2+1;
-    user_s = malloc(ulen);
+    esclen = strlen(user)*2+1;
+    user_s = malloc(esclen);
 
     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'", options->table, options->user_column, user, options->expired_column, 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);
         if(pg_exec(options, conn, &res, 
                    "SELECT 1 FROM %s WHERE %s='%s' AND (%s='y' OR %s='1')" ,
-                   options->table,
-                   options->user_column,
+                   table_s,
+                   user_column_s,
                    user_s,
-                   options->expired_column,
-                   options->expired_column) != 0) {
+                   expired_column_s,
+                   expired_column_s) != 0) {
             PQfinish(conn);
             free_module_options(options);
             return PAM_AUTH_ERR;
@@ -602,14 +602,14 @@
 
     /* 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'", options->table, options->user_column, user, options->newtok_column, 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);
         if(pg_exec(options, conn, &res, 
                    "SELECT 1 FROM %s WHERE %s='%s' AND (%s='y' OR %s='1')",
-                   options->table,
-                   options->user_column,
+                   table_s,
+                   user_column_s,
                    user_s,
-                   options->newtok_column,
-                   options->newtok_column) != 0) {
+                   newtok_column_s,
+                   newtok_column_s) != 0) {
             PQfinish(conn);
             free_module_options(options);
             return PAM_AUTH_ERR;
@@ -625,6 +625,10 @@
 
     PQfinish(conn);
     free(user_s);
+    free(table_s);
+    free(newtok_column_s);
+    free(user_column_s);
+    free(expired_column_s);
     return PAM_SUCCESS;
 }
 
@@ -633,9 +637,13 @@
 pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
     struct module_options *options;
-    int rc, std_flags, ulen;
+    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;
     PGconn *conn;
     PGresult *res;
 
@@ -714,18 +722,34 @@
             return PAM_AUTHINFO_UNAVAIL;
         }
 
-        ulen = strlen(user)*2+1;
-        user_s = malloc(ulen);
+        esclen = strlen(user)*2+1;
+        user_s = malloc(esclen);
 
         sqlescape(user, user_s, strlen(user));
 
-        DBGLOG("query: UPDATE %s SET %s='%s' WHERE %s='%s'", options->table, options->pwd_column, "******", options->user_column, 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));
+
+        DBGLOG("query: UPDATE %s SET %s='%s' WHERE %s='%s'", table_s, pwd_column_s, "******", user_column_s, user_s);
         if(pg_exec(options, conn, &res,
                    "UPDATE %s SET %s='%s' WHERE %s='%s'",
-                   options->table,
-                   options->pwd_column,
-                   newpass_crypt,
-                   options->user_column,
+                   table_s,
+                   pwd_column_s,
+                   newpass_crypt_s,
+                   user_column_s,
                    user_s) != 0) {
             free(newpass_crypt);
             free_module_options(options);
@@ -735,12 +759,16 @@
 
         /* if we get here, we must have succeeded (pg_exec checks for success) */
         free(newpass_crypt);
+        free(newpass_crypt_s);
+        free(user_s);
+        free(pwd_column_s);
+        free(user_column_s);
+        free(table_s);
         PQclear(res);
         PQfinish(conn);
     }
 
     free_module_options(options);
-    free(user_s);
     SYSLOG("(%s) password for '%s' was changed.", pam_get_service(pamh), user);
     return PAM_SUCCESS;
 }
