diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-04-20 23:48:47 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-04-20 23:48:47 +0000 |
commit | ea46000a40cf583401504e095ca1a49f57fa0227 (patch) | |
tree | 759478262148b456ade1c7350bbd7137317e1188 /src/backend/utils/cache/relcache.c | |
parent | 7de2dfccc5868d8ba1c00a6bf7de67d9d50bc7bc (diff) | |
download | postgresql-ea46000a40cf583401504e095ca1a49f57fa0227.tar.gz postgresql-ea46000a40cf583401504e095ca1a49f57fa0227.zip |
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).
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 375a477a304..1ce08a3e6af 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -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); - -#define NUM_CRITICAL_SHARED_INDEXES 2 /* fix if you change list above */ + load_critical_index(AuthIdRolnameIndexId, + AuthIdRelationId); + load_critical_index(AuthIdOidIndexId, + AuthIdRelationId); + load_critical_index(AuthMemMemRoleIndexId, + AuthMemRelationId); + +#define NUM_CRITICAL_SHARED_INDEXES 5 /* fix if you change list above */ criticalSharedRelcachesBuilt = true; } |