Index: doc/src/sgml/client-auth.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v retrieving revision 1.15 diff -c -r1.15 client-auth.sgml *** doc/src/sgml/client-auth.sgml 2001/08/01 23:25:39 1.15 --- doc/src/sgml/client-auth.sgml 2001/08/15 05:12:48 *************** *** 205,215 **** Like the password method, but the password is sent over the wire encrypted using a simple ! challenge-response protocol. This is still not ! cryptographically secure but it protects against incidental wire-sniffing. The name of a file may follow the ! crypt keyword that contains a list of users ! that this record pertains to. --- 205,214 ---- Like the password method, but the password is sent over the wire encrypted using a simple ! challenge-response protocol. This protects against incidental wire-sniffing. The name of a file may follow the ! crypt keyword. It contains a list of users ! for this record. Index: doc/src/sgml/protocol.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/protocol.sgml,v retrieving revision 1.18 diff -c -r1.18 protocol.sgml *** doc/src/sgml/protocol.sgml 2001/06/22 23:27:48 1.18 --- doc/src/sgml/protocol.sgml 2001/08/15 05:12:49 *************** *** 1295,1301 **** ! The encrypted (using crypt()) password. --- 1295,1301 ---- ! The encrypted (using MD5 or crypt()) password. Index: doc/src/sgml/runtime.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/runtime.sgml,v retrieving revision 1.74 diff -c -r1.74 runtime.sgml *** doc/src/sgml/runtime.sgml 2001/08/09 16:20:43 1.74 --- doc/src/sgml/runtime.sgml 2001/08/15 05:12:52 *************** *** 968,973 **** --- 968,985 ---- + AUSTRALIAN_TIMEZONES (bool) + + + If set to true, CST, EST, + and SAT are interpreted as Australian + timezones rather than as North American Central/Eastern + Timezones and Saturday. The default is false. + + + + + deadlock timeout *************** *** 1256,1273 **** keyword to exclude subtables. See the SQL language reference and the User's Guide for more information about inheritance. - - - - - - AUSTRALIAN_TIMEZONES (bool) - - - If set to true, CST, EST, - and SAT are interpreted as Australian - timezones rather than as North American Central/Eastern - Timezones and Saturday. The default is false. --- 1268,1273 ---- Index: doc/src/sgml/ref/alter_user.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/alter_user.sgml,v retrieving revision 1.14 diff -c -r1.14 alter_user.sgml *** doc/src/sgml/ref/alter_user.sgml 2001/07/10 22:09:27 1.14 --- doc/src/sgml/ref/alter_user.sgml 2001/08/15 05:12:52 *************** *** 27,33 **** where option can be: ! PASSWORD 'password' | CREATEDB | NOCREATEDB | CREATEUSER | NOCREATEUSER | VALID UNTIL 'abstime' --- 27,33 ---- where option can be: ! [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password' | CREATEDB | NOCREATEDB | CREATEUSER | NOCREATEUSER | VALID UNTIL 'abstime' *************** *** 53,62 **** ! password The new password to be used for this account. --- 53,65 ---- ! [ encrypted | unencrypted ] password The new password to be used for this account. + Encrypted/ unencrypted + controls whether the password is stored encrypted in the + database. Index: doc/src/sgml/ref/create_user.sgml =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/ref/create_user.sgml,v retrieving revision 1.17 diff -c -r1.17 create_user.sgml *** doc/src/sgml/ref/create_user.sgml 2001/07/10 22:09:27 1.17 --- doc/src/sgml/ref/create_user.sgml 2001/08/15 05:12:52 *************** *** 28,34 **** where option can be: SYSID uid ! | PASSWORD 'password' | CREATEDB | NOCREATEDB | CREATEUSER | NOCREATEUSER | IN GROUP groupname [, ...] --- 28,34 ---- where option can be: SYSID uid ! | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password' | CREATEDB | NOCREATEDB | CREATEUSER | NOCREATEUSER | IN GROUP groupname [, ...] *************** *** 72,83 **** ! password Sets the user's password. If you do not plan to use password authentication you can omit this option, otherwise the user won't be able to connect to a password-authenticated server. See the chapter on client authentication in the Administrator's Guide for details on how to set up authentication mechanisms. --- 72,90 ---- ! [ encrypted | unencrypted ] password Sets the user's password. If you do not plan to use password authentication you can omit this option, otherwise the user won't be able to connect to a password-authenticated server. + + + ENCRYPTED/UNENCRYPTED controls whether the + password is stored encrypted in the database. Older clients may + have trouble communicating using encrypted password storage. + + See the chapter on client authentication in the Administrator's Guide for details on how to set up authentication mechanisms. Index: src/backend/commands/user.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/commands/user.c,v retrieving revision 1.79 diff -c -r1.79 user.c *** src/backend/commands/user.c 2001/07/12 18:02:59 1.79 --- src/backend/commands/user.c 2001/08/15 05:12:53 *************** *** 25,30 **** --- 25,31 ---- #include "catalog/indexing.h" #include "commands/user.h" #include "libpq/crypt.h" + #include "libpq/md5.h" #include "miscadmin.h" #include "utils/array.h" #include "utils/builtins.h" *************** *** 34,41 **** static void CheckPgUserAclNotNull(void); - /*--------------------------------------------------------------------- * write_password_file / update_pg_pwd * --- 35,42 ---- static void CheckPgUserAclNotNull(void); + extern bool Password_encryption; /*--------------------------------------------------------------------- * write_password_file / update_pg_pwd * *************** *** 201,272 **** int max_id = -1; List *item, *option; char *password = NULL; /* PostgreSQL user password */ int sysid = 0; /* PgSQL system id (valid if havesysid) */ bool createdb = false; /* Can the user create databases? */ bool createuser = false; /* Can this user create users? */ List *groupElts = NIL; /* The groups the user is a member of */ char *validUntil = NULL; /* The time the login is valid until */ ! DefElem *dpassword = NULL; ! DefElem *dsysid = NULL; ! DefElem *dcreatedb = NULL; ! DefElem *dcreateuser = NULL; ! DefElem *dgroupElts = NULL; ! DefElem *dvalidUntil = NULL; /* Extract options from the statement node tree */ foreach(option, stmt->options) { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "password") == 0) { ! if (dpassword) ! elog(ERROR, "CREATE USER: conflicting options"); ! dpassword = defel; ! } ! else if (strcasecmp(defel->defname, "sysid") == 0) { ! if (dsysid) ! elog(ERROR, "CREATE USER: conflicting options"); ! dsysid = defel; ! } ! else if (strcasecmp(defel->defname, "createdb") == 0) { ! if (dcreatedb) ! elog(ERROR, "CREATE USER: conflicting options"); ! dcreatedb = defel; ! } ! else if (strcasecmp(defel->defname, "createuser") == 0) { ! if (dcreateuser) ! elog(ERROR, "CREATE USER: conflicting options"); ! dcreateuser = defel; ! } ! else if (strcasecmp(defel->defname, "groupElts") == 0) { ! if (dgroupElts) ! elog(ERROR, "CREATE USER: conflicting options"); ! dgroupElts = defel; ! } ! else if (strcasecmp(defel->defname, "validUntil") == 0) { ! if (dvalidUntil) ! elog(ERROR, "CREATE USER: conflicting options"); ! dvalidUntil = defel; ! } ! else ! elog(ERROR,"CREATE USER: option \"%s\" not recognized", ! defel->defname); ! } ! if (dcreatedb) createdb = intVal(dcreatedb->arg) != 0; ! if (dcreateuser) createuser = intVal(dcreateuser->arg) != 0; ! if (dsysid) { sysid = intVal(dsysid->arg); havesysid = true; } ! if (dvalidUntil) validUntil = strVal(dvalidUntil->arg); ! if (dpassword) password = strVal(dpassword->arg); ! if (dgroupElts) groupElts = (List *) dgroupElts->arg; /* Check some permissions first */ --- 202,281 ---- int max_id = -1; List *item, *option; char *password = NULL; /* PostgreSQL user password */ + bool encrypt_password = Password_encryption; /* encrypt password? */ + char encrypted_password[MD5_PASSWD_LEN+1]; int sysid = 0; /* PgSQL system id (valid if havesysid) */ bool createdb = false; /* Can the user create databases? */ bool createuser = false; /* Can this user create users? */ List *groupElts = NIL; /* The groups the user is a member of */ char *validUntil = NULL; /* The time the login is valid until */ ! DefElem *dpassword = NULL; ! DefElem *dsysid = NULL; ! DefElem *dcreatedb = NULL; ! DefElem *dcreateuser = NULL; ! DefElem *dgroupElts = NULL; ! DefElem *dvalidUntil = NULL; /* Extract options from the statement node tree */ foreach(option, stmt->options) { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "password") == 0 || ! strcasecmp(defel->defname, "encryptedPassword") == 0 || ! strcasecmp(defel->defname, "unencryptedPassword") == 0) { ! if (dpassword) ! elog(ERROR, "CREATE USER: conflicting options"); ! dpassword = defel; ! if (strcasecmp(defel->defname, "encryptedPassword") == 0) ! encrypt_password = true; ! else if (strcasecmp(defel->defname, "unencryptedPassword") == 0) ! encrypt_password = false; ! } ! else if (strcasecmp(defel->defname, "sysid") == 0) { ! if (dsysid) ! elog(ERROR, "CREATE USER: conflicting options"); ! dsysid = defel; ! } ! else if (strcasecmp(defel->defname, "createdb") == 0) { ! if (dcreatedb) ! elog(ERROR, "CREATE USER: conflicting options"); ! dcreatedb = defel; ! } ! else if (strcasecmp(defel->defname, "createuser") == 0) { ! if (dcreateuser) ! elog(ERROR, "CREATE USER: conflicting options"); ! dcreateuser = defel; ! } ! else if (strcasecmp(defel->defname, "groupElts") == 0) { ! if (dgroupElts) ! elog(ERROR, "CREATE USER: conflicting options"); ! dgroupElts = defel; ! } ! else if (strcasecmp(defel->defname, "validUntil") == 0) { ! if (dvalidUntil) ! elog(ERROR, "CREATE USER: conflicting options"); ! dvalidUntil = defel; ! } ! else ! elog(ERROR,"CREATE USER: option \"%s\" not recognized", ! defel->defname); ! } ! if (dcreatedb) createdb = intVal(dcreatedb->arg) != 0; ! if (dcreateuser) createuser = intVal(dcreateuser->arg) != 0; ! if (dsysid) { sysid = intVal(dsysid->arg); havesysid = true; } ! if (dvalidUntil) validUntil = strVal(dvalidUntil->arg); ! if (dpassword) password = strVal(dpassword->arg); ! if (dgroupElts) groupElts = (List *) dgroupElts->arg; /* Check some permissions first */ *************** *** 337,344 **** new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser); if (password) ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(password)); if (validUntil) new_record[Anum_pg_shadow_valuntil - 1] = DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil)); --- 346,363 ---- new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser); if (password) ! { ! if (!encrypt_password || isMD5(password)) ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(password)); ! else ! { ! if (!EncryptMD5(password, stmt->user, encrypted_password)) ! elog(ERROR, "CREATE USER: password encryption failed"); ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); ! } ! } if (validUntil) new_record[Anum_pg_shadow_valuntil - 1] = DirectFunctionCall1(nabstimein, CStringGetDatum(validUntil)); *************** *** 418,423 **** --- 437,444 ---- bool null; List *option; char *password = NULL; /* PostgreSQL user password */ + bool encrypt_password = Password_encryption; /* encrypt password? */ + char encrypted_password[MD5_PASSWD_LEN+1]; int createdb = -1; /* Can the user create databases? */ int createuser = -1; /* Can this user create users? */ char *validUntil = NULL; /* The time the login is valid until */ *************** *** 431,440 **** { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "password") == 0) { if (dpassword) elog(ERROR, "ALTER USER: conflicting options"); dpassword = defel; } else if (strcasecmp(defel->defname, "createdb") == 0) { if (dcreatedb) --- 452,467 ---- { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "password") == 0 || ! strcasecmp(defel->defname, "encryptedPassword") == 0 || ! strcasecmp(defel->defname, "unencryptedPassword") == 0) { if (dpassword) elog(ERROR, "ALTER USER: conflicting options"); dpassword = defel; + if (strcasecmp(defel->defname, "encryptedPassword") == 0) + encrypt_password = true; + else if (strcasecmp(defel->defname, "unencryptedPassword") == 0) + encrypt_password = false; } else if (strcasecmp(defel->defname, "createdb") == 0) { if (dcreatedb) *************** *** 445,461 **** if (dcreateuser) elog(ERROR, "ALTER USER: conflicting options"); dcreateuser = defel; ! } else if (strcasecmp(defel->defname, "validUntil") == 0) { if (dvalidUntil) elog(ERROR, "ALTER USER: conflicting options"); dvalidUntil = defel; } ! else elog(ERROR,"ALTER USER: option \"%s\" not recognized", defel->defname); } ! if (dcreatedb) createdb = intVal(dcreatedb->arg); if (dcreateuser) --- 472,488 ---- if (dcreateuser) elog(ERROR, "ALTER USER: conflicting options"); dcreateuser = defel; ! } else if (strcasecmp(defel->defname, "validUntil") == 0) { if (dvalidUntil) elog(ERROR, "ALTER USER: conflicting options"); dvalidUntil = defel; } ! else elog(ERROR,"ALTER USER: option \"%s\" not recognized", defel->defname); } ! if (dcreatedb) createdb = intVal(dcreatedb->arg); if (dcreateuser) *************** *** 464,471 **** validUntil = strVal(dvalidUntil->arg); if (dpassword) password = strVal(dpassword->arg); ! ! if (password) CheckPgUserAclNotNull(); /* must be superuser or just want to change your own password */ --- 491,498 ---- validUntil = strVal(dvalidUntil->arg); if (dpassword) password = strVal(dpassword->arg); ! ! if (password) CheckPgUserAclNotNull(); /* must be superuser or just want to change your own password */ *************** *** 552,559 **** /* password */ if (password) { ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(password)); new_record_nulls[Anum_pg_shadow_passwd - 1] = ' '; } else --- 579,594 ---- /* password */ if (password) { ! if (!encrypt_password || isMD5(password)) ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(password)); ! else ! { ! if (!EncryptMD5(password, stmt->user, encrypted_password)) ! elog(ERROR, "CREATE USER: password encryption failed"); ! new_record[Anum_pg_shadow_passwd - 1] = ! DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); ! } new_record_nulls[Anum_pg_shadow_passwd - 1] = ' '; } else *************** *** 793,832 **** Datum new_record[Natts_pg_group]; char new_record_nulls[Natts_pg_group]; List *item, ! *option, *newlist = NIL; ArrayType *userarray; ! int sysid = 0; ! List *userElts = NIL; ! DefElem *dsysid = NULL; ! DefElem *duserElts = NULL; foreach(option, stmt->options) { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "sysid") == 0) { ! if (dsysid) ! elog(ERROR, "CREATE GROUP: conflicting options"); ! dsysid = defel; ! } ! else if (strcasecmp(defel->defname, "userElts") == 0) { ! if (duserElts) ! elog(ERROR, "CREATE GROUP: conflicting options"); ! duserElts = defel; ! } ! else ! elog(ERROR,"CREATE GROUP: option \"%s\" not recognized", ! defel->defname); ! } ! if (dsysid) { sysid = intVal(dsysid->arg); havesysid = true; } ! if (duserElts) userElts = (List *) duserElts->arg; /* --- 828,867 ---- Datum new_record[Natts_pg_group]; char new_record_nulls[Natts_pg_group]; List *item, ! *option, *newlist = NIL; ArrayType *userarray; ! int sysid = 0; ! List *userElts = NIL; ! DefElem *dsysid = NULL; ! DefElem *duserElts = NULL; foreach(option, stmt->options) { DefElem *defel = (DefElem *) lfirst(option); ! if (strcasecmp(defel->defname, "sysid") == 0) { ! if (dsysid) ! elog(ERROR, "CREATE GROUP: conflicting options"); ! dsysid = defel; ! } ! else if (strcasecmp(defel->defname, "userElts") == 0) { ! if (duserElts) ! elog(ERROR, "CREATE GROUP: conflicting options"); ! duserElts = defel; ! } ! else ! elog(ERROR,"CREATE GROUP: option \"%s\" not recognized", ! defel->defname); ! } ! if (dsysid) { sysid = intVal(dsysid->arg); havesysid = true; } ! if (duserElts) userElts = (List *) duserElts->arg; /* Index: src/backend/libpq/Makefile =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/Makefile,v retrieving revision 1.24 diff -c -r1.24 Makefile *** src/backend/libpq/Makefile 2000/08/25 10:00:30 1.24 --- src/backend/libpq/Makefile 2001/08/15 05:12:53 *************** *** 15,21 **** # be-fsstubs is here for historical reasons, probably belongs elsewhere OBJS = be-fsstubs.o \ ! auth.o crypt.o hba.o password.o \ pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o --- 15,21 ---- # be-fsstubs is here for historical reasons, probably belongs elsewhere OBJS = be-fsstubs.o \ ! auth.o crypt.o hba.o md5.o password.o \ pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o Index: src/backend/libpq/auth.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/auth.c,v retrieving revision 1.56 diff -c -r1.56 auth.c *** src/backend/libpq/auth.c 2001/08/07 10:44:13 1.56 --- src/backend/libpq/auth.c 2001/08/15 05:12:53 *************** *** 420,428 **** authmethod = "IDENT"; break; case uaPassword: - authmethod = "Password"; - break; case uaCrypt: authmethod = "Password"; break; } --- 420,427 ---- authmethod = "IDENT"; break; case uaPassword: case uaCrypt: + case uaMD5: authmethod = "Password"; break; } *************** *** 507,512 **** --- 506,516 ---- status = recv_and_check_password_packet(port); break; + case uaMD5: + sendAuthRequest(port, AUTH_REQ_MD5); + status = recv_and_check_password_packet(port); + break; + case uaTrust: status = STATUS_OK; break; *************** *** 532,538 **** pq_sendint(&buf, (int32) areq, sizeof(int32)); /* Add the salt for encrypted passwords. */ ! if (areq == AUTH_REQ_CRYPT) { pq_sendint(&buf, port->salt[0], 1); pq_sendint(&buf, port->salt[1], 1); --- 536,542 ---- pq_sendint(&buf, (int32) areq, sizeof(int32)); /* Add the salt for encrypted passwords. */ ! if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5) { pq_sendint(&buf, port->salt[0], 1); pq_sendint(&buf, port->salt[1], 1); *************** *** 557,563 **** if (pq_eof() == EOF || pq_getint(&len, 4) == EOF) return STATUS_ERROR; /* client didn't want to send password */ initStringInfo(&buf); ! pq_getstr(&buf); if (DebugLvl) fprintf(stderr, "received password packet with len=%d, pw=%s\n", --- 561,567 ---- if (pq_eof() == EOF || pq_getint(&len, 4) == EOF) return STATUS_ERROR; /* client didn't want to send password */ initStringInfo(&buf); ! pq_getstr(&buf); /* receive password */ if (DebugLvl) fprintf(stderr, "received password packet with len=%d, pw=%s\n", *************** *** 579,585 **** if (port->auth_arg[0] != '\0') return verify_password(port, user, password); ! return crypt_verify(port, user, password); } --- 583,589 ---- if (port->auth_arg[0] != '\0') return verify_password(port, user, password); ! return md5_crypt_verify(port, user, password); } *************** *** 594,600 **** MsgType msgtype = (MsgType) port->proto; /* Handle the authentication that's offered. */ - switch (msgtype) { case STARTUP_KRB4_MSG: --- 598,603 ---- *************** *** 634,639 **** --- 637,643 ---- switch (port->auth_method) { case uaCrypt: + case uaMD5: case uaReject: status = STATUS_ERROR; break; Index: src/backend/libpq/crypt.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/crypt.c,v retrieving revision 1.32 diff -c -r1.32 crypt.c *** src/backend/libpq/crypt.c 2001/06/23 23:26:17 1.32 --- src/backend/libpq/crypt.c 2001/08/15 05:12:54 *************** *** 19,24 **** --- 19,25 ---- #include "postgres.h" #include "libpq/crypt.h" + #include "libpq/md5.h" #include "miscadmin.h" #include "storage/fd.h" #include "utils/nabstime.h" *************** *** 254,260 **** /*-------------------------------------------------------------------------*/ int ! crypt_verify(const Port *port, const char *user, const char *pgpass) { char *passwd, --- 255,261 ---- /*-------------------------------------------------------------------------*/ int ! md5_crypt_verify(const Port *port, const char *user, const char *pgpass) { char *passwd, *************** *** 280,288 **** * Compare with the encrypted or plain password depending on the * authentication method being used for this connection. */ ! ! crypt_pwd = ! (port->auth_method == uaCrypt ? crypt(passwd, port->salt) : passwd); if (!strcmp(pgpass, crypt_pwd)) { --- 281,327 ---- * Compare with the encrypted or plain password depending on the * authentication method being used for this connection. */ ! switch (port->auth_method) ! { ! case uaCrypt: ! crypt_pwd = crypt(passwd, port->salt); ! break; ! case uaMD5: ! crypt_pwd = palloc(MD5_PASSWD_LEN+1); ! ! if (isMD5(passwd)) ! { ! if (!EncryptMD5(passwd + strlen("md5"), ! (char *)port->salt, crypt_pwd)) ! { ! pfree(crypt_pwd); ! return STATUS_ERROR; ! } ! } ! else ! { ! char *crypt_pwd2 = palloc(MD5_PASSWD_LEN+1); ! ! if (!EncryptMD5(passwd, port->user, crypt_pwd2)) ! { ! pfree(crypt_pwd); ! pfree(crypt_pwd2); ! return STATUS_ERROR; ! } ! if (!EncryptMD5(crypt_pwd2 + strlen("md5"), port->salt, ! crypt_pwd)) ! { ! pfree(crypt_pwd); ! pfree(crypt_pwd2); ! return STATUS_ERROR; ! } ! pfree(crypt_pwd2); ! } ! break; ! default: ! crypt_pwd = passwd; ! break; ! } if (!strcmp(pgpass, crypt_pwd)) { *************** *** 302,310 **** retval = STATUS_OK; } ! pfree((void *) passwd); if (valuntil) ! pfree((void *) valuntil); return retval; } --- 341,351 ---- retval = STATUS_OK; } ! pfree(passwd); if (valuntil) ! pfree(valuntil); ! if (port->auth_method == uaMD5) ! pfree(crypt_pwd); return retval; } Index: src/backend/libpq/hba.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/hba.c,v retrieving revision 1.61 diff -c -r1.61 hba.c *** src/backend/libpq/hba.c 2001/08/02 14:39:35 1.61 --- src/backend/libpq/hba.c 2001/08/15 05:12:54 *************** *** 203,210 **** * *error_p. line points to the next token of the line. */ static void ! parse_hba_auth(List *line, UserAuth *userauth_p, char *auth_arg, ! bool *error_p) { char *token; --- 203,210 ---- * *error_p. line points to the next token of the line. */ static void ! parse_hba_auth(List *line, ProtocolVersion proto, UserAuth *userauth_p, ! char *auth_arg, bool *error_p) { char *token; *************** *** 227,233 **** else if (strcmp(token, "reject") == 0) *userauth_p = uaReject; else if (strcmp(token, "crypt") == 0) ! *userauth_p = uaCrypt; else *error_p = true; line = lnext(line); --- 227,241 ---- else if (strcmp(token, "reject") == 0) *userauth_p = uaReject; else if (strcmp(token, "crypt") == 0) ! { ! /* if the client supports it, use MD5 */ ! if (PG_PROTOCOL_MAJOR(proto) > 2 || ! (PG_PROTOCOL_MAJOR(proto) == 2 && ! PG_PROTOCOL_MINOR(proto) >= 1)) ! *userauth_p = uaMD5; ! else ! *userauth_p = uaCrypt; ! } else *error_p = true; line = lnext(line); *************** *** 285,291 **** line = lnext(line); if (!line) goto hba_syntax; ! parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p); if (*error_p) goto hba_syntax; --- 293,300 ---- line = lnext(line); if (!line) goto hba_syntax; ! parse_hba_auth(line, port->proto, &port->auth_method, ! port->auth_arg, error_p); if (*error_p) goto hba_syntax; *************** *** 354,360 **** line = lnext(line); if (!line) goto hba_syntax; ! parse_hba_auth(line, &port->auth_method, port->auth_arg, error_p); if (*error_p) goto hba_syntax; --- 363,370 ---- line = lnext(line); if (!line) goto hba_syntax; ! parse_hba_auth(line, port->proto, &port->auth_method, ! port->auth_arg, error_p); if (*error_p) goto hba_syntax; Index: src/backend/libpq/password.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/password.c,v retrieving revision 1.37 diff -c -r1.37 password.c *** src/backend/libpq/password.c 2001/06/18 16:11:30 1.37 --- src/backend/libpq/password.c 2001/08/15 05:12:54 *************** *** 82,92 **** * the current code needs non-encrypted passwords to * encrypt with a random salt. */ ! if (port->auth_method == uaCrypt ! || test_pw == NULL || test_pw[0] == '\0' ! || strcmp(test_pw, "+") == 0) ! return crypt_verify(port, user, password); if (strcmp(crypt(password, test_pw), test_pw) == 0) { /* it matched. */ --- 82,95 ---- * the current code needs non-encrypted passwords to * encrypt with a random salt. */ ! if (port->auth_method == uaCrypt || ! port->auth_method == uaMD5 || ! test_pw == NULL || ! test_pw[0] == '\0' || ! strcmp(test_pw, "+") == 0) ! return md5_crypt_verify(port, user, password); + /* external password file is crypt-only */ if (strcmp(crypt(password, test_pw), test_pw) == 0) { /* it matched. */ Index: src/backend/libpq/pg_hba.conf.sample =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/libpq/pg_hba.conf.sample,v retrieving revision 1.23 diff -c -r1.23 pg_hba.conf.sample *** src/backend/libpq/pg_hba.conf.sample 2001/08/01 23:25:39 1.23 --- src/backend/libpq/pg_hba.conf.sample 2001/08/15 05:12:55 *************** *** 3,9 **** # # # This file controls: - # # o which hosts are allowed to connect # o how users are authenticated on each host # o databases accessible by each host --- 3,8 ---- *************** *** 24,30 **** # ============ # # There are three types of records: - # # o host # o hostssl # o local --- 23,28 ---- *************** *** 40,46 **** # host DBNAME IP_ADDRESS ADDRESS_MASK AUTH_TYPE [AUTH_ARGUMENT] # # DBNAME can be: - # # o the name of a PostgreSQL database # o "all" to indicate all databases # o "sameuser" to allow access only to databases with the same --- 38,43 ---- *************** *** 80,86 **** # allowed only if this record type appears. # # Format: - # # local DBNAME AUTH_TYPE [AUTH_ARGUMENT] # # This format is identical to the "host" record type except the IP_ADDRESS --- 77,82 ---- *************** *** 219,222 **** local all trust host all 127.0.0.1 255.255.255.255 trust - --- 215,217 ---- Index: src/backend/parser/gram.y =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/gram.y,v retrieving revision 2.244 diff -c -r2.244 gram.y *** src/backend/parser/gram.y 2001/08/13 21:34:51 2.244 --- src/backend/parser/gram.y 2001/08/15 05:13:01 *************** *** 306,312 **** CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP, ! ELSE, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT, FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL, GLOBAL, GRANT, GROUP, HAVING, HOUR_P, IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS, --- 306,312 ---- CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR, DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP, ! ELSE, ENCRYPTED, END_TRANS, ESCAPE, EXCEPT, EXECUTE, EXISTS, EXTRACT, FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL, GLOBAL, GRANT, GROUP, HAVING, HOUR_P, IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS, *************** *** 319,325 **** SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING, TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P, ! UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING, VALUES, VARCHAR, VARYING, VIEW, WHEN, WHERE, WITH, WORK, YEAR_P, ZONE --- 319,325 ---- SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING, TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P, ! UNENCRYPTED, UNION, UNIQUE, UNKNOWN, UPDATE, USER, USING, VALUES, VARCHAR, VARYING, VIEW, WHEN, WHERE, WITH, WORK, YEAR_P, ZONE *************** *** 558,563 **** --- 558,575 ---- $$->defname = "password"; $$->arg = (Node *)makeString($2); } + | ENCRYPTED PASSWORD Sconst + { + $$ = makeNode(DefElem); + $$->defname = "encryptedPassword"; + $$->arg = (Node *)makeString($3); + } + | UNENCRYPTED PASSWORD Sconst + { + $$ = makeNode(DefElem); + $$->defname = "unencryptedPassword"; + $$->arg = (Node *)makeString($3); + } | SYSID Iconst { $$ = makeNode(DefElem); *************** *** 5765,5770 **** --- 5777,5783 ---- | DISTINCT { $$ = "distinct"; } | DO { $$ = "do"; } | ELSE { $$ = "else"; } + | ENCRYPTED { $$ = "encrypted"; } | END_TRANS { $$ = "end"; } | EXCEPT { $$ = "except"; } | EXISTS { $$ = "exists"; } *************** *** 5836,5841 **** --- 5849,5855 ---- | TRANSACTION { $$ = "transaction"; } | TRIM { $$ = "trim"; } | TRUE_P { $$ = "true"; } + | UNENCRYPTED { $$ = "unencrypted"; } | UNION { $$ = "union"; } | UNIQUE { $$ = "unique"; } | UNKNOWN { $$ = "unknown"; } Index: src/backend/parser/keywords.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/keywords.c,v retrieving revision 1.94 diff -c -r1.94 keywords.c *** src/backend/parser/keywords.c 2001/07/16 05:06:58 1.94 --- src/backend/parser/keywords.c 2001/08/15 05:13:02 *************** *** 102,107 **** --- 102,108 ---- {"each", EACH}, {"else", ELSE}, {"encoding", ENCODING}, + {"encrypted", ENCRYPTED}, {"end", END_TRANS}, {"escape", ESCAPE}, {"except", EXCEPT}, *************** *** 262,267 **** --- 263,269 ---- {"truncate", TRUNCATE}, {"trusted", TRUSTED}, {"type", TYPE_P}, + {"unencrypted", UNENCRYPTED}, {"union", UNION}, {"unique", UNIQUE}, {"unknown", UNKNOWN}, Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/guc.c,v retrieving revision 1.45 diff -c -r1.45 guc.c *** src/backend/utils/misc/guc.c 2001/07/05 15:19:40 1.45 --- src/backend/utils/misc/guc.c 2001/08/15 05:13:03 *************** *** 80,85 **** --- 80,87 ---- bool Australian_timezones = false; + bool Password_encryption = false; + #ifndef PG_KRB_SRVTAB #define PG_KRB_SRVTAB "" #endif *************** *** 246,255 **** {"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL}, ! {"australian_timezones", PGC_USERSET, &Australian_timezones, ! false, ClearDateCache}, {"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL}, {NULL, 0, NULL, false, NULL} }; --- 248,258 ---- {"sql_inheritance", PGC_USERSET, &SQL_inheritance, true, NULL}, ! {"australian_timezones", PGC_USERSET, &Australian_timezones, false, ClearDateCache}, {"fixbtree", PGC_POSTMASTER, &FixBTree, true, NULL}, + + {"password_encryption", PGC_USERSET, &Password_encryption, false, NULL}, {NULL, 0, NULL, false, NULL} }; Index: src/backend/utils/misc/postgresql.conf.sample =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v retrieving revision 1.15 diff -c -r1.15 postgresql.conf.sample *** src/backend/utils/misc/postgresql.conf.sample 2001/07/05 15:19:40 1.15 --- src/backend/utils/misc/postgresql.conf.sample 2001/08/15 05:13:03 *************** *** 176,184 **** # # Misc # - #default_transaction_isolation = 'read committed' - #sql_inheritance = true #australian_timezones = false #deadlock_timeout = 1000 #max_expr_depth = 10000 # min 10 --- 176,185 ---- # # Misc # #australian_timezones = false #deadlock_timeout = 1000 + #default_transaction_isolation = 'read committed' #max_expr_depth = 10000 # min 10 + #password_encryption = false + #sql_inheritance = true Index: src/include/miscadmin.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/miscadmin.h,v retrieving revision 1.88 diff -c -r1.88 miscadmin.h *** src/include/miscadmin.h 2001/08/05 02:06:50 1.88 --- src/include/miscadmin.h 2001/08/15 05:13:03 *************** *** 171,178 **** extern bool allowSystemTableMods; extern int SortMem; ! /* a few postmaster startup options are exported here so the ! configuration file processor has access to them */ extern bool NetServer; extern bool EnableSSL; --- 171,180 ---- extern bool allowSystemTableMods; extern int SortMem; ! /* ! * A few postmaster startup options are exported here so the ! * configuration file processor can access them. ! */ extern bool NetServer; extern bool EnableSSL; Index: src/include/libpq/crypt.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/crypt.h,v retrieving revision 1.11 diff -c -r1.11 crypt.h *** src/include/libpq/crypt.h 2000/07/04 16:32:01 1.11 --- src/include/libpq/crypt.h 2001/08/15 05:13:03 *************** *** 22,31 **** extern char *crypt_getpwdfilename(void); extern char *crypt_getpwdreloadfilename(void); ! #ifdef NOT_USED ! extern MsgType crypt_salt(const char *user); ! ! #endif ! extern int crypt_verify(const Port *port, const char *user, const char *pgpass); #endif --- 22,27 ---- extern char *crypt_getpwdfilename(void); extern char *crypt_getpwdreloadfilename(void); ! extern int md5_crypt_verify(const Port *port, const char *user, const char *pgpass); #endif Index: src/include/libpq/hba.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/hba.h,v retrieving revision 1.22 diff -c -r1.22 hba.h *** src/include/libpq/hba.h 2001/08/01 23:25:39 1.22 --- src/include/libpq/hba.h 2001/08/15 05:13:03 *************** *** 35,41 **** uaTrust, uaIdent, uaPassword, ! uaCrypt } UserAuth; typedef struct Port hbaPort; --- 35,43 ---- uaTrust, uaIdent, uaPassword, ! uaCrypt, ! uaMD5 /* This starts as uaCrypt from pg_hba.conf, but gets ! overridden if the client supports MD5 */ } UserAuth; typedef struct Port hbaPort; Index: src/include/libpq/pqcomm.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/libpq/pqcomm.h,v retrieving revision 1.55 diff -c -r1.55 pqcomm.h *** src/include/libpq/pqcomm.h 2001/03/22 04:00:48 1.55 --- src/include/libpq/pqcomm.h 2001/08/15 05:13:05 *************** *** 90,96 **** /* The earliest and latest frontend/backend protocol version supported. */ #define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0,0) ! #define PG_PROTOCOL_LATEST PG_PROTOCOL(2,0) /* * All packets sent to the postmaster start with the length. This is omitted --- 90,96 ---- /* The earliest and latest frontend/backend protocol version supported. */ #define PG_PROTOCOL_EARLIEST PG_PROTOCOL(0,0) ! #define PG_PROTOCOL_LATEST PG_PROTOCOL(2,1) /* * All packets sent to the postmaster start with the length. This is omitted *************** *** 127,137 **** /* These are the authentication requests sent by the backend. */ ! #define AUTH_REQ_OK 0 /* User is authenticated */ #define AUTH_REQ_KRB4 1 /* Kerberos V4 */ #define AUTH_REQ_KRB5 2 /* Kerberos V5 */ #define AUTH_REQ_PASSWORD 3 /* Password */ ! #define AUTH_REQ_CRYPT 4 /* Encrypted password */ typedef uint32 AuthRequest; --- 127,138 ---- /* These are the authentication requests sent by the backend. */ ! #define AUTH_REQ_OK 0 /* User is authenticated */ #define AUTH_REQ_KRB4 1 /* Kerberos V4 */ #define AUTH_REQ_KRB5 2 /* Kerberos V5 */ #define AUTH_REQ_PASSWORD 3 /* Password */ ! #define AUTH_REQ_CRYPT 4 /* crypt password */ ! #define AUTH_REQ_MD5 5 /* md5 password */ typedef uint32 AuthRequest; Index: src/interfaces/libpq/Makefile =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/Makefile,v retrieving revision 1.53 diff -c -r1.53 Makefile *** src/interfaces/libpq/Makefile 2001/07/15 13:45:04 1.53 --- src/interfaces/libpq/Makefile 2001/08/15 05:13:05 *************** *** 20,26 **** override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"' OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ ! pqexpbuffer.o dllist.o pqsignal.o \ $(INET_ATON) $(SNPRINTF) $(STRERROR) ifdef MULTIBYTE --- 20,26 ---- override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"' OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ ! pqexpbuffer.o dllist.o md5.o pqsignal.o \ $(INET_ATON) $(SNPRINTF) $(STRERROR) ifdef MULTIBYTE *************** *** 33,39 **** SHLIB_LINK += $(filter -L%, $(LDFLAGS)) $(filter -lcrypt -ldes -lkrb -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl, $(LIBS)) ! all: all-lib # Shared library stuff include $(top_srcdir)/src/Makefile.shlib --- 33,39 ---- SHLIB_LINK += $(filter -L%, $(LDFLAGS)) $(filter -lcrypt -ldes -lkrb -lcom_err -lcrypto -lk5crypto -lkrb5 -lssl -lsocket -lnsl -lresolv -lintl, $(LIBS)) ! all: md5.c md5.h all-lib # Shared library stuff include $(top_srcdir)/src/Makefile.shlib *************** *** 49,54 **** --- 49,60 ---- dllist.c: $(backend_src)/lib/dllist.c rm -f $@ && $(LN_S) $< . + md5.c: $(backend_src)/libpq/md5.c + rm -f $@ && $(LN_S) $< . + + md5.h: $(backend_src)/../include/libpq/md5.h + rm -f $@ && $(LN_S) $< . + # this only gets done if configure finds system doesn't have inet_aton() inet_aton.c: $(backend_src)/port/inet_aton.c rm -f $@ && $(LN_S) $< . *************** *** 82,88 **** rm -f $(addprefix $(DESTDIR)$(includedir)/, libpq-fe.h libpq-int.h pqexpbuffer.h) clean distclean maintainer-clean: clean-lib ! rm -f $(OBJS) dllist.c wchar.c rm -f $(OBJS) inet_aton.c snprintf.c strerror.c depend dep: --- 88,94 ---- rm -f $(addprefix $(DESTDIR)$(includedir)/, libpq-fe.h libpq-int.h pqexpbuffer.h) clean distclean maintainer-clean: clean-lib ! rm -f $(OBJS) dllist.c md5.c md5.h wchar.c rm -f $(OBJS) inet_aton.c snprintf.c strerror.c depend dep: Index: src/interfaces/libpq/fe-auth.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v retrieving revision 1.48 diff -c -r1.48 fe-auth.c *** src/interfaces/libpq/fe-auth.c 2001/07/15 13:45:04 1.48 --- src/interfaces/libpq/fe-auth.c 2001/08/15 05:13:05 *************** *** 33,38 **** --- 33,39 ---- #include "libpq-fe.h" #include "libpq-int.h" #include "fe-auth.h" + #include "md5.h" #ifdef WIN32 #include "win32.h" *************** *** 434,445 **** static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq) { /* Encrypt the password if needed. */ ! if (areq == AUTH_REQ_CRYPT) ! password = crypt(password, conn->salt); ! return pqPacketSend(conn, password, strlen(password) + 1); } /* --- 435,486 ---- static int pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq) { + int ret; + char *crypt_pwd; + /* Encrypt the password if needed. */ ! switch (areq) ! { ! case AUTH_REQ_CRYPT: ! crypt_pwd = crypt(password, conn->salt); ! break; ! case AUTH_REQ_MD5: ! { ! char *crypt_pwd2; ! if (!(crypt_pwd = malloc(MD5_PASSWD_LEN+1)) || ! !(crypt_pwd2 = malloc(MD5_PASSWD_LEN+1))) ! { ! perror("malloc"); ! return STATUS_ERROR; ! } ! if (!EncryptMD5(password, conn->pguser, crypt_pwd2)) ! { ! free(crypt_pwd); ! free(crypt_pwd2); ! return STATUS_ERROR; ! } ! if (!EncryptMD5(crypt_pwd2 + strlen("md5"), conn->salt, ! crypt_pwd)) ! { ! free(crypt_pwd); ! free(crypt_pwd2); ! return STATUS_ERROR; ! } ! free(crypt_pwd2); ! break; ! } ! default: ! /* discard const so we can assign it */ ! crypt_pwd = (char *)password; ! break; ! } ! ! ret = pqPacketSend(conn, crypt_pwd, strlen(crypt_pwd) + 1); ! if (areq == AUTH_REQ_MD5) ! free(crypt_pwd); ! return ret; } /* *************** *** 494,499 **** --- 535,541 ---- case AUTH_REQ_PASSWORD: case AUTH_REQ_CRYPT: + case AUTH_REQ_MD5: if (password == NULL || *password == '\0') { (void) sprintf(PQerrormsg, *************** *** 506,514 **** "fe_sendauth: error sending password authentication\n"); return STATUS_ERROR; } - break; - default: snprintf(PQerrormsg, PQERRORMSG_LENGTH, libpq_gettext("authentication method %u not supported\n"), areq); --- 548,554 ---- Index: src/interfaces/libpq/fe-connect.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v retrieving revision 1.172 diff -c -r1.172 fe-connect.c *** src/interfaces/libpq/fe-connect.c 2001/08/03 22:11:39 1.172 --- src/interfaces/libpq/fe-connect.c 2001/08/15 05:13:06 *************** *** 1341,1347 **** } /* Get the password salt if there is one. */ ! if (areq == AUTH_REQ_CRYPT) { if (pqGetnchar(conn->salt, sizeof(conn->salt), conn)) { --- 1341,1347 ---- } /* Get the password salt if there is one. */ ! if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5) { if (pqGetnchar(conn->salt, sizeof(conn->salt), conn)) { *************** *** 1960,1966 **** closePGconn(PGconn *conn) { /* Note that the protocol doesn't allow us to send Terminate ! messages during the startup phase. */ if (conn->sock >= 0 && conn->status == CONNECTION_OK) { --- 1960,1966 ---- closePGconn(PGconn *conn) { /* Note that the protocol doesn't allow us to send Terminate ! messages during the startup phase. */ if (conn->sock >= 0 && conn->status == CONNECTION_OK) { Index: src/interfaces/libpq/fe-exec.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v retrieving revision 1.105 diff -c -r1.105 fe-exec.c *** src/interfaces/libpq/fe-exec.c 2001/08/03 22:11:39 1.105 --- src/interfaces/libpq/fe-exec.c 2001/08/15 05:13:13 *************** *** 1269,1275 **** static int getNotice(PGconn *conn) { - /* * Since the Notice might be pretty long, we create a temporary * PQExpBuffer rather than using conn->workBuffer. workBuffer is --- 1269,1274 ---- Index: src/interfaces/libpq/libpq-int.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/libpq/libpq-int.h,v retrieving revision 1.36 diff -c -r1.36 libpq-int.h *** src/interfaces/libpq/libpq-int.h 2001/07/15 13:45:04 1.36 --- src/interfaces/libpq/libpq-int.h 2001/08/15 05:13:13 *************** *** 45,51 **** * pqcomm.h describe what the backend knows, not what libpq knows. */ ! #define PG_PROTOCOL_LIBPQ PG_PROTOCOL(2,0) /* * POSTGRES backend dependent Constants. --- 45,51 ---- * pqcomm.h describe what the backend knows, not what libpq knows. */ ! #define PG_PROTOCOL_LIBPQ PG_PROTOCOL(2,1) /* * POSTGRES backend dependent Constants. Index: src/interfaces/odbc/connection.c =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/connection.c,v retrieving revision 1.32 diff -c -r1.32 connection.c *** src/interfaces/odbc/connection.c 2001/06/19 02:17:06 1.32 --- src/interfaces/odbc/connection.c 2001/08/15 05:13:14 *************** *** 677,683 **** mylog("auth got 'R'\n"); areq = SOCK_get_int(sock, 4); ! if (areq == AUTH_REQ_CRYPT) SOCK_get_n_char(sock, salt, 2); mylog("areq = %d\n", areq); --- 677,683 ---- mylog("auth got 'R'\n"); areq = SOCK_get_int(sock, 4); ! if (areq == AUTH_REQ_CRYPT || areq == AUTH_REQ_MD5) SOCK_get_n_char(sock, salt, 2); mylog("areq = %d\n", areq); *************** *** 717,722 **** --- 717,723 ---- break; case AUTH_REQ_CRYPT: + case AUTH_REQ_MD5: self->errormsg = "Password crypt authentication not supported"; self->errornumber = CONN_AUTH_TYPE_UNSUPPORTED; return 0; *************** *** 1672,1686 **** int CC_get_max_query_len(const ConnectionClass *conn) { ! int value; ! /* Long Queries in 7.0+ */ ! if (PG_VERSION_GE(conn, 7.0)) ! value = 0 /* MAX_STATEMENT_LEN */; ! /* Prior to 7.0 we used 2*BLCKSZ */ ! else if (PG_VERSION_GE(conn, 6.5)) ! value = (2 * BLCKSZ); ! else ! /* Prior to 6.5 we used BLCKSZ */ ! value = BLCKSZ; ! return value; } --- 1673,1687 ---- int CC_get_max_query_len(const ConnectionClass *conn) { ! int value; ! /* Long Queries in 7.0+ */ ! if (PG_VERSION_GE(conn, 7.0)) ! value = 0 /* MAX_STATEMENT_LEN */; ! /* Prior to 7.0 we used 2*BLCKSZ */ ! else if (PG_VERSION_GE(conn, 6.5)) ! value = (2 * BLCKSZ); ! else ! /* Prior to 6.5 we used BLCKSZ */ ! value = BLCKSZ; ! return value; } Index: src/interfaces/odbc/connection.h =================================================================== RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/connection.h,v retrieving revision 1.24 diff -c -r1.24 connection.h *** src/interfaces/odbc/connection.h 2001/05/30 20:52:34 1.24 --- src/interfaces/odbc/connection.h 2001/08/15 05:13:14 *************** *** 93,98 **** --- 93,99 ---- #define AUTH_REQ_KRB5 2 #define AUTH_REQ_PASSWORD 3 #define AUTH_REQ_CRYPT 4 + #define AUTH_REQ_MD5 5 /* Startup Packet sizes */ #define SM_DATABASE 64