]> granicus.if.org Git - postgresql/commitdiff
From: todd brandys <brandys@eng3.hep.uiuc.edu>
authorMarc G. Fournier <scrappy@hub.org>
Thu, 4 Dec 1997 00:28:15 +0000 (00:28 +0000)
committerMarc G. Fournier <scrappy@hub.org>
Thu, 4 Dec 1997 00:28:15 +0000 (00:28 +0000)
An extension to the code to allow for a pg_password authentication database
that is *seperate* from the system password file

19 files changed:
src/backend/commands/Makefile
src/backend/libpq/Makefile
src/backend/libpq/auth.c
src/backend/parser/gram.y
src/backend/parser/keywords.c
src/backend/postmaster/postmaster.c
src/backend/tcop/utility.c
src/bin/initdb/initdb.sh
src/bin/psql/psqlHelp.h
src/include/catalog/pg_attribute.h
src/include/catalog/pg_class.h
src/include/catalog/pg_user.h
src/include/libpq/pqcomm.h
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h
src/interfaces/libpq/fe-auth.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-connect.h
src/interfaces/libpq/libpq-fe.h

index bb6524b79d928fd53cde2e374a7df7fe34328c6c..9e57883debad4127d9d8b5dbb7ee2bfb0e0c9c49 100644 (file)
@@ -4,7 +4,7 @@
 #    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 $
 #
 #-------------------------------------------------------------------------
 
@@ -19,7 +19,7 @@ CFLAGS+=$(INCLUDE_OPT)
 
 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
 
index 84c2db63bb130908aa62349c5826321375316c53..ed43bdd1352d086e83090848b3fed1eea3b199ee 100644 (file)
@@ -4,7 +4,7 @@
 #    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 $
 #
 #-------------------------------------------------------------------------
 
@@ -24,7 +24,7 @@ LDFLAGS+= $(KRBLIBS)
 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
index aa9c541b168a1378e5db2734dfa4aca552c98af2..e4f1753800a42c9927181a9dfd26580ef5402a74 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,6 +71,7 @@
 #include <libpq/libpq-be.h>
 #include <libpq/hba.h>
 #include <libpq/password.h>
+#include <libpq/crypt.h>
 
 static int     be_getauthsvc(MsgType msgtype);
 
@@ -122,7 +123,8 @@ static struct authsvc authsvcs[] = {
 #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);
@@ -445,6 +447,28 @@ pg_password_recvauth(Port *port, char *database, char *DataDir)
        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
  */
@@ -571,6 +595,10 @@ be_recvauth(MsgType msgtype_arg, Port *port, char *username, StartupInfo *sp)
                                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",
index 8cbc5397d1da66265ec65cdb7a7d819720227559..a7bc22d67c2b17c19e8e4704d47cca475792ae95 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * 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
@@ -40,6 +40,7 @@
 #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"
@@ -83,6 +84,7 @@ Oid   param_type(int t); /* used in parse_expr.c */
        char                            chr;
        char                            *str;
        bool                            boolean;
+       bool*                           pboolean;       /* for pg_user privileges */
        List                            *list;
        Node                            *node;
        Value                           *value;
@@ -119,10 +121,16 @@ Oid       param_type(int t); /* used in parse_expr.c */
                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
@@ -268,6 +276,14 @@ Oid        param_type(int t); /* used in parse_expr.c */
                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
@@ -318,17 +334,20 @@ stmtmulti:  stmtmulti stmt ';'
                ;
 
 stmt :   AddAttrStmt
+               | AlterUserStmt
                | ClosePortalStmt
                | CopyStmt
                | CreateStmt
                | CreateSeqStmt
                | CreatePLangStmt
                | CreateTrigStmt
+               | CreateUserStmt
                | ClusterStmt
                | DefineStmt
                | DestroyStmt
                | DropPLangStmt
                | DropTrigStmt
+               | DropUserStmt
                | ExtendStmt
                | ExplainStmt
                | FetchStmt
@@ -356,6 +375,105 @@ stmt :      AddAttrStmt
                | 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; }
+                      ;
 
 /*****************************************************************************
  *
index 0e17dc122461cf98f155f60547d8e4bd481c08e9..c51cc1f33d318f61888c56992f1b9d01567d29d3 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -64,6 +64,8 @@ static ScanKeyword ScanKeywords[] = {
        {"constraint", CONSTRAINT},
        {"copy", COPY},
        {"create", CREATE},
+       {"createdb", CREATEDB},
+       {"createuser", CREATEUSER},
        {"cross", CROSS},
        {"current", CURRENT},
        {"current_date", CURRENT_DATE},
@@ -133,6 +135,8 @@ static ScanKeyword ScanKeywords[] = {
        {"natural", NATURAL},
        {"nchar", NCHAR},
        {"new", NEW},
+       {"nocreatedb", NOCREATEDB},
+       {"nocreateuser", NOCREATEUSER},
        {"none", NONE},
        {"no", NO},
        {"not", NOT},
@@ -149,6 +153,7 @@ static ScanKeyword ScanKeywords[] = {
        {"order", ORDER},
        {"outer", OUTER_P},
        {"partial", PARTIAL},
+       {"password", PASSWORD},
        {"position", POSITION},
        {"precision", PRECISION},
        {"primary", PRIMARY},
@@ -188,9 +193,12 @@ static ScanKeyword ScanKeywords[] = {
        {"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},
index 52bc471853f2febf31c1800f267bcd46763d1913..b4d1f9559926883d1f1be150f3ea829c42a887c8 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * 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
  *
@@ -47,6 +47,7 @@
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
+#include <time.h>
 
 #if !defined(NO_UNISTD_H)
 #include <unistd.h>
@@ -78,6 +79,7 @@
 #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"
@@ -199,6 +201,7 @@ static void usage(const char *);
 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,
@@ -663,7 +666,27 @@ ServerLoop(void)
                                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
@@ -1355,3 +1378,44 @@ dumpstatus(SIGNAL_ARGS)
                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());
+}
index 2e9b764644d97a4b200333b4ae5e6b0fb4e05adf..57960aee87672d1a0ee802f08e86335b3586e19d 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -721,6 +721,32 @@ ProcessUtility(Node * parsetree,
                        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 ********************************
                         *
index 6d6456f957dc68e802508704e9a6a180f950a50d..76ebc8ea6659563b89101736efccb9c05b56cf08 100644 (file)
@@ -26,7 +26,7 @@
 #
 #
 # 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 $
 #
 #-------------------------------------------------------------------------
 
@@ -351,6 +351,13 @@ echo "vacuuming template1"
 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
index a91272e929792db12775cacbcd5d00733d6163ad..27f820d26e24064eb369a21a9de87e9cc9d4e42e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,6 +27,9 @@ static struct _helpStruct QL_HELP[] = {
        {"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];"},
@@ -84,6 +87,9 @@ static struct _helpStruct QL_HELP[] = {
        {"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>];"},
@@ -126,6 +132,9 @@ static struct _helpStruct QL_HELP[] = {
        {"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>"},
index cb69640964b9918c608b1dcb55b98d7d4233201a..9be5e6ba23b1b1100ee29d5e7100bea0738ce74d 100644 (file)
@@ -7,7 +7,7 @@
  *
  * 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
@@ -275,12 +275,14 @@ DATA(insert OID = 0 ( 1255 cmax                           29 0  4  -6 0 -1 t f i f f));
  *             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));
index 1240e8ac4fe20d42c6c87f60401082cf46f436d1..7c0ee50fec9c8fad3fd465452ef98b6dc42f8566 100644 (file)
@@ -7,7 +7,7 @@
  *
  * 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
@@ -125,7 +125,7 @@ DATA(insert OID = 1255 (  pg_proc 81                  PGUID 0 0 0 f f r 16 0 0 f _null_ ));
 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("");
index 7f7bd8b6525e84a1224a37a346d291e31aff3632..8e6bb2cd0ee1a825dee3d21344741d846b87ddd5 100644 (file)
@@ -7,7 +7,7 @@
  *
  * 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
@@ -36,6 +36,8 @@ CATALOG(pg_user) BOOTSTRAP
        bool            usetrace;
        bool            usesuper;
        bool            usecatupd;
+       text            passwd;
+       int4            valuntil;
 } FormData_pg_user;
 
 /* ----------------
@@ -49,46 +51,48 @@ typedef FormData_pg_user *Form_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 */
index 399e3231b65c928efb93a6bd107bfde156d0b661..a832918f947c022097ec7509bc64c730093ebd87 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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
@@ -59,7 +59,16 @@ typedef enum _MsgType
        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 */
@@ -119,6 +128,7 @@ typedef struct Port
         * PacketBufId                          id;
 *//* id of packet buf currently in use */
        PacketBuf       buf;                    /* stream implementation (curr pack buf) */
+       char            salt[2];
 } Port;
 
 /* invalid socket descriptor */
index 7239818bd95527ffc49da26e759ba193ad3b5148..7388c0af8322335ce928dc5b4a9dcab700d0af9c 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -186,6 +186,9 @@ typedef enum NodeTag
        T_DropTrigStmt,
        T_CreatePLangStmt,
        T_DropPLangStmt,
+       T_CreateUserStmt,
+       T_AlterUserStmt,
+       T_DropUserStmt,
 
        T_A_Expr = 700,
        T_Attr,
index c0a77d1ff3a5b7d23a510bb8c53a38e1b8b0ea39..8674f456dd154c386bdf0929d3b51c0266920c0d 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -197,6 +197,30 @@ typedef struct DropPLangStmt
 }                      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
  * ----------------------
index 3bcd919dc0cf8a006952c072115b8957b818dd3e..8f96230f02d1ecc263e670ad79c5230918161c69 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -511,6 +511,7 @@ fe_sendauth(MsgType msgtype, Port *port, const char *hostname,
                case STARTUP_MSG:
                        break;
                case STARTUP_PASSWORD_MSG:
+               case STARTUP_CRYPT_MSG:
                        pg_password_sendauth(port, user, password);
                default:
                        break;
index cd5331f7981fad6a1032b12b32b4b7aaada15b58..84fa1f6742c45f0eac73ff3a0cfa68f9b0d80df8 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,6 +36,9 @@
 #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 */
@@ -284,7 +287,7 @@ PQconndefaults(void)
 }
 
 /* ----------------
- *             PQsetdb
+ *             PQsetdbLogin
  *
  * establishes a connection to a postgres backend through the postmaster
  * at the specified host and port.
@@ -324,7 +327,7 @@ PQconndefaults(void)
  * ----------------
  */
 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;
@@ -386,7 +389,12 @@ PQsetdb(const char *pghost, const char *pgport, const char *pgoptions, const cha
                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);
@@ -407,8 +415,14 @@ PQsetdb(const char *pghost, const char *pgport, const char *pgoptions, const cha
                        }
                }
 
-               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;
 
@@ -479,6 +493,7 @@ connectDB(PGconn *conn)
 
        StartupInfo startup;
        PacketBuf       pacBuf;
+       PacketLen       pacLen;
        int                     status;
        MsgType         msgtype;
        int                     laddrlen = sizeof(struct sockaddr);
@@ -486,6 +501,8 @@ connectDB(PGconn *conn)
        int                     portno,
                                family,
                                len;
+       bool                    salted = false;
+       char*                   tmp;
 
        /*
         * Initialize the startup packet.
@@ -592,7 +609,57 @@ connectDB(PGconn *conn)
        }
 
        /* 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);
@@ -820,6 +887,63 @@ packetSend(Port *port,
        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()
  *
index bbacedf6dd6dcf25271f055cd060383abb3c0d01..7a68e3dedcd5f068f581173e3a16b99c662637b3 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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
index 6f2d93b8db47918862fd25839bdf4bb6fe7f2fc3..ce54af85b04ee897f405ff0fa3406c5cbba4144d 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -221,8 +221,9 @@ extern              "C"
        /* 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);