diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/catalog/genbki.sh | 3 | ||||
| -rw-r--r-- | src/backend/commands/user.c | 41 | ||||
| -rw-r--r-- | src/backend/utils/init/miscinit.c | 16 | ||||
| -rw-r--r-- | src/backend/utils/init/postinit.c | 47 | ||||
| -rw-r--r-- | src/backend/utils/misc/superuser.c | 6 |
5 files changed, 91 insertions, 22 deletions
diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index 25c8d7d2d4..850c329579 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -10,7 +10,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.23 2001/08/26 16:55:59 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.24 2001/09/08 15:24:00 petere Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -183,6 +183,7 @@ sed -e "s/;[ ]*$//g" \ -e "s/[ ]TransactionId/ xid/g" \ -e "s/^TransactionId/xid/g" \ -e "s/(TransactionId/(xid/g" \ + -e "s/PGUID/1/g" \ -e "s/NAMEDATALEN/$NAMEDATALEN/g" \ -e "s/DEFAULT_ATTSTATTARGET/$DEFAULTATTSTATTARGET/g" \ -e "s/INDEX_MAX_KEYS\*2/$INDEXMAXKEYS2/g" \ diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index d830dfdfc9..122a490361 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.82 2001/08/17 02:59:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.83 2001/09/08 15:24:00 petere Exp $ * *------------------------------------------------------------------------- */ @@ -198,7 +198,7 @@ CreateUser(CreateUserStmt *stmt) bool user_exists = false, sysid_exists = false, havesysid = false; - int max_id = -1; + int max_id; List *item, *option; char *password = NULL; /* PostgreSQL user password */ bool encrypt_password = Password_encryption; /* encrypt password? */ @@ -268,6 +268,8 @@ CreateUser(CreateUserStmt *stmt) if (dsysid) { sysid = intVal(dsysid->arg); + if (sysid <= 0) + elog(ERROR, "user id must be positive"); havesysid = true; } if (dvalidUntil) @@ -294,6 +296,7 @@ CreateUser(CreateUserStmt *stmt) pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL); + max_id = 99; /* start auto-assigned ids at 100 */ while (!user_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { @@ -550,31 +553,31 @@ AlterUser(AlterUserStmt *stmt) new_record[Anum_pg_shadow_usetrace - 1] = heap_getattr(tuple, Anum_pg_shadow_usetrace, pg_shadow_dsc, &null); new_record_nulls[Anum_pg_shadow_usetrace - 1] = null ? 'n' : ' '; - /* createuser (superuser) */ + /* + * createuser (superuser) and catupd + * + * XXX It's rather unclear how to handle catupd. It's probably + * best to keep it equal to the superuser status, otherwise you + * could end up with a situation where no existing superuser can + * alter the catalogs, including pg_shadow! + */ if (createuser < 0) { /* don't change */ new_record[Anum_pg_shadow_usesuper - 1] = heap_getattr(tuple, Anum_pg_shadow_usesuper, pg_shadow_dsc, &null); new_record_nulls[Anum_pg_shadow_usesuper - 1] = null ? 'n' : ' '; + + new_record[Anum_pg_shadow_usecatupd - 1] = heap_getattr(tuple, Anum_pg_shadow_usecatupd, pg_shadow_dsc, &null); + new_record_nulls[Anum_pg_shadow_usecatupd - 1] = null ? 'n' : ' '; } else { new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0); new_record_nulls[Anum_pg_shadow_usesuper - 1] = ' '; - } - /* catupd - set to false if someone's superuser priv is being yanked */ - if (createuser == 0) - { - new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(false); + new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser > 0); new_record_nulls[Anum_pg_shadow_usecatupd - 1] = ' '; } - else - { - /* leave alone */ - new_record[Anum_pg_shadow_usecatupd - 1] = heap_getattr(tuple, Anum_pg_shadow_usecatupd, pg_shadow_dsc, &null); - new_record_nulls[Anum_pg_shadow_usecatupd - 1] = null ? 'n' : ' '; - } /* password */ if (password) @@ -692,6 +695,11 @@ DropUser(DropUserStmt *stmt) usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null)); + if (usesysid == GetUserId()) + elog(ERROR, "current user cannot be dropped"); + if (usesysid == GetSessionUserId()) + elog(ERROR, "session user cannot be dropped"); + /* * Check if user still owns a database. If so, error out. * @@ -825,7 +833,7 @@ CreateGroup(CreateGroupStmt *stmt) bool group_exists = false, sysid_exists = false, havesysid = false; - int max_id = 0; + int max_id; Datum new_record[Natts_pg_group]; char new_record_nulls[Natts_pg_group]; List *item, @@ -859,6 +867,8 @@ CreateGroup(CreateGroupStmt *stmt) if (dsysid) { sysid = intVal(dsysid->arg); + if (sysid <= 0) + elog(ERROR, "group id must be positive"); havesysid = true; } @@ -875,6 +885,7 @@ CreateGroup(CreateGroupStmt *stmt) pg_group_dsc = RelationGetDescr(pg_group_rel); scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL); + max_id = 99; /* start auto-assigned ids at 100 */ while (!group_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, false))) { diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index a57f3d2624..e6da787bc4 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.76 2001/08/15 07:07:40 ishii Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.77 2001/09/08 15:24:00 petere Exp $ * *------------------------------------------------------------------------- */ @@ -476,6 +476,20 @@ InitializeSessionUserId(const char *username) } +void +InitializeSessionUserIdStandalone(void) +{ + /* This function should only be called in a single-user backend. */ + AssertState(!IsUnderPostmaster); + + /* call only once */ + AssertState(!OidIsValid(SessionUserId)); + + SetSessionUserId(BOOTSTRAP_USESYSID); + AuthenticatedUserIsSuperuser = true; +} + + /* * Change session auth ID while running */ diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 51c95fb141..60338397db 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.90 2001/09/07 00:27:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.91 2001/09/08 15:24:00 petere Exp $ * * *------------------------------------------------------------------------- @@ -25,6 +25,7 @@ #include "access/heapam.h" #include "catalog/catname.h" #include "catalog/pg_database.h" +#include "catalog/pg_shadow.h" #include "commands/trigger.h" #include "commands/variable.h" /* for set_default_client_encoding() */ #include "mb/pg_wchar.h" @@ -43,6 +44,7 @@ static void ReverifyMyDatabase(const char *name); static void InitCommunication(void); static void ShutdownPostgres(void); +static bool ThereIsAtLeastOneUser(void); int lockingOff = 0; /* backend -L switch */ @@ -329,12 +331,24 @@ InitPostgres(const char *dbname, const char *username) LockDisable(true); /* - * Figure out our postgres user id. If bootstrapping, we can't - * assume that pg_shadow exists yet, so fake it. + * Figure out our postgres user id. In standalone mode we use a + * fixed id, otherwise we figure it out from the authenticated + * user name. */ if (bootstrap) - SetSessionUserId(geteuid()); + InitializeSessionUserIdStandalone(); + else if (!IsUnderPostmaster) + { + InitializeSessionUserIdStandalone(); + if (!ThereIsAtLeastOneUser()) + { + elog(NOTICE, "There are currently no users defined in this database system."); + elog(NOTICE, "You should immediately run 'CREATE USER \"%s\" WITH SYSID %d CREATEUSER;'.", + username, BOOTSTRAP_USESYSID); + } + } else + /* normal multiuser case */ InitializeSessionUserId(username); /* @@ -406,3 +420,28 @@ ShutdownPostgres(void) */ smgrDoPendingDeletes(false);/* delete as though aborting xact */ } + + + +/* + * Returns true if at least one user is defined in this database cluster. + */ +static bool +ThereIsAtLeastOneUser(void) +{ + Relation pg_shadow_rel; + TupleDesc pg_shadow_dsc; + HeapScanDesc scan; + bool result; + + pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock); + pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); + + scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, 0); + result = HeapTupleIsValid(heap_getnext(scan, 0)); + + heap_endscan(scan); + heap_close(pg_shadow_rel, AccessExclusiveLock); + + return result; +} diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c index 73cfe8cb97..2f09202848 100644 --- a/src/backend/utils/misc/superuser.c +++ b/src/backend/utils/misc/superuser.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.18 2001/06/13 21:44:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.19 2001/09/08 15:24:00 petere Exp $ * *------------------------------------------------------------------------- */ @@ -34,6 +34,10 @@ superuser(void) bool result = false; HeapTuple utup; + /* Special escape path in case you deleted all your users. */ + if (!IsUnderPostmaster && GetUserId() == BOOTSTRAP_USESYSID) + return true; + utup = SearchSysCache(SHADOWSYSID, ObjectIdGetDatum(GetUserId()), 0, 0, 0); |
