# Makefile for commands
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.7 1997/11/24 05:20:49 momjian Exp $
+# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.8 1997/12/04 00:26:44 scrappy Exp $
#
#-------------------------------------------------------------------------
OBJS = async.o creatinh.o command.o copy.o defind.o define.o \
remove.o rename.o vacuum.o version.o view.o cluster.o \
- recipe.o explain.o sequence.o trigger.o proclang.o dbcommands.o
+ recipe.o explain.o sequence.o trigger.o user.o proclang.o dbcommands.o
all: SUBSYS.o
# Makefile for libpq subsystem (backend half of libpq interface)
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.7 1997/04/04 10:39:19 scrappy Exp $
+# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.8 1997/12/04 00:26:47 scrappy Exp $
#
#-------------------------------------------------------------------------
endif
OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o pqcomprim.o\
- auth.o hba.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o \
+ auth.o hba.o crypt.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o \
password.o
all: SUBSYS.o
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.18 1997/11/17 16:10:06 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.19 1997/12/04 00:26:50 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <libpq/libpq-be.h>
#include <libpq/hba.h>
#include <libpq/password.h>
+#include <libpq/crypt.h>
static int be_getauthsvc(MsgType msgtype);
#else
{"kerberos", STARTUP_KRB4_MSG, 1},
#endif
- {"password", STARTUP_PASSWORD_MSG, 1}
+ {"password", STARTUP_PASSWORD_MSG, 1},
+ {"crypt", STARTUP_CRYPT_MSG, 1}
};
static n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
return verify_password(user, password, port, database, DataDir);
}
+static int
+crypt_recvauth(Port *port)
+{
+ PacketBuf buf;
+ char *user,
+ *password;
+
+ if (PacketReceive(port, &buf, BLOCKING) != STATUS_OK)
+ {
+ sprintf(PQerrormsg,
+ "crypt_recvauth: failed to receive authentication packet.\n");
+ fputs(PQerrormsg, stderr);
+ pqdebug("%s", PQerrormsg);
+ return STATUS_ERROR;
+ }
+
+ user = buf.data;
+ password = buf.data + strlen(user) + 1;
+
+ return crypt_verify(port, user, password);
+}
+
/*
* be_recvauth -- server demux routine for incoming authentication information
*/
return (STATUS_ERROR);
}
break;
+ case STARTUP_CRYPT_MSG:
+ if (crypt_recvauth(port) != STATUS_OK)
+ return STATUS_ERROR;
+ break;
default:
sprintf(PQerrormsg,
"be_recvauth: unrecognized message type: %d\n",
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.75 1997/12/02 16:09:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.76 1997/12/04 00:26:57 scrappy Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
#include "nodes/print.h"
#include "parser/gramparse.h"
#include "utils/acl.h"
+#include "utils/palloc.h"
#include "catalog/catname.h"
#include "utils/elog.h"
#include "access/xact.h"
char chr;
char *str;
bool boolean;
+ bool* pboolean; /* for pg_user privileges */
List *list;
Node *node;
Value *value;
RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
- ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
+ ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
+ CreateUserStmt, AlterUserStmt, DropUserStmt
%type <str> opt_database, location
+%type <pboolean> user_createdb_clause, user_createuser_clause
+%type <str> user_passwd_clause
+%type <str> user_valid_clause
+%type <list> user_group_list, user_group_clause
+
%type <node> SubSelect
%type <str> join_expr, join_outer, join_spec
%type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
VACUUM, VERBOSE, VERSION
+/*
+ * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
+ * when some sort of pg_privileges relation is introduced.
+ *
+ * Todd A. Brandys
+ */
+%token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
+
/* Special keywords, not in the query language - see the "lex" file */
%token <str> IDENT, SCONST, Op
%token <ival> ICONST, PARAM
;
stmt : AddAttrStmt
+ | AlterUserStmt
| ClosePortalStmt
| CopyStmt
| CreateStmt
| CreateSeqStmt
| CreatePLangStmt
| CreateTrigStmt
+ | CreateUserStmt
| ClusterStmt
| DefineStmt
| DestroyStmt
| DropPLangStmt
| DropTrigStmt
+ | DropUserStmt
| ExtendStmt
| ExplainStmt
| FetchStmt
| VariableResetStmt
;
+/*****************************************************************************
+ *
+ * Create a new postresql DBMS user
+ *
+ *
+ *****************************************************************************/
+
+CreateUserStmt: CREATE USER Id
+ user_passwd_clause
+ user_createdb_clause
+ user_createuser_clause
+ user_group_clause
+ user_valid_clause
+ { CreateUserStmt *n = makeNode(CreateUserStmt);
+ n->user = $3;
+ n->password = $4;
+ n->createdb = $5;
+ n->createuser = $6;
+ n->groupElts = $7;
+ n->validUntil = $8;
+ $$ = (Node *)n;
+ }
+ ;
+
+/*****************************************************************************
+ *
+ * Alter a postresql DBMS user
+ *
+ *
+ *****************************************************************************/
+
+AlterUserStmt: ALTER USER Id
+ user_passwd_clause
+ user_createdb_clause
+ user_createuser_clause
+ user_group_clause
+ user_valid_clause
+ { AlterUserStmt *n = makeNode(AlterUserStmt);
+ n->user = $3;
+ n->password = $4;
+ n->createdb = $5;
+ n->createuser = $6;
+ n->groupElts = $7;
+ n->validUntil = $8;
+ $$ = (Node *)n;
+ }
+ ;
+
+/*****************************************************************************
+ *
+ * Drop a postresql DBMS user
+ *
+ *
+ *****************************************************************************/
+
+DropUserStmt: DROP USER Id
+ { DropUserStmt *n = makeNode(DropUserStmt);
+ n->user = $3;
+ $$ = (Node *)n;
+ }
+ ;
+
+user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+user_createdb_clause: CREATEDB { bool* b;
+ $$ = (b = (bool*)palloc(sizeof(bool)));
+ *b = true;
+ }
+ | NOCREATEDB { bool* b;
+ $$ = (b = (bool*)palloc(sizeof(bool)));
+ *b = false;
+ }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+user_createuser_clause: CREATEUSER { bool* b;
+ $$ = (b = (bool*)palloc(sizeof(bool)));
+ *b = true;
+ }
+ | NOCREATEUSER { bool* b;
+ $$ = (b = (bool*)palloc(sizeof(bool)));
+ *b = false;
+ }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+user_group_list: user_group_list ',' Id { $$ = lcons((void*)makeString($3), $1); }
+ | Id { $$ = makeList((void*)makeString($1), NULL); }
+ ;
+
+user_group_clause: IN GROUP user_group_list { $$ = $3; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
+user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
/*****************************************************************************
*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.26 1997/11/26 01:11:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.27 1997/12/04 00:27:04 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
{"constraint", CONSTRAINT},
{"copy", COPY},
{"create", CREATE},
+ {"createdb", CREATEDB},
+ {"createuser", CREATEUSER},
{"cross", CROSS},
{"current", CURRENT},
{"current_date", CURRENT_DATE},
{"natural", NATURAL},
{"nchar", NCHAR},
{"new", NEW},
+ {"nocreatedb", NOCREATEDB},
+ {"nocreateuser", NOCREATEUSER},
{"none", NONE},
{"no", NO},
{"not", NOT},
{"order", ORDER},
{"outer", OUTER_P},
{"partial", PARTIAL},
+ {"password", PASSWORD},
{"position", POSITION},
{"precision", PRECISION},
{"primary", PRIMARY},
{"type", TYPE_P},
{"union", UNION},
{"unique", UNIQUE},
+ {"until", UNTIL},
{"update", UPDATE},
+ {"user", USER},
{"using", USING},
{"vacuum", VACUUM},
+ {"valid", VALID},
{"values", VALUES},
{"varchar", VARCHAR},
{"varying", VARYING},
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.62 1997/11/17 03:47:28 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.63 1997/12/04 00:27:17 scrappy Exp $
*
* NOTES
*
#include <signal.h>
#include <string.h>
#include <stdlib.h>
+#include <time.h>
#if !defined(NO_UNISTD_H)
#include <unistd.h>
#include "libpq/auth.h"
#include "libpq/pqcomm.h"
#include "libpq/pqsignal.h"
+#include "libpq/crypt.h"
#include "miscadmin.h"
#include "version.h"
#include "lib/dllist.h"
static int ServerLoop(void);
static int BackendStartup(StartupInfo *packet, Port *port, int *pidPtr);
static void send_error_reply(Port *port, const char *errormsg);
+static void RandomSalt(char* salt);
extern char *optarg;
extern int optind,
switch (status)
{
case STATUS_OK:
- {
+ /* Here is where we check for a USER login packet. If there is one, then
+ * we must deterine whether the login has a password in pg_user. If so, send
+ * back a salt to crypt() the password with. Otherwise, send an unsalt packet
+ * back and read the real startup packet.
+ */
+ if (ntohl(port->buf.msgtype) == STARTUP_USER_MSG) {
+ PacketLen plen;
+
+ port->buf.msgtype = htonl(crypt_salt(port->buf.data));
+ plen = sizeof(port->buf.len) + sizeof(port->buf.msgtype) + 2;
+ port->buf.len = htonl(plen);
+ RandomSalt(port->salt);
+ memcpy((void*)port->buf.data, (void*)port->salt, 2);
+
+ status = PacketSend(port, &port->buf, plen, BLOCKING);
+ if (status != STATUS_OK)
+ break;
+
+ /* port->nBytes = 0; */
+ continue;
+ } else {
int CSstatus; /* Completion status of
* ConnStartup */
char errormsg[200]; /* error msg from
curr = DLGetSucc(curr);
}
}
+
+/*
+ * CharRemap
+ */
+static char
+CharRemap(long int ch) {
+
+ if (ch < 0)
+ ch = -ch;
+
+ ch = ch % 62;
+ if (ch < 26)
+ return ('A' + ch);
+
+ ch -= 26;
+ if (ch < 26)
+ return ('a' + ch);
+
+ ch -= 26;
+ return ('0' + ch);
+}
+
+/*
+ * RandomSalt
+ */
+static void
+RandomSalt(char* salt) {
+
+ static bool initialized = false;
+
+ if (!initialized) {
+ time_t now;
+
+ now = time(NULL);
+ srandom((unsigned int)now);
+ initialized = true;
+ }
+
+ *salt = CharRemap(random());
+ *(salt + 1) = CharRemap(random());
+}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.31 1997/11/24 05:32:40 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.32 1997/12/04 00:27:24 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
DropProceduralLanguage((DropPLangStmt *) parsetree);
break;
+ /*
+ * ******************************** USER statements ****
+ *
+ */
+ case T_CreateUserStmt:
+ commandTag = "CREATE USER";
+ CHECK_IF_ABORTED();
+
+ DefineUser((CreateUserStmt*)parsetree);
+ break;
+
+ case T_AlterUserStmt:
+ commandTag = "ALTER USER";
+ CHECK_IF_ABORTED();
+
+ AlterUser((AlterUserStmt*)parsetree);
+ break;
+
+ case T_DropUserStmt:
+ commandTag = "DROP USER";
+ CHECK_IF_ABORTED();
+
+ RemoveUser(((DropUserStmt*)parsetree)->user);
+ break;
+
+
/*
* ******************************** default ********************************
*
#
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.29 1997/11/16 04:36:14 momjian Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.30 1997/12/04 00:27:31 scrappy Exp $
#
#-------------------------------------------------------------------------
echo "vacuum" | postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\
grep -v "^DEBUG:"
+echo "Altering pg_user acl"
+echo "REVOKE ALL ON pg_user FROM public" | postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\
+ grep -v "'DEBUG:"
+
+echo "COPY pg_user TO '$PGDATA/pg_pwd' USING DELIMITERS '#'" | postgres -F -Q -D$PGDATA template1 2>&1 > /dev/null |\
+ grep -v "'DEBUG:"
+
echo "loading pg_description"
echo "copy pg_description from '$TEMPLATE_DESCR'" | postgres -F -Q -D$PGDATA template1 > /dev/null
echo "copy pg_description from '$GLOBAL_DESCR'" | postgres -F -Q -D$PGDATA template1 > /dev/null
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: psqlHelp.h,v 1.33 1997/11/21 18:11:46 momjian Exp $
+ * $Id: psqlHelp.h,v 1.34 1997/12/04 00:27:37 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
{"alter table",
"add/rename attributes, rename tables",
"\talter table <class_name> [*] add column <attr> <type>;\n\talter table <class_name> [*] rename [column] <attr1> to <attr2>;\n\talter table <class_name1> rename to <class_name2>"},
+ {"alter user",
+ "alter system information for a user",
+ "alter user <user_name>\n\t[with password <password>]\n\t[createdb | noccreatedb]\n\t[createuser | nocreateuser]\n\t[in group <group_1>, ..., <group_n>]\n\t[valid until '<abstime>'];"},
{"begin",
"begin a new transaction",
"begin [transaction|work];"},
{"create type",
"create a new user-defined base data type",
"create type <typename> (\n\tinternallength = (<number> | variable),\n\t[externallength = (<number>|variable),]\n\tinput=<input_function>, output = <output_function>\n\t[,element = <typename>][,delimiter=<character>][,default=\'<string>\']\n\t[,send = <send_function>][,receive = <receive_function>][,passedbyvalue]);"},
+ {"create user",
+ "create a new user",
+ "create user <user_name>\n\t[with password <password>]\n\t[createdb | nocreatedb]\n\t[createuser | nocreateuser]\n\t[in group <group_1>, ..., <group_n>]\n\t[valid until '<abstime>'];"},
{"create view",
"create a view",
"create view <view_name> as select <expr1>[as <attr1>][,... <exprN>[as <attrN>]] [from <from_list>] [where <qual>];"},
{"drop type",
"remove a user-defined base type",
"drop type <typename>;"},
+ {"drop user",
+ "remove a user from the system",
+ "drop user <user_name>;"},
{"drop view",
"remove a view",
"drop view <view_name>"},
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_attribute.h,v 1.20 1997/11/21 18:12:01 momjian Exp $
+ * $Id: pg_attribute.h,v 1.21 1997/12/04 00:27:47 scrappy Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
* pg_user
* ----------------
*/
-DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 f f i f f));
-DATA(insert OID = 0 ( 1260 usesysid 23 0 4 2 0 -1 t f s f f));
-DATA(insert OID = 0 ( 1260 usecreatedb 16 0 1 3 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usetrace 16 0 1 4 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usesuper 16 0 1 5 0 -1 t f c f f));
-DATA(insert OID = 0 ( 1260 usecatupd 16 0 1 6 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usename 19 0 NAMEDATALEN 1 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 usesysid 23 0 4 2 0 -1 t f s f f));
+DATA(insert OID = 0 ( 1260 usecreatedb 16 0 1 3 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usetrace 16 0 1 4 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usesuper 16 0 1 5 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 usecatupd 16 0 1 6 0 -1 t f c f f));
+DATA(insert OID = 0 ( 1260 passwd 25 0 -1 7 0 -1 f f i f f));
+DATA(insert OID = 0 ( 1260 valuntil 702 0 4 8 0 -1 t f i f f));
DATA(insert OID = 0 ( 1260 ctid 27 0 6 -1 0 -1 f f i f f));
DATA(insert OID = 0 ( 1260 oid 26 0 4 -2 0 -1 t f i f f));
DATA(insert OID = 0 ( 1260 xmin 28 0 4 -3 0 -1 f f i f f));
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_class.h,v 1.16 1997/11/21 18:12:07 momjian Exp $
+ * $Id: pg_class.h,v 1.17 1997/12/04 00:27:50 scrappy Exp $
*
* NOTES
* ``pg_relation'' is being replaced by ``pg_class''. currently
DESCR("");
DATA(insert OID = 1259 ( pg_class 83 PGUID 0 0 0 f f r 18 0 0 f _null_ ));
DESCR("");
-DATA(insert OID = 1260 ( pg_user 86 PGUID 0 0 0 f t r 6 0 0 f _null_ ));
+DATA(insert OID = 1260 ( pg_user 86 PGUID 0 0 0 f t r 8 0 0 f _null_ ));
DESCR("");
DATA(insert OID = 1261 ( pg_group 87 PGUID 0 0 0 f t s 3 0 0 f _null_ ));
DESCR("");
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_user.h,v 1.5 1997/09/08 02:35:34 momjian Exp $
+ * $Id: pg_user.h,v 1.6 1997/12/04 00:27:54 scrappy Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
bool usetrace;
bool usesuper;
bool usecatupd;
+ text passwd;
+ int4 valuntil;
} FormData_pg_user;
/* ----------------
* compiler constants for pg_user
* ----------------
*/
-#define Natts_pg_user 6
+#define Natts_pg_user 8
#define Anum_pg_user_usename 1
#define Anum_pg_user_usesysid 2
#define Anum_pg_user_usecreatedb 3
#define Anum_pg_user_usetrace 4
#define Anum_pg_user_usesuper 5
#define Anum_pg_user_usecatupd 6
+#define Anum_pg_user_passwd 7
+#define Anum_pg_user_valuntil 8
/* ----------------
* initial contents of pg_user
* ----------------
*/
-DATA(insert OID = 0 ( postgres PGUID t t t t ));
+DATA(insert OID = 0 ( postgres PGUID t t t t postgres 2116994400 ));
BKI_BEGIN
#ifdef ALLOW_PG_GROUP
BKI_END
-DATA(insert OID = 0 ( mike 799 t t t t ));
-DATA(insert OID = 0 ( mao 1806 t t t t ));
-DATA(insert OID = 0 ( hellers 1089 t t t t ));
-DATA(insert OID = 0 ( joey 5209 t t t t ));
-DATA(insert OID = 0 ( jolly 5443 t t t t ));
-DATA(insert OID = 0 ( sunita 6559 t t t t ));
-DATA(insert OID = 0 ( paxson 3029 t t t t ));
-DATA(insert OID = 0 ( marc 2435 t t t t ));
-DATA(insert OID = 0 ( jiangwu 6124 t t t t ));
-DATA(insert OID = 0 ( aoki 2360 t t t t ));
-DATA(insert OID = 0 ( avi 31080 t t t t ));
-DATA(insert OID = 0 ( kristin 1123 t t t t ));
-DATA(insert OID = 0 ( andrew 5229 t t t t ));
-DATA(insert OID = 0 ( nobuko 5493 t t t t ));
-DATA(insert OID = 0 ( hartzell 6676 t t t t ));
-DATA(insert OID = 0 ( devine 6724 t t t t ));
-DATA(insert OID = 0 ( boris 6396 t t t t ));
-DATA(insert OID = 0 ( sklower 354 t t t t ));
-DATA(insert OID = 0 ( marcel 31113 t t t t ));
-DATA(insert OID = 0 ( ginger 3692 t t t t ));
-DATA(insert OID = 0 ( woodruff 31026 t t t t ));
-DATA(insert OID = 0 ( searcher 8261 t t t t ));
+DATA(insert OID = 0 ( mike 799 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( mao 1806 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( hellers 1089 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( joey 5209 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( jolly 5443 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( sunita 6559 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( paxson 3029 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( marc 2435 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( jiangwu 6124 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( aoki 2360 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( avi 31080 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( kristin 1123 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( andrew 5229 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( nobuko 5493 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( hartzell 6676 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( devine 6724 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( boris 6396 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( sklower 354 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( marcel 31113 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( ginger 3692 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( woodruff 31026 t t t t _null_ 2116994400 ));
+DATA(insert OID = 0 ( searcher 8261 t t t t _null_ 2116994400 ));
BKI_BEGIN
#endif /* ALLOW_PG_GROUP */
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.h,v 1.16 1997/11/07 20:52:06 momjian Exp $
+ * $Id: pqcomm.h,v 1.17 1997/12/04 00:27:56 scrappy Exp $
*
* NOTES
* Some of this should move to libpq.h
STARTUP_KRB5_MSG = 11, /* krb5 session follows startup packet */
STARTUP_HBA_MSG = 12, /* use host-based authentication */
STARTUP_UNAUTH_MSG = 13, /* use unauthenticated connection */
- STARTUP_PASSWORD_MSG = 14 /* use plaintext password authentication */
+ STARTUP_PASSWORD_MSG = 14, /* use plaintext password authentication */
+ /* The following three are not really a named authentication method
+ * since the front end has no choice in choosing the method. The
+ * backend sends the SALT/UNSALT messages back to the frontend after
+ * the USER login has been given to the backend.
+ */
+ STARTUP_CRYPT_MSG = 15, /* use crypt()'ed password authentication */
+ STARTUP_USER_MSG = 16, /* send user name to check pg_user for password */
+ STARTUP_SALT_MSG = 17, /* frontend should crypt the password it sends */
+ STARTUP_UNSALT_MSG = 18 /* frontend should NOT crypt the password it sends */
/* insert new values here -- DO NOT REORDER OR DELETE ENTRIES */
/* also change LAST_AUTHENTICATION_TYPE below and add to the */
/* authentication_type_name[] array in pqcomm.c */
* PacketBufId id;
*//* id of packet buf currently in use */
PacketBuf buf; /* stream implementation (curr pack buf) */
+ char salt[2];
} Port;
/* invalid socket descriptor */
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.17 1997/11/21 18:12:25 momjian Exp $
+ * $Id: nodes.h,v 1.18 1997/12/04 00:28:01 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
T_DropTrigStmt,
T_CreatePLangStmt,
T_DropPLangStmt,
+ T_CreateUserStmt,
+ T_AlterUserStmt,
+ T_DropUserStmt,
T_A_Expr = 700,
T_Attr,
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.35 1997/11/24 05:09:50 momjian Exp $
+ * $Id: parsenodes.h,v 1.36 1997/12/04 00:28:03 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
} DropPLangStmt;
+/* ----------------------
+ * Create/Alter/Drop User Statements
+ * ----------------------
+ */
+typedef struct CreateUserStmt
+{
+ NodeTag type;
+ char* user; /* PostgreSQL user login */
+ char* password; /* PostgreSQL user password */
+ bool* createdb; /* Can the user create databases? */
+ bool* createuser; /* Can this user create users? */
+ List* groupElts; /* The groups the user is a member of */
+ char* validUntil; /* The time the login is valid until */
+} CreateUserStmt;
+
+typedef CreateUserStmt AlterUserStmt;
+
+typedef struct DropUserStmt
+{
+ NodeTag type;
+ char* user; /* PostgreSQL user login */
+} DropUserStmt;
+
+
/* ----------------------
* Create SEQUENCE Statement
* ----------------------
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.11 1997/09/08 21:55:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.12 1997/12/04 00:28:08 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
case STARTUP_MSG:
break;
case STARTUP_PASSWORD_MSG:
+ case STARTUP_CRYPT_MSG:
pg_password_sendauth(port, user, password);
default:
break;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.49 1997/12/01 22:02:46 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.50 1997/12/04 00:28:11 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef HAVE_STRDUP
#include "strdup.h"
#endif
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
/* use a local version instead of the one found in pqpacket.c */
}
/* ----------------
- * PQsetdb
+ * PQsetdbLogin
*
* establishes a connection to a postgres backend through the postmaster
* at the specified host and port.
* ----------------
*/
PGconn *
-PQsetdb(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName)
+PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd)
{
PGconn *conn;
char *tmp;
else
conn->pgoptions = strdup(pgoptions);
- if ((tmp = getenv("PGUSER")) != NULL)
+ if (login)
+ {
+ error = FALSE;
+ conn->pguser = strdup(login);
+ }
+ else if ((tmp = getenv("PGUSER")) != NULL)
{
error = FALSE;
conn->pguser = strdup(tmp);
}
}
- if ((tmp = getenv("PGPASSWORD")) != NULL)
+ if (pwd)
+ {
+ conn->pgpass = strdup(pwd);
+ }
+ else if ((tmp = getenv("PGPASSWORD")) != NULL)
+ {
conn->pgpass = strdup(tmp);
+ }
else
conn->pgpass = 0;
StartupInfo startup;
PacketBuf pacBuf;
+ PacketLen pacLen;
int status;
MsgType msgtype;
int laddrlen = sizeof(struct sockaddr);
int portno,
family,
len;
+ bool salted = false;
+ char* tmp;
/*
* Initialize the startup packet.
}
/* by this point, connection has been opened */
- msgtype = fe_getauthsvc(conn->errorMessage);
+
+ /* This section of code is new as of Nov 19, 1997. It sends just the
+ * user's login to the backend. This allows the backend to search
+ * pg_user to see if the user has a password defined. If the user
+ * does have a password in pg_user, then the backend will send a
+ * packet back with a randomly generated salt, so the user's password
+ * can be encrypted.
+ */
+ pacLen = sizeof(pacBuf.len) + sizeof(pacBuf.msgtype) + strlen(startup.user) + 1;
+ pacBuf.len = htonl(pacLen);
+ pacBuf.msgtype = htonl(STARTUP_USER_MSG);
+ strcpy(pacBuf.data, startup.user);
+ status = packetSend(port, &pacBuf, pacLen, BLOCKING);
+ if (status == STATUS_ERROR) {
+ sprintf(conn->errorMessage, "connectDB() -- couldn't send complete packet: errno=%d\n%s\n", errno, strerror(errno));
+ goto connect_errReturn;
+ }
+
+ /* Check to see if the server sent us a salt back to encrypt the
+ * password to send for authentication. --TAB
+ */
+ status = packetReceive(port, &pacBuf, BLOCKING);
+
+ if (status != STATUS_OK) {
+ sprintf(conn->errorMessage, "connectDB() -- couldn't receive un/salt packet: errno=%d\n%s\n", errno, strerror(errno));
+ goto connect_errReturn;
+ }
+ pacBuf.msgtype = ntohl(pacBuf.msgtype);
+ switch (pacBuf.msgtype) {
+ case STARTUP_SALT_MSG:
+ salted = true;
+ if (!conn->pgpass) {
+ sprintf(conn->errorMessage, "connectDB() -- backend requested a password, but none was given\n");
+ goto connect_errReturn;
+ }
+ tmp = crypt(conn->pgpass, pacBuf.data);
+ free((void*)conn->pgpass);
+ conn->pgpass = strdup(tmp);
+ break;
+ case STARTUP_UNSALT_MSG:
+ salted = false;
+ break;
+ default:
+ sprintf(conn->errorMessage, "connectDB() -- backend did not supply a salt packet\n");
+ goto connect_errReturn;
+ }
+
+ if (salted)
+ msgtype = STARTUP_CRYPT_MSG;
+ else
+ msgtype = fe_getauthsvc(conn->errorMessage);
/* pacBuf = startup2PacketBuf(&startup);*/
startup2PacketBuf(&startup, &pacBuf);
return (STATUS_OK);
}
+/*
+ * packetReceive()
+ *
+ This is a less stringent PacketReceive(), defined in backend/libpq/pqpacket.c
+ We define it here to avoid linking in all of libpq.a
+
+ * packetReceive -- receive a packet on a port
+ *
+ * RETURNS: STATUS_ERROR if the read fails, STATUS_OK otherwise.
+ * SIDE_EFFECTS: may block.
+ * NOTES: Non-blocking reads would significantly complicate
+ * buffer management. For now, we're not going to do it.
+ *
+*/
+int
+packetReceive(Port *port, PacketBuf *buf, bool nonBlocking) {
+
+ PacketLen max_size = sizeof(PacketBuf);
+ PacketLen cc; /* character count -- recvd */
+ PacketLen packetLen;
+ int addrLen = sizeof(struct sockaddr_in);
+ int hdrLen;
+ int msgLen;
+
+ /* Read the packet length into the PacketBuf
+ */
+ hdrLen = sizeof(PacketLen);
+ cc = recvfrom(port->sock, (char*)&packetLen, hdrLen, 0, (struct sockaddr*)&port->raddr, &addrLen);
+ if (cc < 0)
+ return STATUS_ERROR;
+ else if (!cc)
+ return STATUS_INVALID;
+ else if (cc < hdrLen)
+ return STATUS_NOT_DONE;
+
+ /* convert to local form of integer and check for oversized packet
+ */
+ buf->len = packetLen;
+ if ((packetLen = ntohl(packetLen)) > max_size) {
+ port->nBytes = packetLen;
+ return STATUS_INVALID;
+ }
+
+ /* fetch the rest of the message
+ */
+ msgLen = packetLen - cc;
+ cc = recvfrom(port->sock, (char*)&buf->msgtype, msgLen, 0, (struct sockaddr*)&port->raddr, &addrLen);
+ if (cc < 0)
+ return STATUS_ERROR;
+ else if (!cc)
+ return STATUS_INVALID;
+ else if (cc < msgLen)
+ return STATUS_NOT_DONE;
+
+ return STATUS_OK;
+}
+
/*
* startup2PacketBuf()
*
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: fe-connect.h,v 1.4 1997/09/08 21:55:39 momjian Exp $
+ * $Id: fe-connect.h,v 1.5 1997/12/04 00:28:13 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
*/
extern int packetSend(Port *port, PacketBuf *buf, PacketLen len, bool nonBlocking);
+extern int packetReceive(Port *port, PacketBuf *buf, bool nonBlocking);
#endif /* FE_CONNECT_H */
#ifndef FE_CONNECT_H
#define FE_CONNECT_H
int packetSend(Port *port, PacketBuf *buf, PacketLen len, bool nonBlocking);
+int packetReceive(Port *port, PacketBuf *buf, bool nonBlocking);
#endif
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-fe.h,v 1.23 1997/09/08 21:55:45 momjian Exp $
+ * $Id: libpq-fe.h,v 1.24 1997/12/04 00:28:15 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
/* make a new client connection to the backend */
extern PGconn *PQconnectdb(const char *conninfo);
extern PQconninfoOption *PQconndefaults(void);
- extern PGconn *PQsetdb(const char *pghost, const char *pgport, const char *pgoptions,
- const char *pgtty, const char *dbName);
+ extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
+ const char *pgtty, const char *dbName, const char *login, const char *pwd);
+#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
/* close the current connection and free the PGconn data structure */
extern void PQfinish(PGconn *conn);