Arrange for client authentication to occur before we select a specific

database to connect to. This is necessary for the walsender code to work
properly (it was previously using an untenable assumption that template1 would
always be available to connect to).  This also gets rid of a small security
shortcoming that was introduced in the original patch to eliminate the flat
authentication files: before, you could find out whether or not the requested
database existed even if you couldn't pass the authentication checks.

The changes needed to support this are mainly just to treat pg_authid and
pg_auth_members as nailed relations, so that we can read them without having
to be able to locate real pg_class entries for them.  This mechanism was
already debugged for pg_database, but we hadn't recognized the value of
applying it to those catalogs too.

Since the current code doesn't have support for accessing toast tables before
we've brought up all of the relcache, remove pg_authid's toast table to ensure
that no one can store an out-of-line toasted value of rolpassword.  The case
seems quite unlikely to occur in practice, and was effectively unsupported
anyway in the old "flatfiles" implementation.

Update genbki.pl to actually implement the same rules as bootstrap.c does for
not-nullability of catalog columns.  The previous coding was a bit cheesy but
worked all right for the previous set of bootstrap catalogs.  It does not work
for pg_authid, where rolvaliduntil needs to be nullable.

Initdb forced due to minor catalog changes (mainly the toast table removal).
This commit is contained in:
Tom Lane 2010-04-20 23:48:47 +00:00
parent 7de2dfccc5
commit ea46000a40
10 changed files with 177 additions and 122 deletions

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.89 2010/02/26 02:00:36 momjian Exp $
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.90 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -327,9 +327,7 @@ IsSharedRelation(Oid relationId)
relationId == DbRoleSettingDatidRolidIndexId)
return true;
/* These are their toast tables and toast indexes (see toasting.h) */
if (relationId == PgAuthidToastTable ||
relationId == PgAuthidToastIndex ||
relationId == PgDatabaseToastTable ||
if (relationId == PgDatabaseToastTable ||
relationId == PgDatabaseToastIndex ||
relationId == PgShdescriptionToastTable ||
relationId == PgShdescriptionToastIndex ||

View File

@ -10,7 +10,7 @@
# Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.7 2010/01/22 16:40:18 rhaas Exp $
# $PostgreSQL: pgsql/src/backend/catalog/genbki.pl,v 1.8 2010/04/20 23:48:47 tgl Exp $
#
#----------------------------------------------------------------------
@ -183,13 +183,15 @@ foreach my $catname ( @{ $catalogs->{names} } )
# Generate entries for user attributes.
my $attnum = 0;
my $priornotnull = 1;
my @user_attrs = @{ $table->{columns} };
foreach my $attr (@user_attrs)
{
$attnum++;
my $row = emit_pgattr_row($table_name, $attr);
my $row = emit_pgattr_row($table_name, $attr, $priornotnull);
$row->{attnum} = $attnum;
$row->{attstattarget} = '-1';
$priornotnull &= ($row->{attnotnull} eq 't');
# If it's bootstrapped, put an entry in postgres.bki.
if ($is_bootstrap eq ' bootstrap')
@ -221,7 +223,7 @@ foreach my $catname ( @{ $catalogs->{names} } )
foreach my $attr (@SYS_ATTRS)
{
$attnum--;
my $row = emit_pgattr_row($table_name, $attr);
my $row = emit_pgattr_row($table_name, $attr, 1);
$row->{attnum} = $attnum;
$row->{attstattarget} = '0';
@ -308,10 +310,11 @@ exit 0;
# Given a system catalog name and a reference to a key-value pair corresponding
# to the name and type of a column, generate a reference to a hash that
# represents a pg_attribute entry
# represents a pg_attribute entry. We must also be told whether preceding
# columns were all not-null.
sub emit_pgattr_row
{
my ($table_name, $attr) = @_;
my ($table_name, $attr, $priornotnull) = @_;
my ($attname, $atttype) = %$attr;
my %row;
@ -337,15 +340,21 @@ sub emit_pgattr_row
$row{attalign} = $type->{typalign};
# set attndims if it's an array type
$row{attndims} = $type->{typcategory} eq 'A' ? '1' : '0';
# This approach to attnotnull is not really good enough;
# we need to know about prior column types too. Look at
# DefineAttr in bootstrap.c. For the moment it's okay for
# the column orders appearing in bootstrapped catalogs.
$row{attnotnull} =
$type->{typname} eq 'oidvector' ? 't'
: $type->{typname} eq 'int2vector' ? 't'
: $type->{typlen} eq 'NAMEDATALEN' ? 't'
: $type->{typlen} > 0 ? 't' : 'f';
# attnotnull must be set true if the type is fixed-width and
# prior columns are too --- compare DefineAttr in bootstrap.c.
# oidvector and int2vector are also treated as not-nullable.
if ($priornotnull)
{
$row{attnotnull} =
$type->{typname} eq 'oidvector' ? 't'
: $type->{typname} eq 'int2vector' ? 't'
: $type->{typlen} eq 'NAMEDATALEN' ? 't'
: $type->{typlen} > 0 ? 't' : 'f';
}
else
{
$row{attnotnull} = 'f';
}
last;
}
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.151 2010/02/14 18:42:17 rhaas Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.152 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -981,34 +981,52 @@ InitCatCachePhase2(CatCache *cache, bool touch_index)
* certain system indexes that support critical syscaches.
* We can't use an indexscan to fetch these, else we'll get into
* infinite recursion. A plain heap scan will work, however.
*
* Once we have completed relcache initialization (signaled by
* criticalRelcachesBuilt), we don't have to worry anymore.
*
* Similarly, during backend startup we have to be able to use the
* pg_authid and pg_auth_members syscaches for authentication even if
* we don't yet have relcache entries for those catalogs' indexes.
*/
static bool
IndexScanOK(CatCache *cache, ScanKey cur_skey)
{
if (cache->id == INDEXRELID)
switch (cache->id)
{
/*
* Rather than tracking exactly which indexes have to be loaded before
* we can use indexscans (which changes from time to time), just force
* all pg_index searches to be heap scans until we've built the
* critical relcaches.
*/
if (!criticalRelcachesBuilt)
case INDEXRELID:
/*
* Rather than tracking exactly which indexes have to be loaded
* before we can use indexscans (which changes from time to time),
* just force all pg_index searches to be heap scans until we've
* built the critical relcaches.
*/
if (!criticalRelcachesBuilt)
return false;
break;
case AMOID:
case AMNAME:
/*
* Always do heap scans in pg_am, because it's so small there's
* not much point in an indexscan anyway. We *must* do this when
* initially building critical relcache entries, but we might as
* well just always do it.
*/
return false;
}
else if (cache->id == AMOID ||
cache->id == AMNAME)
{
/*
* Always do heap scans in pg_am, because it's so small there's not
* much point in an indexscan anyway. We *must* do this when
* initially building critical relcache entries, but we might as well
* just always do it.
*/
return false;
case AUTHNAME:
case AUTHOID:
case AUTHMEMMEMROLE:
/*
* Protect authentication lookups occurring before relcache has
* collected entries for shared indexes.
*/
if (!criticalSharedRelcachesBuilt)
return false;
break;
default:
break;
}
/* Normal case, allow index scan */
@ -1397,7 +1415,7 @@ SearchCatCacheList(CatCache *cache,
scandesc = systable_beginscan(relation,
cache->cc_indexoid,
true,
IndexScanOK(cache, cur_skey),
SnapshotNow,
nkeys,
cur_skey);

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.309 2010/04/14 21:31:11 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.310 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -43,6 +43,7 @@
#include "catalog/pg_amproc.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
@ -87,13 +88,15 @@
#define RELCACHE_INIT_FILEMAGIC 0x573265 /* version ID value */
/*
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
* hardcoded tuple descriptors, generated by genbki.pl
*/
static const FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class};
static const FormData_pg_attribute Desc_pg_attribute[Natts_pg_attribute] = {Schema_pg_attribute};
static const FormData_pg_attribute Desc_pg_proc[Natts_pg_proc] = {Schema_pg_proc};
static const FormData_pg_attribute Desc_pg_type[Natts_pg_type] = {Schema_pg_type};
static const FormData_pg_attribute Desc_pg_database[Natts_pg_database] = {Schema_pg_database};
static const FormData_pg_attribute Desc_pg_authid[Natts_pg_authid] = {Schema_pg_authid};
static const FormData_pg_attribute Desc_pg_auth_members[Natts_pg_auth_members] = {Schema_pg_auth_members};
static const FormData_pg_attribute Desc_pg_index[Natts_pg_index] = {Schema_pg_index};
/*
@ -118,7 +121,7 @@ bool criticalRelcachesBuilt = false;
/*
* This flag is false until we have prepared the critical relcache entries
* for shared catalogs (specifically, pg_database and its indexes).
* for shared catalogs (which are the tables needed for login).
*/
bool criticalSharedRelcachesBuilt = false;
@ -1379,8 +1382,9 @@ LookupOpclassInfo(Oid operatorClassOid,
* quite a lot since we only need to work for a few basic system
* catalogs.
*
* formrdesc is currently used for: pg_database, pg_class, pg_attribute,
* pg_proc, and pg_type (see RelationCacheInitializePhase2/3).
* formrdesc is currently used for: pg_database, pg_authid, pg_auth_members,
* pg_class, pg_attribute, pg_proc, and pg_type
* (see RelationCacheInitializePhase2/3).
*
* Note that these catalogs can't have constraints (except attnotnull),
* default values, rules, or triggers, since we don't cope with any of that.
@ -1461,8 +1465,8 @@ formrdesc(const char *relationName, Oid relationReltype,
* initialize attribute tuple form
*
* Unlike the case with the relation tuple, this data had better be right
* because it will never be replaced. The input values must be correctly
* defined by macros in src/include/catalog/ headers.
* because it will never be replaced. The data comes from
* src/include/catalog/ headers via genbki.pl.
*/
relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
relation->rd_att->tdrefcount = 1; /* mark as refcounted */
@ -2455,6 +2459,8 @@ RelationBuildLocalRelation(const char *relname,
switch (relid)
{
case DatabaseRelationId:
case AuthIdRelationId:
case AuthMemRelationId:
case RelationRelationId:
case AttributeRelationId:
case ProcedureRelationId:
@ -2750,12 +2756,13 @@ RelationCacheInitialize(void)
/*
* RelationCacheInitializePhase2
*
* This is called to prepare for access to pg_database during startup.
* We must at least set up a nailed reldesc for pg_database. Ideally
* we'd like to have reldescs for its indexes, too. We attempt to
* load this information from the shared relcache init file. If that's
* missing or broken, just make a phony entry for pg_database.
* RelationCacheInitializePhase3 will clean up as needed.
* This is called to prepare for access to shared catalogs during startup.
* We must at least set up nailed reldescs for pg_database, pg_authid,
* and pg_auth_members. Ideally we'd like to have reldescs for their
* indexes, too. We attempt to load this information from the shared
* relcache init file. If that's missing or broken, just make phony
* entries for the catalogs themselves. RelationCacheInitializePhase3
* will clean up as needed.
*/
void
RelationCacheInitializePhase2(void)
@ -2768,7 +2775,8 @@ RelationCacheInitializePhase2(void)
RelationMapInitializePhase2();
/*
* In bootstrap mode, pg_database isn't there yet anyway, so do nothing.
* In bootstrap mode, the shared catalogs aren't there yet anyway,
* so do nothing.
*/
if (IsBootstrapProcessingMode())
return;
@ -2780,14 +2788,18 @@ RelationCacheInitializePhase2(void)
/*
* Try to load the shared relcache cache file. If unsuccessful, bootstrap
* the cache with a pre-made descriptor for pg_database.
* the cache with pre-made descriptors for the critical shared catalogs.
*/
if (!load_relcache_init_file(true))
{
formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true,
true, Natts_pg_database, Desc_pg_database);
formrdesc("pg_authid", AuthIdRelation_Rowtype_Id, true,
true, Natts_pg_authid, Desc_pg_authid);
formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id, true,
false, Natts_pg_auth_members, Desc_pg_auth_members);
#define NUM_CRITICAL_SHARED_RELS 1 /* fix if you change list above */
#define NUM_CRITICAL_SHARED_RELS 3 /* fix if you change list above */
}
MemoryContextSwitchTo(oldcxt);
@ -2910,7 +2922,9 @@ RelationCacheInitializePhase3(void)
* DatabaseNameIndexId isn't critical for relcache loading, but rather for
* initial lookup of MyDatabaseId, without which we'll never find any
* non-shared catalogs at all. Autovacuum calls InitPostgres with a
* database OID, so it instead depends on DatabaseOidIndexId.
* database OID, so it instead depends on DatabaseOidIndexId. We also
* need to nail up some indexes on pg_authid and pg_auth_members for use
* during client authentication.
*/
if (!criticalSharedRelcachesBuilt)
{
@ -2918,8 +2932,14 @@ RelationCacheInitializePhase3(void)
DatabaseRelationId);
load_critical_index(DatabaseOidIndexId,
DatabaseRelationId);
load_critical_index(AuthIdRolnameIndexId,
AuthIdRelationId);
load_critical_index(AuthIdOidIndexId,
AuthIdRelationId);
load_critical_index(AuthMemMemRoleIndexId,
AuthMemRelationId);
#define NUM_CRITICAL_SHARED_INDEXES 2 /* fix if you change list above */
#define NUM_CRITICAL_SHARED_INDEXES 5 /* fix if you change list above */
criticalSharedRelcachesBuilt = true;
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.183 2010/02/26 02:01:13 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.184 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -429,10 +429,8 @@ InitializeSessionUserId(const char *rolename)
* These next checks are not enforced when in standalone mode, so that
* there is a way to recover from sillinesses like "UPDATE pg_authid SET
* rolcanlogin = false;".
*
* We do not enforce them for the autovacuum process either.
*/
if (IsUnderPostmaster && !IsAutoVacuumWorkerProcess())
if (IsUnderPostmaster)
{
/*
* Is role allowed to login at all?
@ -479,7 +477,10 @@ InitializeSessionUserId(const char *rolename)
void
InitializeSessionUserIdStandalone(void)
{
/* This function should only be called in a single-user backend. */
/*
* This function should only be called in single-user mode and in
* autovacuum workers.
*/
AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess());
/* call only once */

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.209 2010/04/20 01:38:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.210 2010/04/20 23:48:47 tgl Exp $
*
*
*-------------------------------------------------------------------------
@ -552,7 +552,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/*
* Load relcache entries for the shared system catalogs. This must create
* at least an entry for pg_database.
* at least entries for pg_database and catalogs used for authentication.
*/
RelationCacheInitializePhase2();
@ -585,14 +585,60 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
(void) GetTransactionSnapshot();
}
/*
* Perform client authentication if necessary, then figure out our
* postgres user ID, and see if we are a superuser.
*
* In standalone mode and in autovacuum worker processes, we use a fixed
* ID, otherwise we figure it out from the authenticated user name.
*/
if (bootstrap || IsAutoVacuumWorkerProcess())
{
InitializeSessionUserIdStandalone();
am_superuser = true;
}
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
am_superuser = true;
if (!ThereIsAtLeastOneRole())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("no roles are defined in this database system"),
errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
username)));
}
else
{
/* normal multiuser case */
Assert(MyProcPort != NULL);
PerformAuthentication(MyProcPort);
InitializeSessionUserId(username);
am_superuser = superuser();
}
/*
* If walsender, we're done here --- we don't want to connect to any
* particular database.
*/
if (am_walsender)
{
Assert(!bootstrap);
/* report this backend in the PgBackendStatus array */
pgstat_bestart();
/* close the transaction we started above */
CommitTransactionCommand();
return;
}
/*
* Set up the global variables holding database id and default tablespace.
* But note we won't actually try to touch the database just yet.
*
* We take a shortcut in the bootstrap and walsender case, otherwise we
* have to look up the db's entry in pg_database.
* We take a shortcut in the bootstrap case, otherwise we have to look up
* the db's entry in pg_database.
*/
if (bootstrap || am_walsender)
if (bootstrap)
{
MyDatabaseId = TemplateDbOid;
MyDatabaseTableSpace = DEFAULTTABLESPACE_OID;
@ -655,7 +701,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
* AccessShareLock for such sessions and thereby not conflict against
* CREATE DATABASE.
*/
if (!bootstrap && !am_walsender)
if (!bootstrap)
LockSharedObject(DatabaseRelationId, MyDatabaseId, 0,
RowExclusiveLock);
@ -664,7 +710,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
* If there was a concurrent DROP DATABASE, this ensures we will die
* cleanly without creating a mess.
*/
if (!bootstrap && !am_walsender)
if (!bootstrap)
{
HeapTuple tuple;
@ -684,7 +730,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
*/
fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace);
if (!bootstrap && !am_walsender)
if (!bootstrap)
{
if (access(fullpath, F_OK) == -1)
{
@ -715,51 +761,16 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
*/
RelationCacheInitializePhase3();
/*
* Perform client authentication if necessary, then figure out our
* postgres user ID, and see if we are a superuser.
*
* In standalone mode and in autovacuum worker processes, we use a fixed
* ID, otherwise we figure it out from the authenticated user name.
*/
if (bootstrap || IsAutoVacuumWorkerProcess())
{
InitializeSessionUserIdStandalone();
am_superuser = true;
}
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
am_superuser = true;
if (!ThereIsAtLeastOneRole())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("no roles are defined in this database system"),
errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
username)));
}
else
{
/* normal multiuser case */
Assert(MyProcPort != NULL);
PerformAuthentication(MyProcPort);
InitializeSessionUserId(username);
am_superuser = superuser();
}
/* set up ACL framework (so CheckMyDatabase can check permissions) */
initialize_acl();
/* Process pg_db_role_setting options */
process_settings(MyDatabaseId, GetSessionUserId());
/*
* Re-read the pg_database row for our database, check permissions and set
* up database-specific GUC settings. We can't do this until all the
* database-access infrastructure is up. (Also, it wants to know if the
* user is a superuser, so the above stuff has to happen first.)
*/
if (!bootstrap && !am_walsender)
if (!bootstrap)
CheckMyDatabase(dbname, am_superuser);
/*
@ -841,6 +852,9 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
}
}
/* Process pg_db_role_setting options */
process_settings(MyDatabaseId, GetSessionUserId());
/* Apply PostAuthDelay as soon as we've read all options */
if (PostAuthDelay > 0)
pg_usleep(PostAuthDelay * 1000000L);
@ -856,10 +870,6 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/* initialize client encoding */
InitializeClientEncoding();
/* reset the database for walsender */
if (am_walsender)
MyProc->databaseId = MyDatabaseId = InvalidOid;
/* report this backend in the PgBackendStatus array */
if (!bootstrap)
pgstat_bestart();

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.585 2010/02/16 22:34:54 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.586 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201002161
#define CATALOG_VERSION_NO 201004201
#endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_auth_members.h,v 1.8 2010/01/05 01:06:56 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_auth_members.h,v 1.9 2010/04/20 23:48:47 tgl Exp $
*
* NOTES
* the genbki.pl script reads this file and generates .bki
@ -27,8 +27,9 @@
* ----------------
*/
#define AuthMemRelationId 1261
#define AuthMemRelation_Rowtype_Id 2843
CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(2843) BKI_SCHEMA_MACRO
{
Oid roleid; /* ID of a role */
Oid member; /* ID of a member of that role */

View File

@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_authid.h,v 1.12 2010/01/05 01:06:56 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_authid.h,v 1.13 2010/04/20 23:48:47 tgl Exp $
*
* NOTES
* the genbki.pl script reads this file and generates .bki
@ -40,8 +40,9 @@
* ----------------
*/
#define AuthIdRelationId 1260
#define AuthIdRelation_Rowtype_Id 2842
CATALOG(pg_authid,1260) BKI_SHARED_RELATION
CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MACRO
{
NameData rolname; /* name of role */
bool rolsuper; /* read this field via superuser() only! */
@ -71,7 +72,7 @@ typedef FormData_pg_authid *Form_pg_authid;
* compiler constants for pg_authid
* ----------------
*/
#define Natts_pg_authid 11
#define Natts_pg_authid 10
#define Anum_pg_authid_rolname 1
#define Anum_pg_authid_rolsuper 2
#define Anum_pg_authid_rolinherit 3

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.13 2010/01/06 03:04:03 momjian Exp $
* $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.14 2010/04/20 23:48:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -49,9 +49,6 @@ DECLARE_TOAST(pg_statistic, 2840, 2841);
DECLARE_TOAST(pg_trigger, 2336, 2337);
/* shared catalogs */
DECLARE_TOAST(pg_authid, 2842, 2843);
#define PgAuthidToastTable 2842
#define PgAuthidToastIndex 2843
DECLARE_TOAST(pg_database, 2844, 2845);
#define PgDatabaseToastTable 2844
#define PgDatabaseToastIndex 2845