mirror of
https://github.com/postgres/postgres.git
synced 2025-11-10 17:42:29 +03:00
Replace pg_shadow and pg_group by new role-capable catalogs pg_authid
and pg_auth_members. There are still many loose ends to finish in this patch (no documentation, no regression tests, no pg_dump support for instance). But I'm going to commit it now anyway so that Alvaro can make some progress on shared dependencies. The catalog changes should be pretty much done.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.6 2005/06/19 22:34:56 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.7 2005/06/28 05:08:51 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Each global transaction is associated with a global transaction
|
||||
@@ -107,7 +107,7 @@ typedef struct GlobalTransactionData
|
||||
PGPROC proc; /* dummy proc */
|
||||
TimestampTz prepared_at; /* time of preparation */
|
||||
XLogRecPtr prepare_lsn; /* XLOG offset of prepare record */
|
||||
AclId owner; /* ID of user that executed the xact */
|
||||
Oid owner; /* ID of user that executed the xact */
|
||||
TransactionId locking_xid; /* top-level XID of backend working on xact */
|
||||
bool valid; /* TRUE if fully prepared */
|
||||
char gid[GIDSIZE]; /* The GID assigned to the prepared xact */
|
||||
@@ -206,7 +206,7 @@ TwoPhaseShmemInit(void)
|
||||
*/
|
||||
GlobalTransaction
|
||||
MarkAsPreparing(TransactionId xid, const char *gid,
|
||||
TimestampTz prepared_at, AclId owner, Oid databaseid)
|
||||
TimestampTz prepared_at, Oid owner, Oid databaseid)
|
||||
{
|
||||
GlobalTransaction gxact;
|
||||
int i;
|
||||
@@ -350,7 +350,7 @@ MarkAsPrepared(GlobalTransaction gxact)
|
||||
* Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
|
||||
*/
|
||||
static GlobalTransaction
|
||||
LockGXact(const char *gid, AclId user)
|
||||
LockGXact(const char *gid, Oid user)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -559,7 +559,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
|
||||
INT4OID, -1, 0);
|
||||
OIDOID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
|
||||
OIDOID, -1, 0);
|
||||
|
||||
@@ -601,7 +601,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
|
||||
values[0] = TransactionIdGetDatum(gxact->proc.xid);
|
||||
values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid));
|
||||
values[2] = TimestampTzGetDatum(gxact->prepared_at);
|
||||
values[3] = Int32GetDatum(gxact->owner);
|
||||
values[3] = ObjectIdGetDatum(gxact->owner);
|
||||
values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
|
||||
|
||||
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
|
||||
@@ -690,7 +690,7 @@ typedef struct TwoPhaseFileHeader
|
||||
TransactionId xid; /* original transaction XID */
|
||||
Oid database; /* OID of database it was in */
|
||||
TimestampTz prepared_at; /* time of preparation */
|
||||
AclId owner; /* user running the transaction */
|
||||
Oid owner; /* user running the transaction */
|
||||
int32 nsubxacts; /* number of following subxact XIDs */
|
||||
int32 ncommitrels; /* number of delete-on-commit rels */
|
||||
int32 nabortrels; /* number of delete-on-abort rels */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.207 2005/06/19 20:00:38 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.208 2005/06/28 05:08:51 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -121,7 +121,7 @@ typedef struct TransactionStateData
|
||||
* context */
|
||||
ResourceOwner curTransactionOwner; /* my query resources */
|
||||
List *childXids; /* subcommitted child XIDs */
|
||||
AclId currentUser; /* subxact start current_user */
|
||||
Oid currentUser; /* subxact start current_user */
|
||||
bool prevXactReadOnly; /* entry-time xact r/o state */
|
||||
struct TransactionStateData *parent; /* back link to parent */
|
||||
} TransactionStateData;
|
||||
@@ -1488,8 +1488,10 @@ CommitTransaction(void)
|
||||
/* NOTIFY commit must come before lower-level cleanup */
|
||||
AtCommit_Notify();
|
||||
|
||||
/* Update flat files if we changed pg_database, pg_shadow or pg_group */
|
||||
/* This should be the last step before commit */
|
||||
/*
|
||||
* Update flat files if we changed pg_database, pg_authid or
|
||||
* pg_auth_members. This should be the last step before commit.
|
||||
*/
|
||||
AtEOXact_UpdateFlatFiles(true);
|
||||
|
||||
/* Prevent cancel/die interrupt while cleaning up */
|
||||
@@ -3847,7 +3849,7 @@ PushTransaction(void)
|
||||
{
|
||||
TransactionState p = CurrentTransactionState;
|
||||
TransactionState s;
|
||||
AclId currentUser;
|
||||
Oid currentUser;
|
||||
|
||||
/*
|
||||
* At present, GetUserId cannot fail, but let's not assume that. Get
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Makefile for backend/catalog
|
||||
#
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.53 2004/07/21 20:34:45 momjian Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.54 2005/06/28 05:08:52 tgl Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@@ -31,8 +31,9 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
|
||||
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
|
||||
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
|
||||
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
|
||||
pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
|
||||
pg_tablespace.h pg_depend.h indexing.h \
|
||||
pg_namespace.h pg_conversion.h pg_database.h \
|
||||
pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \
|
||||
indexing.h \
|
||||
)
|
||||
|
||||
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.112 2005/05/29 23:38:05 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.113 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* See acl.h.
|
||||
@@ -21,15 +21,15 @@
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_auth_members.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/pg_language.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_opclass.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "miscadmin.h"
|
||||
@@ -76,10 +76,10 @@ dumpacl(Acl *acl)
|
||||
* all granted privileges appear to flow from the object owner, and there
|
||||
* are never multiple "original sources" of a privilege.
|
||||
*/
|
||||
static AclId
|
||||
select_grantor(AclId ownerId)
|
||||
static Oid
|
||||
select_grantor(Oid ownerId)
|
||||
{
|
||||
AclId grantorId;
|
||||
Oid grantorId;
|
||||
|
||||
grantorId = GetUserId();
|
||||
|
||||
@@ -105,7 +105,7 @@ static Acl *
|
||||
merge_acl_with_grant(Acl *old_acl, bool is_grant,
|
||||
bool grant_option, DropBehavior behavior,
|
||||
List *grantees, AclMode privileges,
|
||||
AclId grantor_uid, AclId owner_uid)
|
||||
Oid grantorId, Oid ownerId)
|
||||
{
|
||||
unsigned modechg;
|
||||
ListCell *j;
|
||||
@@ -122,41 +122,25 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
|
||||
{
|
||||
PrivGrantee *grantee = (PrivGrantee *) lfirst(j);
|
||||
AclItem aclitem;
|
||||
uint32 idtype;
|
||||
Acl *newer_acl;
|
||||
|
||||
if (grantee->username)
|
||||
{
|
||||
aclitem. ai_grantee = get_usesysid(grantee->username);
|
||||
|
||||
idtype = ACL_IDTYPE_UID;
|
||||
}
|
||||
else if (grantee->groupname)
|
||||
{
|
||||
aclitem. ai_grantee = get_grosysid(grantee->groupname);
|
||||
|
||||
idtype = ACL_IDTYPE_GID;
|
||||
}
|
||||
if (grantee->rolname)
|
||||
aclitem.ai_grantee = get_roleid_checked(grantee->rolname);
|
||||
else
|
||||
{
|
||||
aclitem. ai_grantee = ACL_ID_WORLD;
|
||||
|
||||
idtype = ACL_IDTYPE_WORLD;
|
||||
}
|
||||
aclitem.ai_grantee = ACL_ID_PUBLIC;
|
||||
|
||||
/*
|
||||
* Grant options can only be granted to individual users, not
|
||||
* groups or public. The reason is that if a user would re-grant
|
||||
* a privilege that he held through a group having a grant option,
|
||||
* and later the user is removed from the group, the situation is
|
||||
* impossible to clean up.
|
||||
* Grant options can only be granted to individual roles, not PUBLIC.
|
||||
* The reason is that if a user would re-grant a privilege that he
|
||||
* held through PUBLIC, and later the user is removed, the situation
|
||||
* is impossible to clean up.
|
||||
*/
|
||||
if (is_grant && grant_option && idtype != ACL_IDTYPE_UID)
|
||||
if (is_grant && grant_option && aclitem.ai_grantee == ACL_ID_PUBLIC)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
|
||||
errmsg("grant options can only be granted to individual users")));
|
||||
errmsg("grant options can only be granted to roles")));
|
||||
|
||||
aclitem. ai_grantor = grantor_uid;
|
||||
aclitem.ai_grantor = grantorId;
|
||||
|
||||
/*
|
||||
* The asymmetry in the conditions here comes from the spec. In
|
||||
@@ -166,12 +150,11 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
|
||||
* and its grant option, while REVOKE GRANT OPTION revokes only
|
||||
* the option.
|
||||
*/
|
||||
ACLITEM_SET_PRIVS_IDTYPE(aclitem,
|
||||
ACLITEM_SET_PRIVS_GOPTIONS(aclitem,
|
||||
(is_grant || !grant_option) ? privileges : ACL_NO_RIGHTS,
|
||||
(!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS,
|
||||
idtype);
|
||||
(!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS);
|
||||
|
||||
newer_acl = aclupdate(new_acl, &aclitem, modechg, owner_uid, behavior);
|
||||
newer_acl = aclupdate(new_acl, &aclitem, modechg, ownerId, behavior);
|
||||
|
||||
/* avoid memory leak when there are many grantees */
|
||||
pfree(new_acl);
|
||||
@@ -261,8 +244,8 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_class];
|
||||
char nulls[Natts_pg_class];
|
||||
@@ -430,8 +413,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_database];
|
||||
char nulls[Natts_pg_database];
|
||||
@@ -587,8 +570,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_proc];
|
||||
char nulls[Natts_pg_proc];
|
||||
@@ -740,8 +723,8 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_language];
|
||||
char nulls[Natts_pg_language];
|
||||
@@ -767,7 +750,7 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
|
||||
* Note: for now, languages are treated as owned by the bootstrap
|
||||
* user. We should add an owner column to pg_language instead.
|
||||
*/
|
||||
ownerId = BOOTSTRAP_USESYSID;
|
||||
ownerId = BOOTSTRAP_SUPERUSERID;
|
||||
grantorId = select_grantor(ownerId);
|
||||
|
||||
/*
|
||||
@@ -903,8 +886,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_namespace];
|
||||
char nulls[Natts_pg_namespace];
|
||||
@@ -1059,8 +1042,8 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
|
||||
AclMode this_privileges;
|
||||
Acl *old_acl;
|
||||
Acl *new_acl;
|
||||
AclId grantorId;
|
||||
AclId ownerId;
|
||||
Oid grantorId;
|
||||
Oid ownerId;
|
||||
HeapTuple newtuple;
|
||||
Datum values[Natts_pg_tablespace];
|
||||
char nulls[Natts_pg_tablespace];
|
||||
@@ -1207,27 +1190,6 @@ privilege_to_string(AclMode privilege)
|
||||
return NULL; /* appease compiler */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert group ID to name, or return NULL if group can't be found
|
||||
*/
|
||||
char *
|
||||
get_groname(AclId grosysid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
char *name = NULL;
|
||||
|
||||
tuple = SearchSysCache(GROSYSID,
|
||||
ObjectIdGetDatum(grosysid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname));
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Standardized reporting of aclcheck permissions failures.
|
||||
*
|
||||
@@ -1310,26 +1272,26 @@ aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
|
||||
}
|
||||
|
||||
|
||||
/* Check if given userid has usecatupd privilege according to pg_shadow */
|
||||
/* Check if given user has rolcatupdate privilege according to pg_authid */
|
||||
static bool
|
||||
has_usecatupd(AclId userid)
|
||||
has_rolcatupdate(Oid roleid)
|
||||
{
|
||||
bool usecatupd;
|
||||
bool rolcatupdate;
|
||||
HeapTuple tuple;
|
||||
|
||||
tuple = SearchSysCache(SHADOWSYSID,
|
||||
ObjectIdGetDatum(userid),
|
||||
tuple = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(roleid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("user with ID %u does not exist", userid)));
|
||||
errmsg("role with OID %u does not exist", roleid)));
|
||||
|
||||
usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd;
|
||||
rolcatupdate = ((Form_pg_authid) GETSTRUCT(tuple))->rolcatupdate;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return usecatupd;
|
||||
return rolcatupdate;
|
||||
}
|
||||
|
||||
|
||||
@@ -1344,7 +1306,7 @@ has_usecatupd(AclId userid)
|
||||
* below.
|
||||
*/
|
||||
AclMode
|
||||
pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
pg_class_aclmask(Oid table_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1353,7 +1315,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/*
|
||||
* Must get the relation's tuple from pg_class
|
||||
@@ -1370,7 +1332,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
|
||||
/*
|
||||
* Deny anyone permission to update a system catalog unless
|
||||
* pg_shadow.usecatupd is set. (This is to let superusers protect
|
||||
* pg_authid.rolcatupdate is set. (This is to let superusers protect
|
||||
* themselves from themselves.) Also allow it if
|
||||
* allowSystemTableMods.
|
||||
*
|
||||
@@ -1381,7 +1343,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
|
||||
IsSystemClass(classForm) &&
|
||||
classForm->relkind != RELKIND_VIEW &&
|
||||
!has_usecatupd(userid) &&
|
||||
!has_rolcatupdate(roleid) &&
|
||||
!allowSystemTableMods)
|
||||
{
|
||||
#ifdef ACLDEBUG
|
||||
@@ -1393,10 +1355,10 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
/*
|
||||
* Otherwise, superusers bypass all permission-checking.
|
||||
*/
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
{
|
||||
#ifdef ACLDEBUG
|
||||
elog(DEBUG2, "%u is superuser, home free", userid);
|
||||
elog(DEBUG2, "OID %u is superuser, home free", roleid);
|
||||
#endif
|
||||
ReleaseSysCache(tuple);
|
||||
return mask;
|
||||
@@ -1421,7 +1383,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1436,7 +1398,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
|
||||
* Exported routine for examining a user's privileges for a database
|
||||
*/
|
||||
AclMode
|
||||
pg_database_aclmask(Oid db_oid, AclId userid,
|
||||
pg_database_aclmask(Oid db_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1447,10 +1409,10 @@ pg_database_aclmask(Oid db_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return mask;
|
||||
|
||||
/*
|
||||
@@ -1487,7 +1449,7 @@ pg_database_aclmask(Oid db_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1503,7 +1465,7 @@ pg_database_aclmask(Oid db_oid, AclId userid,
|
||||
* Exported routine for examining a user's privileges for a function
|
||||
*/
|
||||
AclMode
|
||||
pg_proc_aclmask(Oid proc_oid, AclId userid,
|
||||
pg_proc_aclmask(Oid proc_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1511,10 +1473,10 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return mask;
|
||||
|
||||
/*
|
||||
@@ -1544,7 +1506,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1559,7 +1521,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
|
||||
* Exported routine for examining a user's privileges for a language
|
||||
*/
|
||||
AclMode
|
||||
pg_language_aclmask(Oid lang_oid, AclId userid,
|
||||
pg_language_aclmask(Oid lang_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1567,10 +1529,10 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return mask;
|
||||
|
||||
/*
|
||||
@@ -1585,7 +1547,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
|
||||
errmsg("language with OID %u does not exist", lang_oid)));
|
||||
|
||||
/* XXX pg_language should have an owner column, but doesn't */
|
||||
ownerId = BOOTSTRAP_USESYSID;
|
||||
ownerId = BOOTSTRAP_SUPERUSERID;
|
||||
|
||||
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
|
||||
&isNull);
|
||||
@@ -1601,7 +1563,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1616,7 +1578,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
|
||||
* Exported routine for examining a user's privileges for a namespace
|
||||
*/
|
||||
AclMode
|
||||
pg_namespace_aclmask(Oid nsp_oid, AclId userid,
|
||||
pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1624,10 +1586,10 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return mask;
|
||||
|
||||
/*
|
||||
@@ -1685,7 +1647,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1700,7 +1662,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
|
||||
* Exported routine for examining a user's privileges for a tablespace
|
||||
*/
|
||||
AclMode
|
||||
pg_tablespace_aclmask(Oid spc_oid, AclId userid,
|
||||
pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
|
||||
AclMode mask, AclMaskHow how)
|
||||
{
|
||||
AclMode result;
|
||||
@@ -1711,7 +1673,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
|
||||
Datum aclDatum;
|
||||
bool isNull;
|
||||
Acl *acl;
|
||||
AclId ownerId;
|
||||
Oid ownerId;
|
||||
|
||||
/*
|
||||
* Only shared relations can be stored in global space; don't let even
|
||||
@@ -1721,7 +1683,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
|
||||
return 0;
|
||||
|
||||
/* Otherwise, superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return mask;
|
||||
|
||||
/*
|
||||
@@ -1758,7 +1720,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
|
||||
acl = DatumGetAclP(aclDatum);
|
||||
}
|
||||
|
||||
result = aclmask(acl, userid, ownerId, mask, how);
|
||||
result = aclmask(acl, roleid, ownerId, mask, how);
|
||||
|
||||
/* if we have a detoasted copy, free it */
|
||||
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
|
||||
@@ -1779,9 +1741,9 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
|
||||
* ACLCHECK_NO_PRIV).
|
||||
*/
|
||||
AclResult
|
||||
pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode)
|
||||
pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_class_aclmask(table_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1791,9 +1753,9 @@ pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode)
|
||||
* Exported routine for checking a user's access privileges to a database
|
||||
*/
|
||||
AclResult
|
||||
pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
|
||||
pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_database_aclmask(db_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1803,9 +1765,9 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
|
||||
* Exported routine for checking a user's access privileges to a function
|
||||
*/
|
||||
AclResult
|
||||
pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode)
|
||||
pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_proc_aclmask(proc_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1815,9 +1777,9 @@ pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode)
|
||||
* Exported routine for checking a user's access privileges to a language
|
||||
*/
|
||||
AclResult
|
||||
pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode)
|
||||
pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_language_aclmask(lang_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1827,9 +1789,9 @@ pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode)
|
||||
* Exported routine for checking a user's access privileges to a namespace
|
||||
*/
|
||||
AclResult
|
||||
pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode)
|
||||
pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_namespace_aclmask(nsp_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1839,9 +1801,9 @@ pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode)
|
||||
* Exported routine for checking a user's access privileges to a tablespace
|
||||
*/
|
||||
AclResult
|
||||
pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode)
|
||||
pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
|
||||
{
|
||||
if (pg_tablespace_aclmask(spc_oid, userid, mode, ACLMASK_ANY) != 0)
|
||||
if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0)
|
||||
return ACLCHECK_OK;
|
||||
else
|
||||
return ACLCHECK_NO_PRIV;
|
||||
@@ -1852,13 +1814,13 @@ pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode)
|
||||
* Ownership check for a relation (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_class_ownercheck(Oid class_oid, AclId userid)
|
||||
pg_class_ownercheck(Oid class_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(RELOID,
|
||||
@@ -1869,24 +1831,24 @@ pg_class_ownercheck(Oid class_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_TABLE),
|
||||
errmsg("relation with OID %u does not exist", class_oid)));
|
||||
|
||||
owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
||||
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a type (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_type_ownercheck(Oid type_oid, AclId userid)
|
||||
pg_type_ownercheck(Oid type_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(TYPEOID,
|
||||
@@ -1897,24 +1859,24 @@ pg_type_ownercheck(Oid type_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("type with OID %u does not exist", type_oid)));
|
||||
|
||||
owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
|
||||
ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for an operator (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_oper_ownercheck(Oid oper_oid, AclId userid)
|
||||
pg_oper_ownercheck(Oid oper_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(OPEROID,
|
||||
@@ -1925,24 +1887,24 @@ pg_oper_ownercheck(Oid oper_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("operator with OID %u does not exist", oper_oid)));
|
||||
|
||||
owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
|
||||
ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a function (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_proc_ownercheck(Oid proc_oid, AclId userid)
|
||||
pg_proc_ownercheck(Oid proc_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(PROCOID,
|
||||
@@ -1953,24 +1915,24 @@ pg_proc_ownercheck(Oid proc_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||
errmsg("function with OID %u does not exist", proc_oid)));
|
||||
|
||||
owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
|
||||
ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a namespace (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
|
||||
pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(NAMESPACEOID,
|
||||
@@ -1981,27 +1943,27 @@ pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_SCHEMA),
|
||||
errmsg("schema with OID %u does not exist", nsp_oid)));
|
||||
|
||||
owner_id = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
|
||||
ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a tablespace (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_tablespace_ownercheck(Oid spc_oid, AclId userid)
|
||||
pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
|
||||
{
|
||||
Relation pg_tablespace;
|
||||
ScanKeyData entry[1];
|
||||
HeapScanDesc scan;
|
||||
HeapTuple spctuple;
|
||||
int32 spcowner;
|
||||
Oid spcowner;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
/* There's no syscache for pg_tablespace, so must look the hard way */
|
||||
@@ -2024,20 +1986,20 @@ pg_tablespace_ownercheck(Oid spc_oid, AclId userid)
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_tablespace, AccessShareLock);
|
||||
|
||||
return userid == spcowner;
|
||||
return is_member_of_role(roleid, spcowner);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for an operator class (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_opclass_ownercheck(Oid opc_oid, AclId userid)
|
||||
pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(CLAOID,
|
||||
@@ -2049,27 +2011,27 @@ pg_opclass_ownercheck(Oid opc_oid, AclId userid)
|
||||
errmsg("operator class with OID %u does not exist",
|
||||
opc_oid)));
|
||||
|
||||
owner_id = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
|
||||
ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a database (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_database_ownercheck(Oid db_oid, AclId userid)
|
||||
pg_database_ownercheck(Oid db_oid, Oid roleid)
|
||||
{
|
||||
Relation pg_database;
|
||||
ScanKeyData entry[1];
|
||||
HeapScanDesc scan;
|
||||
HeapTuple dbtuple;
|
||||
int32 dba;
|
||||
Oid dba;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
/* There's no syscache for pg_database, so must look the hard way */
|
||||
@@ -2092,20 +2054,20 @@ pg_database_ownercheck(Oid db_oid, AclId userid)
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_database, AccessShareLock);
|
||||
|
||||
return userid == dba;
|
||||
return is_member_of_role(roleid, dba);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ownership check for a conversion (specified by OID).
|
||||
*/
|
||||
bool
|
||||
pg_conversion_ownercheck(Oid conv_oid, AclId userid)
|
||||
pg_conversion_ownercheck(Oid conv_oid, Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
AclId owner_id;
|
||||
Oid ownerId;
|
||||
|
||||
/* Superusers bypass all permission checking. */
|
||||
if (superuser_arg(userid))
|
||||
if (superuser_arg(roleid))
|
||||
return true;
|
||||
|
||||
tuple = SearchSysCache(CONOID,
|
||||
@@ -2116,9 +2078,9 @@ pg_conversion_ownercheck(Oid conv_oid, AclId userid)
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("conversion with OID %u does not exist", conv_oid)));
|
||||
|
||||
owner_id = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
|
||||
ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
return userid == owner_id;
|
||||
return is_member_of_role(roleid, ownerId);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.36 2005/04/14 20:03:23 tgl Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.37 2005/06/28 05:08:52 tgl Exp $
|
||||
#
|
||||
# NOTES
|
||||
# non-essential whitespace is removed from the generated file.
|
||||
@@ -114,6 +114,14 @@ for dir in $INCLUDE_DIRS; do
|
||||
fi
|
||||
done
|
||||
|
||||
# Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
|
||||
for dir in $INCLUDE_DIRS; do
|
||||
if [ -f "$dir/catalog/pg_authid.h" ]; then
|
||||
BOOTSTRAP_SUPERUSERID=`grep '^#define[ ]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'`
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
|
||||
for dir in $INCLUDE_DIRS; do
|
||||
if [ -f "$dir/catalog/pg_namespace.h" ]; then
|
||||
@@ -153,7 +161,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/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
|
||||
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
|
||||
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
|
||||
| $AWK '
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.28 2005/05/31 03:36:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.29 2005/06/28 05:08:52 tgl Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -210,13 +210,13 @@ CREATE DOMAIN time_stamp AS timestamp(2)
|
||||
|
||||
CREATE VIEW applicable_roles AS
|
||||
SELECT CAST(current_user AS sql_identifier) AS grantee,
|
||||
CAST(g.groname AS sql_identifier) AS role_name,
|
||||
CAST('NO' AS character_data) AS is_grantable
|
||||
CAST(a.rolname AS sql_identifier) AS role_name,
|
||||
CAST(CASE WHEN m.admin_option = 'true' THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_group g, pg_user u
|
||||
FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid))
|
||||
join pg_authid b ON (m.member = b.oid))
|
||||
|
||||
WHERE u.usesysid = ANY (g.grolist)
|
||||
AND u.usename = current_user;
|
||||
WHERE b.rolname = current_user;
|
||||
|
||||
GRANT SELECT ON applicable_roles TO PUBLIC;
|
||||
|
||||
@@ -282,7 +282,7 @@ GRANT SELECT ON column_domain_usage TO PUBLIC;
|
||||
*/
|
||||
|
||||
CREATE VIEW column_privileges AS
|
||||
SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
|
||||
SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
|
||||
CAST(grantee.name AS sql_identifier) AS grantee,
|
||||
CAST(current_database() AS sql_identifier) AS table_catalog,
|
||||
CAST(nc.nspname AS sql_identifier) AS table_schema,
|
||||
@@ -291,20 +291,18 @@ CREATE VIEW column_privileges AS
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_attribute a,
|
||||
pg_class c,
|
||||
pg_namespace nc,
|
||||
pg_user u_grantor,
|
||||
pg_authid u_grantor,
|
||||
(
|
||||
SELECT usesysid, 0, usename FROM pg_user
|
||||
SELECT oid, rolname FROM pg_authid
|
||||
UNION ALL
|
||||
SELECT 0, grosysid, groname FROM pg_group
|
||||
UNION ALL
|
||||
SELECT 0, 0, 'PUBLIC'
|
||||
) AS grantee (usesysid, grosysid, name),
|
||||
SELECT 0, 'PUBLIC'
|
||||
) AS grantee (oid, name),
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
SELECT 'UPDATE' UNION ALL
|
||||
@@ -316,8 +314,8 @@ CREATE VIEW column_privileges AS
|
||||
AND NOT a.attisdropped
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
AND (u_grantor.usename = current_user
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
|
||||
AND (u_grantor.rolname = current_user
|
||||
OR grantee.name = current_user
|
||||
OR grantee.name = 'PUBLIC');
|
||||
|
||||
@@ -693,10 +691,10 @@ GRANT SELECT ON domains TO PUBLIC;
|
||||
*/
|
||||
|
||||
CREATE VIEW enabled_roles AS
|
||||
SELECT CAST(g.groname AS sql_identifier) AS role_name
|
||||
FROM pg_group g, pg_user u
|
||||
WHERE u.usesysid = ANY (g.grolist)
|
||||
AND u.usename = current_user;
|
||||
SELECT CAST(a.rolname AS sql_identifier) AS role_name
|
||||
FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid))
|
||||
join pg_authid b ON (m.member = b.oid))
|
||||
WHERE b.rolname = current_user;
|
||||
|
||||
GRANT SELECT ON enabled_roles TO PUBLIC;
|
||||
|
||||
@@ -865,7 +863,7 @@ CREATE VIEW role_column_grants AS
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_attribute a,
|
||||
@@ -884,7 +882,7 @@ CREATE VIEW role_column_grants AS
|
||||
AND NOT a.attisdropped
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
|
||||
|
||||
GRANT SELECT ON role_column_grants TO PUBLIC;
|
||||
@@ -907,7 +905,7 @@ CREATE VIEW role_routine_grants AS
|
||||
CAST('EXECUTE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(p.proacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_proc p,
|
||||
@@ -917,7 +915,7 @@ CREATE VIEW role_routine_grants AS
|
||||
|
||||
WHERE p.pronamespace = n.oid
|
||||
AND aclcontains(p.proacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
|
||||
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
|
||||
|
||||
GRANT SELECT ON role_routine_grants TO PUBLIC;
|
||||
@@ -937,7 +935,7 @@ CREATE VIEW role_table_grants AS
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
|
||||
CAST('NO' AS character_data) AS with_hierarchy
|
||||
|
||||
@@ -956,7 +954,7 @@ CREATE VIEW role_table_grants AS
|
||||
WHERE c.relnamespace = nc.oid
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
|
||||
|
||||
GRANT SELECT ON role_table_grants TO PUBLIC;
|
||||
@@ -990,7 +988,7 @@ GRANT SELECT ON role_usage_grants TO PUBLIC;
|
||||
*/
|
||||
|
||||
CREATE VIEW routine_privileges AS
|
||||
SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
|
||||
SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
|
||||
CAST(grantee.name AS sql_identifier) AS grantee,
|
||||
CAST(current_database() AS sql_identifier) AS specific_catalog,
|
||||
CAST(n.nspname AS sql_identifier) AS specific_schema,
|
||||
@@ -1001,24 +999,22 @@ CREATE VIEW routine_privileges AS
|
||||
CAST('EXECUTE' AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(p.proacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
|
||||
|
||||
FROM pg_proc p,
|
||||
pg_namespace n,
|
||||
pg_user u_grantor,
|
||||
pg_authid u_grantor,
|
||||
(
|
||||
SELECT usesysid, 0, usename FROM pg_user
|
||||
SELECT oid, rolname FROM pg_authid
|
||||
UNION ALL
|
||||
SELECT 0, grosysid, groname FROM pg_group
|
||||
UNION ALL
|
||||
SELECT 0, 0, 'PUBLIC'
|
||||
) AS grantee (usesysid, grosysid, name)
|
||||
SELECT 0, 'PUBLIC'
|
||||
) AS grantee (oid, name)
|
||||
|
||||
WHERE p.pronamespace = n.oid
|
||||
AND aclcontains(p.proacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
|
||||
AND (u_grantor.usename = current_user
|
||||
makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', false))
|
||||
AND (u_grantor.rolname = current_user
|
||||
OR grantee.name = current_user
|
||||
OR grantee.name = 'PUBLIC');
|
||||
|
||||
@@ -1338,7 +1334,7 @@ GRANT SELECT ON table_constraints TO PUBLIC;
|
||||
*/
|
||||
|
||||
CREATE VIEW table_privileges AS
|
||||
SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
|
||||
SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
|
||||
CAST(grantee.name AS sql_identifier) AS grantee,
|
||||
CAST(current_database() AS sql_identifier) AS table_catalog,
|
||||
CAST(nc.nspname AS sql_identifier) AS table_schema,
|
||||
@@ -1346,20 +1342,18 @@ CREATE VIEW table_privileges AS
|
||||
CAST(pr.type AS character_data) AS privilege_type,
|
||||
CAST(
|
||||
CASE WHEN aclcontains(c.relacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true))
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
|
||||
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
|
||||
CAST('NO' AS character_data) AS with_hierarchy
|
||||
|
||||
FROM pg_class c,
|
||||
pg_namespace nc,
|
||||
pg_user u_grantor,
|
||||
pg_authid u_grantor,
|
||||
(
|
||||
SELECT usesysid, 0, usename FROM pg_user
|
||||
SELECT oid, rolname FROM pg_authid
|
||||
UNION ALL
|
||||
SELECT 0, grosysid, groname FROM pg_group
|
||||
UNION ALL
|
||||
SELECT 0, 0, 'PUBLIC'
|
||||
) AS grantee (usesysid, grosysid, name),
|
||||
SELECT 0, 'PUBLIC'
|
||||
) AS grantee (oid, name),
|
||||
(SELECT 'SELECT' UNION ALL
|
||||
SELECT 'DELETE' UNION ALL
|
||||
SELECT 'INSERT' UNION ALL
|
||||
@@ -1371,8 +1365,8 @@ CREATE VIEW table_privileges AS
|
||||
WHERE c.relnamespace = nc.oid
|
||||
AND c.relkind IN ('r', 'v')
|
||||
AND aclcontains(c.relacl,
|
||||
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false))
|
||||
AND (u_grantor.usename = current_user
|
||||
makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
|
||||
AND (u_grantor.rolname = current_user
|
||||
OR grantee.name = current_user
|
||||
OR grantee.name = 'PUBLIC');
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.75 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.76 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -22,12 +22,12 @@
|
||||
#include "access/xact.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_opclass.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "lib/stringinfo.h"
|
||||
@@ -1499,7 +1499,7 @@ FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
|
||||
static void
|
||||
recomputeNamespacePath(void)
|
||||
{
|
||||
AclId userId = GetUserId();
|
||||
Oid roleid = GetUserId();
|
||||
char *rawname;
|
||||
List *namelist;
|
||||
List *oidlist;
|
||||
@@ -1511,7 +1511,7 @@ recomputeNamespacePath(void)
|
||||
/*
|
||||
* Do nothing if path is already valid.
|
||||
*/
|
||||
if (namespaceSearchPathValid && namespaceUser == userId)
|
||||
if (namespaceSearchPathValid && namespaceUser == roleid)
|
||||
return;
|
||||
|
||||
/* Need a modifiable copy of namespace_search_path string */
|
||||
@@ -1542,21 +1542,21 @@ recomputeNamespacePath(void)
|
||||
/* $user --- substitute namespace matching user name, if any */
|
||||
HeapTuple tuple;
|
||||
|
||||
tuple = SearchSysCache(SHADOWSYSID,
|
||||
ObjectIdGetDatum(userId),
|
||||
tuple = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(roleid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(tuple))
|
||||
{
|
||||
char *uname;
|
||||
char *rname;
|
||||
|
||||
uname = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
|
||||
rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
|
||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
||||
CStringGetDatum(uname),
|
||||
CStringGetDatum(rname),
|
||||
0, 0, 0);
|
||||
ReleaseSysCache(tuple);
|
||||
if (OidIsValid(namespaceId) &&
|
||||
!list_member_oid(oidlist, namespaceId) &&
|
||||
pg_namespace_aclcheck(namespaceId, userId,
|
||||
pg_namespace_aclcheck(namespaceId, roleid,
|
||||
ACL_USAGE) == ACLCHECK_OK)
|
||||
oidlist = lappend_oid(oidlist, namespaceId);
|
||||
}
|
||||
@@ -1569,7 +1569,7 @@ recomputeNamespacePath(void)
|
||||
0, 0, 0);
|
||||
if (OidIsValid(namespaceId) &&
|
||||
!list_member_oid(oidlist, namespaceId) &&
|
||||
pg_namespace_aclcheck(namespaceId, userId,
|
||||
pg_namespace_aclcheck(namespaceId, roleid,
|
||||
ACL_USAGE) == ACLCHECK_OK)
|
||||
oidlist = lappend_oid(oidlist, namespaceId);
|
||||
}
|
||||
@@ -1622,7 +1622,7 @@ recomputeNamespacePath(void)
|
||||
|
||||
/* Mark the path valid. */
|
||||
namespaceSearchPathValid = true;
|
||||
namespaceUser = userId;
|
||||
namespaceUser = roleid;
|
||||
|
||||
/* Clean up. */
|
||||
pfree(rawname);
|
||||
@@ -1674,7 +1674,7 @@ InitTempTableNamespace(void)
|
||||
* that access the temp namespace for my own backend skip
|
||||
* permissions checks on it.
|
||||
*/
|
||||
namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
|
||||
namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
|
||||
/* Advance command counter to make namespace visible */
|
||||
CommandCounterIncrement();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.23 2005/05/27 00:57:49 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.24 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -36,7 +36,7 @@
|
||||
*/
|
||||
Oid
|
||||
ConversionCreate(const char *conname, Oid connamespace,
|
||||
AclId conowner,
|
||||
Oid conowner,
|
||||
int32 conforencoding, int32 contoencoding,
|
||||
Oid conproc, bool def)
|
||||
{
|
||||
@@ -95,7 +95,7 @@ ConversionCreate(const char *conname, Oid connamespace,
|
||||
namestrcpy(&cname, conname);
|
||||
values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname);
|
||||
values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace);
|
||||
values[Anum_pg_conversion_conowner - 1] = Int32GetDatum(conowner);
|
||||
values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner);
|
||||
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
|
||||
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
|
||||
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.13 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.14 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -26,7 +26,7 @@
|
||||
* ---------------
|
||||
*/
|
||||
Oid
|
||||
NamespaceCreate(const char *nspName, int32 ownerSysId)
|
||||
NamespaceCreate(const char *nspName, Oid ownerId)
|
||||
{
|
||||
Relation nspdesc;
|
||||
HeapTuple tup;
|
||||
@@ -57,7 +57,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
|
||||
}
|
||||
namestrcpy(&nname, nspName);
|
||||
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
|
||||
values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId);
|
||||
values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
|
||||
nulls[Anum_pg_namespace_nspacl - 1] = 'n';
|
||||
|
||||
nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.91 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.92 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* these routines moved here from commands/define.c and somewhat cleaned up.
|
||||
@@ -235,7 +235,7 @@ OperatorShellMake(const char *operatorName,
|
||||
namestrcpy(&oname, operatorName);
|
||||
values[i++] = NameGetDatum(&oname); /* oprname */
|
||||
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* oprowner */
|
||||
values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */
|
||||
values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
|
||||
values[i++] = BoolGetDatum(false); /* oprcanhash */
|
||||
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */
|
||||
@@ -519,7 +519,7 @@ OperatorCreate(const char *operatorName,
|
||||
namestrcpy(&oname, operatorName);
|
||||
values[i++] = NameGetDatum(&oname); /* oprname */
|
||||
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* oprowner */
|
||||
values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */
|
||||
values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
|
||||
values[i++] = BoolGetDatum(canHash); /* oprcanhash */
|
||||
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.129 2005/05/03 16:51:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.130 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -217,7 +217,7 @@ ProcedureCreate(const char *procedureName,
|
||||
namestrcpy(&procname, procedureName);
|
||||
values[Anum_pg_proc_proname - 1] = NameGetDatum(&procname);
|
||||
values[Anum_pg_proc_pronamespace - 1] = ObjectIdGetDatum(procNamespace);
|
||||
values[Anum_pg_proc_proowner - 1] = Int32GetDatum(GetUserId());
|
||||
values[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(GetUserId());
|
||||
values[Anum_pg_proc_prolang - 1] = ObjectIdGetDatum(languageObjectId);
|
||||
values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg);
|
||||
values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.100 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.101 2005/06/28 05:08:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -227,7 +227,7 @@ TypeCreate(const char *typeName,
|
||||
namestrcpy(&name, typeName);
|
||||
values[i++] = NameGetDatum(&name); /* typname */
|
||||
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* typowner */
|
||||
values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
|
||||
values[i++] = Int16GetDatum(internalSize); /* typlen */
|
||||
values[i++] = BoolGetDatum(passedByValue); /* typbyval */
|
||||
values[i++] = CharGetDatum(typeType); /* typtype */
|
||||
|
||||
@@ -3,9 +3,45 @@
|
||||
*
|
||||
* Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.15 2005/06/18 19:33:42 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.16 2005/06/28 05:08:52 tgl Exp $
|
||||
*/
|
||||
|
||||
CREATE VIEW pg_roles AS
|
||||
SELECT
|
||||
rolname,
|
||||
rolsuper,
|
||||
rolcreaterole,
|
||||
rolcreatedb,
|
||||
rolcatupdate,
|
||||
rolcanlogin,
|
||||
'********'::text as rolpassword,
|
||||
rolvaliduntil,
|
||||
rolconfig
|
||||
FROM pg_authid;
|
||||
|
||||
CREATE VIEW pg_shadow AS
|
||||
SELECT
|
||||
rolname AS usename,
|
||||
oid AS usesysid,
|
||||
rolcreatedb AS usecreatedb,
|
||||
rolsuper AS usesuper,
|
||||
rolcatupdate AS usecatupd,
|
||||
rolpassword AS passwd,
|
||||
rolvaliduntil::abstime AS valuntil,
|
||||
rolconfig AS useconfig
|
||||
FROM pg_authid
|
||||
WHERE rolcanlogin;
|
||||
|
||||
REVOKE ALL on pg_shadow FROM public;
|
||||
|
||||
CREATE VIEW pg_group AS
|
||||
SELECT
|
||||
rolname AS groname,
|
||||
oid AS grosysid,
|
||||
ARRAY(SELECT member FROM pg_auth_members WHERE roleid = oid) AS grolist
|
||||
FROM pg_authid
|
||||
WHERE NOT rolcanlogin;
|
||||
|
||||
CREATE VIEW pg_user AS
|
||||
SELECT
|
||||
usename,
|
||||
@@ -111,10 +147,10 @@ CREATE VIEW pg_locks AS
|
||||
|
||||
CREATE VIEW pg_prepared_xacts AS
|
||||
SELECT P.transaction, P.gid, P.prepared,
|
||||
U.usename AS owner, D.datname AS database
|
||||
U.rolname AS owner, D.datname AS database
|
||||
FROM pg_prepared_xact() AS P
|
||||
(transaction xid, gid text, prepared timestamptz, ownerid int4, dbid oid)
|
||||
LEFT JOIN pg_shadow U ON P.ownerid = U.usesysid
|
||||
(transaction xid, gid text, prepared timestamptz, ownerid oid, dbid oid)
|
||||
LEFT JOIN pg_authid U ON P.ownerid = U.oid
|
||||
LEFT JOIN pg_database D ON P.dbid = D.oid;
|
||||
|
||||
CREATE VIEW pg_settings AS
|
||||
@@ -269,7 +305,7 @@ CREATE VIEW pg_stat_activity AS
|
||||
D.datname AS datname,
|
||||
pg_stat_get_backend_pid(S.backendid) AS procpid,
|
||||
pg_stat_get_backend_userid(S.backendid) AS usesysid,
|
||||
U.usename AS usename,
|
||||
U.rolname AS usename,
|
||||
pg_stat_get_backend_activity(S.backendid) AS current_query,
|
||||
pg_stat_get_backend_activity_start(S.backendid) AS query_start,
|
||||
pg_stat_get_backend_start(S.backendid) AS backend_start,
|
||||
@@ -277,9 +313,9 @@ CREATE VIEW pg_stat_activity AS
|
||||
pg_stat_get_backend_client_port(S.backendid) AS client_port
|
||||
FROM pg_database D,
|
||||
(SELECT pg_stat_get_backend_idset() AS backendid) AS S,
|
||||
pg_shadow U
|
||||
pg_authid U
|
||||
WHERE pg_stat_get_backend_dbid(S.backendid) = D.oid AND
|
||||
pg_stat_get_backend_userid(S.backendid) = U.usesysid;
|
||||
pg_stat_get_backend_userid(S.backendid) = U.oid;
|
||||
|
||||
CREATE VIEW pg_stat_database AS
|
||||
SELECT
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.26 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.27 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@@ -295,7 +295,7 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname)
|
||||
* Change aggregate owner
|
||||
*/
|
||||
void
|
||||
AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
|
||||
AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
|
||||
{
|
||||
Oid basetypeOid;
|
||||
Oid procOid;
|
||||
@@ -329,7 +329,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (procForm->proowner != newOwnerSysId)
|
||||
if (procForm->proowner != newOwnerId)
|
||||
{
|
||||
/* Otherwise, must be superuser to change object ownership */
|
||||
if (!superuser())
|
||||
@@ -341,7 +341,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
|
||||
* Modify the owner --- okay to scribble on tup because it's a
|
||||
* copy
|
||||
*/
|
||||
procForm->proowner = newOwnerSysId;
|
||||
procForm->proowner = newOwnerId;
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
CatalogUpdateIndexes(rel, tup);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.12 2004/12/31 21:59:41 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.13 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -64,10 +64,6 @@ ExecRenameStmt(RenameStmt *stmt)
|
||||
RenameFunction(stmt->object, stmt->objarg, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_GROUP:
|
||||
RenameGroup(stmt->subname, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_LANGUAGE:
|
||||
RenameLanguage(stmt->subname, stmt->newname);
|
||||
break;
|
||||
@@ -76,6 +72,10 @@ ExecRenameStmt(RenameStmt *stmt)
|
||||
RenameOpClass(stmt->object, stmt->subname, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_ROLE:
|
||||
RenameRole(stmt->subname, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_SCHEMA:
|
||||
RenameSchema(stmt->subname, stmt->newname);
|
||||
break;
|
||||
@@ -84,10 +84,6 @@ ExecRenameStmt(RenameStmt *stmt)
|
||||
RenameTableSpace(stmt->subname, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_USER:
|
||||
RenameUser(stmt->subname, stmt->newname);
|
||||
break;
|
||||
|
||||
case OBJECT_TABLE:
|
||||
case OBJECT_INDEX:
|
||||
case OBJECT_COLUMN:
|
||||
@@ -153,7 +149,7 @@ ExecRenameStmt(RenameStmt *stmt)
|
||||
void
|
||||
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
||||
{
|
||||
AclId newowner = get_usesysid(stmt->newowner);
|
||||
Oid newowner = get_roleid_checked(stmt->newowner);
|
||||
|
||||
switch (stmt->objectType)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.18 2005/05/03 19:17:59 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.19 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -175,7 +175,7 @@ RenameConversion(List *name, const char *newname)
|
||||
* Change conversion owner
|
||||
*/
|
||||
void
|
||||
AlterConversionOwner(List *name, AclId newOwnerSysId)
|
||||
AlterConversionOwner(List *name, Oid newOwnerId)
|
||||
{
|
||||
Oid conversionOid;
|
||||
HeapTuple tup;
|
||||
@@ -203,7 +203,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (convForm->conowner != newOwnerSysId)
|
||||
if (convForm->conowner != newOwnerId)
|
||||
{
|
||||
/* Otherwise, must be superuser to change object ownership */
|
||||
if (!superuser())
|
||||
@@ -215,7 +215,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
|
||||
* Modify the owner --- okay to scribble on tup because it's a
|
||||
* copy
|
||||
*/
|
||||
convForm->conowner = newOwnerSysId;
|
||||
convForm->conowner = newOwnerId;
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.245 2005/06/02 01:21:22 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.246 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -25,7 +25,6 @@
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_index.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/copy.h"
|
||||
#include "commands/trigger.h"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.161 2005/06/25 22:47:29 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.162 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -28,10 +28,10 @@
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "commands/comment.h"
|
||||
#include "commands/dbcommands.h"
|
||||
#include "commands/tablespace.h"
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
|
||||
/* non-export function prototypes */
|
||||
static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
|
||||
static bool get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP,
|
||||
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
|
||||
Oid *dbLastSysOidP,
|
||||
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
|
||||
@@ -70,7 +70,7 @@ createdb(const CreatedbStmt *stmt)
|
||||
HeapScanDesc scan;
|
||||
Relation rel;
|
||||
Oid src_dboid;
|
||||
AclId src_owner;
|
||||
Oid src_owner;
|
||||
int src_encoding;
|
||||
bool src_istemplate;
|
||||
bool src_allowconn;
|
||||
@@ -85,7 +85,7 @@ createdb(const CreatedbStmt *stmt)
|
||||
Datum new_record[Natts_pg_database];
|
||||
char new_record_nulls[Natts_pg_database];
|
||||
Oid dboid;
|
||||
AclId datdba;
|
||||
Oid datdba;
|
||||
ListCell *option;
|
||||
DefElem *dtablespacename = NULL;
|
||||
DefElem *downer = NULL;
|
||||
@@ -186,13 +186,13 @@ createdb(const CreatedbStmt *stmt)
|
||||
nodeTag(dencoding->arg));
|
||||
}
|
||||
|
||||
/* obtain sysid of proposed owner */
|
||||
/* obtain OID of proposed owner */
|
||||
if (dbowner)
|
||||
datdba = get_usesysid(dbowner); /* will ereport if no such user */
|
||||
datdba = get_roleid_checked(dbowner);
|
||||
else
|
||||
datdba = GetUserId();
|
||||
|
||||
if (datdba == GetUserId())
|
||||
if (is_member_of_role(GetUserId(), datdba))
|
||||
{
|
||||
/* creating database for self: can be superuser or createdb */
|
||||
if (!superuser() && !have_createdb_privilege())
|
||||
@@ -243,7 +243,7 @@ createdb(const CreatedbStmt *stmt)
|
||||
*/
|
||||
if (!src_istemplate)
|
||||
{
|
||||
if (!superuser() && GetUserId() != src_owner)
|
||||
if (!pg_database_ownercheck(src_dboid, GetUserId()))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied to copy database \"%s\"",
|
||||
@@ -483,7 +483,7 @@ createdb(const CreatedbStmt *stmt)
|
||||
|
||||
new_record[Anum_pg_database_datname - 1] =
|
||||
DirectFunctionCall1(namein, CStringGetDatum(dbname));
|
||||
new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(datdba);
|
||||
new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
|
||||
new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
|
||||
new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
|
||||
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
|
||||
@@ -557,9 +557,8 @@ createdb(const CreatedbStmt *stmt)
|
||||
void
|
||||
dropdb(const char *dbname)
|
||||
{
|
||||
int4 db_owner;
|
||||
bool db_istemplate;
|
||||
Oid db_id;
|
||||
bool db_istemplate;
|
||||
Relation pgdbrel;
|
||||
SysScanDesc pgdbscan;
|
||||
ScanKeyData key;
|
||||
@@ -588,13 +587,13 @@ dropdb(const char *dbname)
|
||||
*/
|
||||
pgdbrel = heap_open(DatabaseRelationId, ExclusiveLock);
|
||||
|
||||
if (!get_db_info(dbname, &db_id, &db_owner, NULL,
|
||||
if (!get_db_info(dbname, &db_id, NULL, NULL,
|
||||
&db_istemplate, NULL, NULL, NULL, NULL, NULL))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
||||
errmsg("database \"%s\" does not exist", dbname)));
|
||||
|
||||
if (GetUserId() != db_owner && !superuser())
|
||||
if (!pg_database_ownercheck(db_id, GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
|
||||
dbname);
|
||||
|
||||
@@ -818,8 +817,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||
(errcode(ERRCODE_UNDEFINED_DATABASE),
|
||||
errmsg("database \"%s\" does not exist", stmt->dbname)));
|
||||
|
||||
if (!(superuser()
|
||||
|| ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId()))
|
||||
if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
|
||||
stmt->dbname);
|
||||
|
||||
@@ -878,7 +876,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
|
||||
* ALTER DATABASE name OWNER TO newowner
|
||||
*/
|
||||
void
|
||||
AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
|
||||
AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
Relation rel;
|
||||
@@ -910,7 +908,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
|
||||
* command to have succeeded. This is to be consistent with other
|
||||
* objects.
|
||||
*/
|
||||
if (datForm->datdba != newOwnerSysId)
|
||||
if (datForm->datdba != newOwnerId)
|
||||
{
|
||||
Datum repl_val[Natts_pg_database];
|
||||
char repl_null[Natts_pg_database];
|
||||
@@ -930,7 +928,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
|
||||
repl_repl[Anum_pg_database_datdba - 1] = 'r';
|
||||
repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId);
|
||||
repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwnerId);
|
||||
|
||||
/*
|
||||
* Determine the modified ACL for the new owner. This is only
|
||||
@@ -943,7 +941,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
|
||||
if (!isNull)
|
||||
{
|
||||
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
||||
datForm->datdba, newOwnerSysId);
|
||||
datForm->datdba, newOwnerId);
|
||||
repl_repl[Anum_pg_database_datacl - 1] = 'r';
|
||||
repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);
|
||||
}
|
||||
@@ -972,7 +970,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
|
||||
*/
|
||||
|
||||
static bool
|
||||
get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
|
||||
get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP,
|
||||
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
|
||||
Oid *dbLastSysOidP,
|
||||
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
|
||||
@@ -1007,7 +1005,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
|
||||
/* oid of the database */
|
||||
if (dbIdP)
|
||||
*dbIdP = HeapTupleGetOid(tuple);
|
||||
/* sysid of the owner */
|
||||
/* oid of the owner */
|
||||
if (ownerIdP)
|
||||
*ownerIdP = dbform->datdba;
|
||||
/* character encoding */
|
||||
@@ -1046,12 +1044,12 @@ have_createdb_privilege(void)
|
||||
bool result = false;
|
||||
HeapTuple utup;
|
||||
|
||||
utup = SearchSysCache(SHADOWSYSID,
|
||||
Int32GetDatum(GetUserId()),
|
||||
utup = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(GetUserId()),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(utup))
|
||||
{
|
||||
result = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
|
||||
result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb;
|
||||
ReleaseSysCache(utup);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.61 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* These routines take the parse tree and pick out the
|
||||
@@ -853,7 +853,7 @@ RenameFunction(List *name, List *argtypes, const char *newname)
|
||||
* Change function owner
|
||||
*/
|
||||
void
|
||||
AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
|
||||
AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
|
||||
{
|
||||
Oid procOid;
|
||||
HeapTuple tup;
|
||||
@@ -882,7 +882,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (procForm->proowner != newOwnerSysId)
|
||||
if (procForm->proowner != newOwnerId)
|
||||
{
|
||||
Datum repl_val[Natts_pg_proc];
|
||||
char repl_null[Natts_pg_proc];
|
||||
@@ -902,7 +902,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
|
||||
repl_repl[Anum_pg_proc_proowner - 1] = 'r';
|
||||
repl_val[Anum_pg_proc_proowner - 1] = Int32GetDatum(newOwnerSysId);
|
||||
repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId);
|
||||
|
||||
/*
|
||||
* Determine the modified ACL for the new owner. This is only
|
||||
@@ -914,7 +914,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
|
||||
if (!isNull)
|
||||
{
|
||||
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
||||
procForm->proowner, newOwnerSysId);
|
||||
procForm->proowner, newOwnerId);
|
||||
repl_repl[Anum_pg_proc_proacl - 1] = 'r';
|
||||
repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.32 2005/04/14 20:03:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:53 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -321,7 +321,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
||||
namestrcpy(&opcName, opcname);
|
||||
values[i++] = NameGetDatum(&opcName); /* opcname */
|
||||
values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */
|
||||
values[i++] = Int32GetDatum(GetUserId()); /* opcowner */
|
||||
values[i++] = ObjectIdGetDatum(GetUserId()); /* opcowner */
|
||||
values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */
|
||||
values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */
|
||||
values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */
|
||||
@@ -880,7 +880,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
|
||||
* Change opclass owner
|
||||
*/
|
||||
void
|
||||
AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
|
||||
AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
|
||||
{
|
||||
Oid opcOid;
|
||||
Oid amOid;
|
||||
@@ -945,7 +945,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (opcForm->opcowner != newOwnerSysId)
|
||||
if (opcForm->opcowner != newOwnerId)
|
||||
{
|
||||
/* Otherwise, must be superuser to change object ownership */
|
||||
if (!superuser())
|
||||
@@ -957,7 +957,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
|
||||
* Modify the owner --- okay to scribble on tup because it's a
|
||||
* copy
|
||||
*/
|
||||
opcForm->opcowner = newOwnerSysId;
|
||||
opcForm->opcowner = newOwnerId;
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.21 2005/04/14 20:03:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:54 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@@ -269,7 +269,7 @@ RemoveOperatorById(Oid operOid)
|
||||
*/
|
||||
void
|
||||
AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
|
||||
AclId newOwnerSysId)
|
||||
Oid newOwnerId)
|
||||
{
|
||||
Oid operOid;
|
||||
HeapTuple tup;
|
||||
@@ -293,7 +293,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (oprForm->oprowner != newOwnerSysId)
|
||||
if (oprForm->oprowner != newOwnerId)
|
||||
{
|
||||
/* Otherwise, must be superuser to change object ownership */
|
||||
if (!superuser())
|
||||
@@ -305,7 +305,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
|
||||
* Modify the owner --- okay to scribble on tup because it's a
|
||||
* copy
|
||||
*/
|
||||
oprForm->oprowner = newOwnerSysId;
|
||||
oprForm->oprowner = newOwnerId;
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.30 2005/06/21 00:58:15 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.31 2005/06/28 05:08:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -42,11 +42,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
Oid namespaceId;
|
||||
List *parsetree_list;
|
||||
ListCell *parsetree_item;
|
||||
AclId owner_userid;
|
||||
AclId saved_userid;
|
||||
Oid owner_uid;
|
||||
Oid saved_uid;
|
||||
AclResult aclresult;
|
||||
|
||||
saved_userid = GetUserId();
|
||||
saved_uid = GetUserId();
|
||||
|
||||
/*
|
||||
* Figure out user identities.
|
||||
@@ -54,12 +54,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
|
||||
if (!authId)
|
||||
{
|
||||
owner_userid = saved_userid;
|
||||
owner_uid = saved_uid;
|
||||
}
|
||||
else if (superuser())
|
||||
{
|
||||
/* The following will error out if user does not exist */
|
||||
owner_userid = get_usesysid(authId);
|
||||
owner_uid = get_roleid_checked(authId);
|
||||
|
||||
/*
|
||||
* Set the current user to the requested authorization so that
|
||||
@@ -67,15 +66,15 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
* (This will revert to session user on error or at the end of
|
||||
* this routine.)
|
||||
*/
|
||||
SetUserId(owner_userid);
|
||||
SetUserId(owner_uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *owner_name;
|
||||
|
||||
/* not superuser */
|
||||
owner_userid = saved_userid;
|
||||
owner_name = GetUserNameFromId(owner_userid);
|
||||
owner_uid = saved_uid;
|
||||
owner_name = GetUserNameFromId(owner_uid);
|
||||
if (strcmp(authId, owner_name) != 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
@@ -87,7 +86,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
/*
|
||||
* Permissions checks.
|
||||
*/
|
||||
aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE);
|
||||
aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_DATABASE,
|
||||
get_database_name(MyDatabaseId));
|
||||
@@ -99,7 +98,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
|
||||
|
||||
/* Create the schema's namespace */
|
||||
namespaceId = NamespaceCreate(schemaName, owner_userid);
|
||||
namespaceId = NamespaceCreate(schemaName, owner_uid);
|
||||
|
||||
/* Advance cmd counter to make the namespace visible */
|
||||
CommandCounterIncrement();
|
||||
@@ -149,7 +148,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||
PopSpecialNamespace(namespaceId);
|
||||
|
||||
/* Reset current user */
|
||||
SetUserId(saved_userid);
|
||||
SetUserId(saved_uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +278,7 @@ RenameSchema(const char *oldname, const char *newname)
|
||||
* Change schema owner
|
||||
*/
|
||||
void
|
||||
AlterSchemaOwner(const char *name, AclId newOwnerSysId)
|
||||
AlterSchemaOwner(const char *name, Oid newOwnerId)
|
||||
{
|
||||
HeapTuple tup;
|
||||
Relation rel;
|
||||
@@ -300,7 +299,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (nspForm->nspowner != newOwnerSysId)
|
||||
if (nspForm->nspowner != newOwnerId)
|
||||
{
|
||||
Datum repl_val[Natts_pg_namespace];
|
||||
char repl_null[Natts_pg_namespace];
|
||||
@@ -320,7 +319,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
|
||||
repl_repl[Anum_pg_namespace_nspowner - 1] = 'r';
|
||||
repl_val[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(newOwnerSysId);
|
||||
repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId);
|
||||
|
||||
/*
|
||||
* Determine the modified ACL for the new owner. This is only
|
||||
@@ -332,7 +331,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
|
||||
if (!isNull)
|
||||
{
|
||||
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
||||
nspForm->nspowner, newOwnerSysId);
|
||||
nspForm->nspowner, newOwnerId);
|
||||
repl_repl[Anum_pg_namespace_nspacl - 1] = 'r';
|
||||
repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.161 2005/06/06 20:22:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.162 2005/06/28 05:08:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -231,9 +231,9 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
|
||||
const char *colName, TypeName *typename);
|
||||
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
|
||||
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
|
||||
static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
|
||||
static void ATExecChangeOwner(Oid relationOid, Oid newOwnerId);
|
||||
static void change_owner_recurse_to_sequences(Oid relationOid,
|
||||
int32 newOwnerSysId);
|
||||
Oid newOwnerId);
|
||||
static void ATExecClusterOn(Relation rel, const char *indexName);
|
||||
static void ATExecDropCluster(Relation rel);
|
||||
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
|
||||
@@ -2133,8 +2133,8 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
|
||||
AlterTableCreateToastTable(RelationGetRelid(rel), false);
|
||||
break;
|
||||
case AT_ChangeOwner: /* ALTER OWNER */
|
||||
/* get_usesysid raises an error if no such user */
|
||||
ATExecChangeOwner(RelationGetRelid(rel), get_usesysid(cmd->name));
|
||||
ATExecChangeOwner(RelationGetRelid(rel),
|
||||
get_roleid_checked(cmd->name));
|
||||
break;
|
||||
case AT_ClusterOn: /* CLUSTER ON */
|
||||
ATExecClusterOn(rel, cmd->name);
|
||||
@@ -5233,7 +5233,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
|
||||
* ALTER TABLE OWNER
|
||||
*/
|
||||
static void
|
||||
ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
ATExecChangeOwner(Oid relationOid, Oid newOwnerId)
|
||||
{
|
||||
Relation target_rel;
|
||||
Relation class_rel;
|
||||
@@ -5277,7 +5277,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (tuple_class->relowner != newOwnerSysId)
|
||||
if (tuple_class->relowner != newOwnerId)
|
||||
{
|
||||
Datum repl_val[Natts_pg_class];
|
||||
char repl_null[Natts_pg_class];
|
||||
@@ -5297,7 +5297,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
|
||||
repl_repl[Anum_pg_class_relowner - 1] = 'r';
|
||||
repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSysId);
|
||||
repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
|
||||
|
||||
/*
|
||||
* Determine the modified ACL for the new owner. This is only
|
||||
@@ -5309,7 +5309,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
if (!isNull)
|
||||
{
|
||||
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
||||
tuple_class->relowner, newOwnerSysId);
|
||||
tuple_class->relowner, newOwnerId);
|
||||
repl_repl[Anum_pg_class_relacl - 1] = 'r';
|
||||
repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
|
||||
}
|
||||
@@ -5337,7 +5337,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
|
||||
/* For each index, recursively change its ownership */
|
||||
foreach(i, index_oid_list)
|
||||
ATExecChangeOwner(lfirst_oid(i), newOwnerSysId);
|
||||
ATExecChangeOwner(lfirst_oid(i), newOwnerId);
|
||||
|
||||
list_free(index_oid_list);
|
||||
}
|
||||
@@ -5346,10 +5346,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
{
|
||||
/* If it has a toast table, recurse to change its ownership */
|
||||
if (tuple_class->reltoastrelid != InvalidOid)
|
||||
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
|
||||
ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId);
|
||||
|
||||
/* If it has dependent sequences, recurse to change them too */
|
||||
change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
|
||||
change_owner_recurse_to_sequences(relationOid, newOwnerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5366,7 +5366,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
|
||||
* ownership.
|
||||
*/
|
||||
static void
|
||||
change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
|
||||
change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId)
|
||||
{
|
||||
Relation depRel;
|
||||
SysScanDesc scan;
|
||||
@@ -5416,7 +5416,7 @@ change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
|
||||
}
|
||||
|
||||
/* We don't need to close the sequence while we alter it. */
|
||||
ATExecChangeOwner(depForm->objid, newOwnerSysId);
|
||||
ATExecChangeOwner(depForm->objid, newOwnerId);
|
||||
|
||||
/* Now we can close it. Keep the lock till end of transaction. */
|
||||
relation_close(seqRel, NoLock);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.22 2005/06/19 21:34:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.23 2005/06/28 05:08:54 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -208,7 +208,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
|
||||
Oid tablespaceoid;
|
||||
char *location;
|
||||
char *linkloc;
|
||||
AclId ownerid;
|
||||
Oid ownerId;
|
||||
|
||||
/* validate */
|
||||
|
||||
@@ -225,12 +225,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
|
||||
|
||||
/* However, the eventual owner of the tablespace need not be */
|
||||
if (stmt->owner)
|
||||
{
|
||||
/* No need to check result, get_usesysid() does that */
|
||||
ownerid = get_usesysid(stmt->owner);
|
||||
}
|
||||
ownerId = get_roleid_checked(stmt->owner);
|
||||
else
|
||||
ownerid = GetUserId();
|
||||
ownerId = GetUserId();
|
||||
|
||||
/* Unix-ify the offered path, and strip any trailing slashes */
|
||||
location = pstrdup(stmt->location);
|
||||
@@ -297,7 +294,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
|
||||
values[Anum_pg_tablespace_spcname - 1] =
|
||||
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
|
||||
values[Anum_pg_tablespace_spcowner - 1] =
|
||||
Int32GetDatum(ownerid);
|
||||
ObjectIdGetDatum(ownerId);
|
||||
values[Anum_pg_tablespace_spclocation - 1] =
|
||||
DirectFunctionCall1(textin, CStringGetDatum(location));
|
||||
nulls[Anum_pg_tablespace_spcacl - 1] = 'n';
|
||||
@@ -426,9 +423,8 @@ DropTableSpace(DropTableSpaceStmt *stmt)
|
||||
|
||||
tablespaceoid = HeapTupleGetOid(tuple);
|
||||
|
||||
/* Must be superuser or owner */
|
||||
if (GetUserId() != ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner &&
|
||||
!superuser())
|
||||
/* Must be tablespace owner */
|
||||
if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
|
||||
tablespacename);
|
||||
|
||||
@@ -711,8 +707,8 @@ RenameTableSpace(const char *oldname, const char *newname)
|
||||
|
||||
heap_endscan(scan);
|
||||
|
||||
/* Must be owner or superuser */
|
||||
if (newform->spcowner != GetUserId() && !superuser())
|
||||
/* Must be owner */
|
||||
if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname);
|
||||
|
||||
/* Validate new name */
|
||||
@@ -750,7 +746,7 @@ RenameTableSpace(const char *oldname, const char *newname)
|
||||
* Change tablespace owner
|
||||
*/
|
||||
void
|
||||
AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
|
||||
AlterTableSpaceOwner(const char *name, Oid newOwnerId)
|
||||
{
|
||||
Relation rel;
|
||||
ScanKeyData entry[1];
|
||||
@@ -778,7 +774,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (spcForm->spcowner != newOwnerSysId)
|
||||
if (spcForm->spcowner != newOwnerId)
|
||||
{
|
||||
Datum repl_val[Natts_pg_tablespace];
|
||||
char repl_null[Natts_pg_tablespace];
|
||||
@@ -798,7 +794,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
|
||||
repl_repl[Anum_pg_tablespace_spcowner - 1] = 'r';
|
||||
repl_val[Anum_pg_tablespace_spcowner - 1] = Int32GetDatum(newOwnerSysId);
|
||||
repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId);
|
||||
|
||||
/*
|
||||
* Determine the modified ACL for the new owner. This is only
|
||||
@@ -811,7 +807,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
|
||||
if (!isNull)
|
||||
{
|
||||
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
||||
spcForm->spcowner, newOwnerSysId);
|
||||
spcForm->spcowner, newOwnerId);
|
||||
repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r';
|
||||
repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.72 2005/05/06 17:24:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.73 2005/06/28 05:08:54 tgl Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@@ -2016,7 +2016,7 @@ GetDomainConstraints(Oid typeOid)
|
||||
* Change the owner of a type.
|
||||
*/
|
||||
void
|
||||
AlterTypeOwner(List *names, AclId newOwnerSysId)
|
||||
AlterTypeOwner(List *names, Oid newOwnerId)
|
||||
{
|
||||
TypeName *typename;
|
||||
Oid typeOid;
|
||||
@@ -2063,7 +2063,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
|
||||
* If the new owner is the same as the existing owner, consider the
|
||||
* command to have succeeded. This is for dump restoration purposes.
|
||||
*/
|
||||
if (typTup->typowner != newOwnerSysId)
|
||||
if (typTup->typowner != newOwnerId)
|
||||
{
|
||||
/* Otherwise, must be superuser to change object ownership */
|
||||
if (!superuser())
|
||||
@@ -2075,7 +2075,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
|
||||
* Modify the owner --- okay to scribble on typTup because it's a
|
||||
* copy
|
||||
*/
|
||||
typTup->typowner = newOwnerSysId;
|
||||
typTup->typowner = newOwnerId;
|
||||
|
||||
simple_heap_update(rel, &tup->t_self, tup);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.108 2005/06/09 21:52:07 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.109 2005/06/28 05:08:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "access/xact.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "commands/variable.h"
|
||||
#include "miscadmin.h"
|
||||
#include "parser/scansup.h"
|
||||
@@ -567,46 +567,46 @@ assign_client_encoding(const char *value, bool doit, GucSource source)
|
||||
* SET SESSION AUTHORIZATION
|
||||
*
|
||||
* When resetting session auth after an error, we can't expect to do catalog
|
||||
* lookups. Hence, the stored form of the value must provide a numeric userid
|
||||
* lookups. Hence, the stored form of the value must provide a numeric oid
|
||||
* that can be re-used directly. We store the string in the form of
|
||||
* NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed
|
||||
* by the numeric userid, followed by a comma, followed by the user name.
|
||||
* This cannot be confused with a plain user name because of the NAMEDATALEN
|
||||
* by the numeric oid, followed by a comma, followed by the role name.
|
||||
* This cannot be confused with a plain role name because of the NAMEDATALEN
|
||||
* limit on names, so we can tell whether we're being passed an initial
|
||||
* username or a saved/restored value.
|
||||
* role name or a saved/restored value.
|
||||
*/
|
||||
extern char *session_authorization_string; /* in guc.c */
|
||||
|
||||
const char *
|
||||
assign_session_authorization(const char *value, bool doit, GucSource source)
|
||||
{
|
||||
AclId usesysid = 0;
|
||||
Oid roleid = InvalidOid;
|
||||
bool is_superuser = false;
|
||||
const char *actual_username = NULL;
|
||||
const char *actual_rolename = NULL;
|
||||
char *result;
|
||||
|
||||
if (strspn(value, "x") == NAMEDATALEN &&
|
||||
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
|
||||
{
|
||||
/* might be a saved userid string */
|
||||
AclId savedsysid;
|
||||
Oid savedoid;
|
||||
char *endptr;
|
||||
|
||||
savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
|
||||
savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
|
||||
|
||||
if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
|
||||
{
|
||||
/* syntactically valid, so break out the data */
|
||||
usesysid = savedsysid;
|
||||
roleid = savedoid;
|
||||
is_superuser = (value[NAMEDATALEN] == 'T');
|
||||
actual_username = endptr + 1;
|
||||
actual_rolename = endptr + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (usesysid == 0)
|
||||
if (roleid == InvalidOid)
|
||||
{
|
||||
/* not a saved ID, so look it up */
|
||||
HeapTuple userTup;
|
||||
HeapTuple roleTup;
|
||||
|
||||
if (!IsTransactionState())
|
||||
{
|
||||
@@ -618,38 +618,38 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
userTup = SearchSysCache(SHADOWNAME,
|
||||
roleTup = SearchSysCache(AUTHNAME,
|
||||
PointerGetDatum(value),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(userTup))
|
||||
if (!HeapTupleIsValid(roleTup))
|
||||
{
|
||||
if (source >= PGC_S_INTERACTIVE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("user \"%s\" does not exist", value)));
|
||||
errmsg("role \"%s\" does not exist", value)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
|
||||
is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
|
||||
actual_username = value;
|
||||
roleid = HeapTupleGetOid(roleTup);
|
||||
is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
|
||||
actual_rolename = value;
|
||||
|
||||
ReleaseSysCache(userTup);
|
||||
ReleaseSysCache(roleTup);
|
||||
}
|
||||
|
||||
if (doit)
|
||||
SetSessionAuthorization(usesysid, is_superuser);
|
||||
SetSessionAuthorization(roleid, is_superuser);
|
||||
|
||||
result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username));
|
||||
result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_rolename));
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
memset(result, 'x', NAMEDATALEN);
|
||||
|
||||
sprintf(result + NAMEDATALEN, "%c%lu,%s",
|
||||
sprintf(result + NAMEDATALEN, "%c%u,%s",
|
||||
is_superuser ? 'T' : 'F',
|
||||
(unsigned long) usesysid,
|
||||
actual_username);
|
||||
roleid,
|
||||
actual_rolename);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -662,13 +662,13 @@ show_session_authorization(void)
|
||||
* assign_session_authorization
|
||||
*/
|
||||
const char *value = session_authorization_string;
|
||||
AclId savedsysid;
|
||||
Oid savedoid;
|
||||
char *endptr;
|
||||
|
||||
Assert(strspn(value, "x") == NAMEDATALEN &&
|
||||
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'));
|
||||
|
||||
savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
|
||||
savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
|
||||
|
||||
Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.250 2005/06/20 18:37:01 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.251 2005/06/28 05:08:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -352,7 +352,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
|
||||
{
|
||||
AclMode requiredPerms;
|
||||
Oid relOid;
|
||||
AclId userid;
|
||||
Oid userid;
|
||||
|
||||
/*
|
||||
* Only plain-relation RTEs need to be checked here. Subquery RTEs
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.133 2005/05/06 17:24:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.134 2005/06/28 05:08:55 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1270,7 +1270,7 @@ ExecInitAgg(Agg *node, EState *estate)
|
||||
/* Check that aggregate owner has permission to call component fns */
|
||||
{
|
||||
HeapTuple procTuple;
|
||||
AclId aggOwner;
|
||||
Oid aggOwner;
|
||||
|
||||
procTuple = SearchSysCache(PROCOID,
|
||||
ObjectIdGetDatum(aggref->aggfnoid),
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.62 2005/02/20 04:45:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.63 2005/06/28 05:08:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
|
||||
int
|
||||
md5_crypt_verify(const Port *port, const char *user, char *client_pass)
|
||||
md5_crypt_verify(const Port *port, const char *role, char *client_pass)
|
||||
{
|
||||
char *shadow_pass = NULL,
|
||||
*valuntil = NULL,
|
||||
@@ -39,13 +39,11 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
|
||||
ListCell *token;
|
||||
char *crypt_client_pass = client_pass;
|
||||
|
||||
if ((line = get_user_line(user)) == NULL)
|
||||
if ((line = get_role_line(role)) == NULL)
|
||||
return STATUS_ERROR;
|
||||
|
||||
/* Skip over username and usesysid */
|
||||
/* Skip over rolename */
|
||||
token = list_head(*line);
|
||||
if (token)
|
||||
token = lnext(token);
|
||||
if (token)
|
||||
token = lnext(token);
|
||||
if (token)
|
||||
@@ -146,17 +144,28 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
|
||||
/*
|
||||
* Password OK, now check to be sure we are not past valuntil
|
||||
*/
|
||||
AbsoluteTime vuntil;
|
||||
|
||||
if (valuntil == NULL || *valuntil == '\0')
|
||||
vuntil = INVALID_ABSTIME;
|
||||
else
|
||||
vuntil = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
|
||||
CStringGetDatum(valuntil)));
|
||||
if (vuntil != INVALID_ABSTIME && vuntil < GetCurrentAbsoluteTime())
|
||||
retval = STATUS_ERROR;
|
||||
else
|
||||
retval = STATUS_OK;
|
||||
else
|
||||
{
|
||||
TimestampTz vuntil;
|
||||
AbsoluteTime sec;
|
||||
int usec;
|
||||
TimestampTz curtime;
|
||||
|
||||
vuntil = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
|
||||
CStringGetDatum(valuntil),
|
||||
ObjectIdGetDatum(InvalidOid),
|
||||
Int32GetDatum(-1)));
|
||||
|
||||
sec = GetCurrentAbsoluteTimeUsec(&usec);
|
||||
curtime = AbsoluteTimeUsecToTimestampTz(sec, usec);
|
||||
|
||||
if (vuntil < curtime)
|
||||
retval = STATUS_ERROR;
|
||||
else
|
||||
retval = STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (port->auth_method == uaMD5)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.142 2005/06/27 02:04:25 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.143 2005/06/28 05:08:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -53,7 +53,8 @@
|
||||
|
||||
/*
|
||||
* These variables hold the pre-parsed contents of the hba and ident
|
||||
* configuration files. Each is a list of sublists, one sublist for
|
||||
* configuration files, as well as the flat auth file.
|
||||
* Each is a list of sublists, one sublist for
|
||||
* each (non-empty, non-comment) line of the file. Each sublist's
|
||||
* first item is an integer line number (so we can give somewhat-useful
|
||||
* location info in error messages). Remaining items are palloc'd strings,
|
||||
@@ -69,20 +70,13 @@ static List *hba_line_nums = NIL;
|
||||
static List *ident_lines = NIL;
|
||||
static List *ident_line_nums = NIL;
|
||||
|
||||
/* pre-parsed content of group file and corresponding line #s */
|
||||
static List *group_lines = NIL;
|
||||
static List *group_line_nums = NIL;
|
||||
|
||||
/* pre-parsed content of user passwd file and corresponding line #s */
|
||||
static List *user_lines = NIL;
|
||||
static List *user_line_nums = NIL;
|
||||
/* pre-parsed content of flat auth file and corresponding line #s */
|
||||
static List *role_lines = NIL;
|
||||
static List *role_line_nums = NIL;
|
||||
|
||||
/* sorted entries so we can do binary search lookups */
|
||||
static List **user_sorted = NULL; /* sorted user list, for bsearch() */
|
||||
static List **group_sorted = NULL; /* sorted group list, for
|
||||
* bsearch() */
|
||||
static int user_length;
|
||||
static int group_length;
|
||||
static List **role_sorted = NULL; /* sorted role list, for bsearch() */
|
||||
static int role_length;
|
||||
|
||||
static void tokenize_file(const char *filename, FILE *file,
|
||||
List **lines, List **line_nums);
|
||||
@@ -109,7 +103,7 @@ pg_isblank(const char c)
|
||||
* return empty string as *buf and position the file to the beginning
|
||||
* of the next line or EOF, whichever comes first. Allow spaces in
|
||||
* quoted strings. Terminate on unquoted commas. Handle
|
||||
* comments. Treat unquoted keywords that might be user names or
|
||||
* comments. Treat unquoted keywords that might be role names or
|
||||
* database names specially, by appending a newline to them.
|
||||
*/
|
||||
static void
|
||||
@@ -199,7 +193,8 @@ next_token(FILE *fp, char *buf, int bufsz)
|
||||
if (!saw_quote &&
|
||||
(strcmp(start_buf, "all") == 0 ||
|
||||
strcmp(start_buf, "sameuser") == 0 ||
|
||||
strcmp(start_buf, "samegroup") == 0))
|
||||
strcmp(start_buf, "samegroup") == 0 ||
|
||||
strcmp(start_buf, "samerole") == 0))
|
||||
{
|
||||
/* append newline to a magical keyword */
|
||||
*buf++ = '\n';
|
||||
@@ -434,94 +429,58 @@ tokenize_file(const char *filename, FILE *file,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compare two lines based on their user/group names.
|
||||
*
|
||||
* Used for qsort() sorting.
|
||||
*/
|
||||
static int
|
||||
user_group_qsort_cmp(const void *list1, const void *list2)
|
||||
{
|
||||
char *user1 = linitial(*(List **) list1);
|
||||
char *user2 = linitial(*(List **) list2);
|
||||
|
||||
return strcmp(user1, user2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compare two lines based on their user/group names.
|
||||
* Compare two lines based on their role/member names.
|
||||
*
|
||||
* Used for bsearch() lookup.
|
||||
*/
|
||||
static int
|
||||
user_group_bsearch_cmp(const void *user, const void *list)
|
||||
role_bsearch_cmp(const void *role, const void *list)
|
||||
{
|
||||
char *user2 = linitial(*(List **) list);
|
||||
char *role2 = linitial(*(List **) list);
|
||||
|
||||
return strcmp(user, user2);
|
||||
return strcmp(role, role2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lookup a group name in the pg_group file
|
||||
* Lookup a role name in the pg_auth file
|
||||
*/
|
||||
static List **
|
||||
get_group_line(const char *group)
|
||||
List **
|
||||
get_role_line(const char *role)
|
||||
{
|
||||
/* On some versions of Solaris, bsearch of zero items dumps core */
|
||||
if (group_length == 0)
|
||||
if (role_length == 0)
|
||||
return NULL;
|
||||
|
||||
return (List **) bsearch((void *) group,
|
||||
(void *) group_sorted,
|
||||
group_length,
|
||||
return (List **) bsearch((void *) role,
|
||||
(void *) role_sorted,
|
||||
role_length,
|
||||
sizeof(List *),
|
||||
user_group_bsearch_cmp);
|
||||
role_bsearch_cmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lookup a user name in the pg_shadow file
|
||||
*/
|
||||
List **
|
||||
get_user_line(const char *user)
|
||||
{
|
||||
/* On some versions of Solaris, bsearch of zero items dumps core */
|
||||
if (user_length == 0)
|
||||
return NULL;
|
||||
|
||||
return (List **) bsearch((void *) user,
|
||||
(void *) user_sorted,
|
||||
user_length,
|
||||
sizeof(List *),
|
||||
user_group_bsearch_cmp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Does user belong to group?
|
||||
* Does member belong to role?
|
||||
*/
|
||||
static bool
|
||||
check_group(char *group, char *user)
|
||||
check_member(const char *role, const char *member)
|
||||
{
|
||||
List **line;
|
||||
List **line2;
|
||||
ListCell *line_item;
|
||||
char *usesysid;
|
||||
|
||||
if ((line = get_user_line(user)) == NULL)
|
||||
return false; /* if user not exist, say "no" */
|
||||
/* Skip over username to get usesysid */
|
||||
usesysid = (char *) lsecond(*line);
|
||||
if ((line = get_role_line(member)) == NULL)
|
||||
return false; /* if member not exist, say "no" */
|
||||
|
||||
if ((line = get_group_line(group)) == NULL)
|
||||
return false; /* if group not exist, say "no" */
|
||||
if ((line2 = get_role_line(role)) == NULL)
|
||||
return false; /* if role not exist, say "no" */
|
||||
|
||||
/* skip over the group name, examine all the member usesysid's */
|
||||
for_each_cell(line_item, lnext(list_head(*line)))
|
||||
/* skip over the role name, password, valuntil, examine all the members */
|
||||
for_each_cell(line_item, lfourth(*line2))
|
||||
{
|
||||
if (strcmp((char *) lfirst(line_item), usesysid) == 0)
|
||||
if (strcmp((char *) lfirst(line_item), member) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -529,10 +488,10 @@ check_group(char *group, char *user)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check comma user list for a specific user, handle group names.
|
||||
* Check comma member list for a specific role, handle role names.
|
||||
*/
|
||||
static bool
|
||||
check_user(char *user, char *param_str)
|
||||
check_role(char *role, char *param_str)
|
||||
{
|
||||
char *tok;
|
||||
|
||||
@@ -540,10 +499,10 @@ check_user(char *user, char *param_str)
|
||||
{
|
||||
if (tok[0] == '+')
|
||||
{
|
||||
if (check_group(tok + 1, user))
|
||||
if (check_member(tok + 1, role))
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(tok, user) == 0 ||
|
||||
else if (strcmp(tok, role) == 0 ||
|
||||
strcmp(tok, "all\n") == 0)
|
||||
return true;
|
||||
}
|
||||
@@ -552,10 +511,10 @@ check_user(char *user, char *param_str)
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if db/user combination matches param string.
|
||||
* Check to see if db/role combination matches param string.
|
||||
*/
|
||||
static bool
|
||||
check_db(char *dbname, char *user, char *param_str)
|
||||
check_db(char *dbname, char *role, char *param_str)
|
||||
{
|
||||
char *tok;
|
||||
|
||||
@@ -565,12 +524,13 @@ check_db(char *dbname, char *user, char *param_str)
|
||||
return true;
|
||||
else if (strcmp(tok, "sameuser\n") == 0)
|
||||
{
|
||||
if (strcmp(dbname, user) == 0)
|
||||
if (strcmp(dbname, role) == 0)
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(tok, "samegroup\n") == 0)
|
||||
else if (strcmp(tok, "samegroup\n") == 0 ||
|
||||
strcmp(tok, "samerole\n") == 0)
|
||||
{
|
||||
if (check_group(dbname, user))
|
||||
if (check_member(dbname, role))
|
||||
return true;
|
||||
}
|
||||
else if (strcmp(tok, dbname) == 0)
|
||||
@@ -655,7 +615,7 @@ parse_hba(List *line, int line_num, hbaPort *port,
|
||||
{
|
||||
char *token;
|
||||
char *db;
|
||||
char *user;
|
||||
char *role;
|
||||
struct addrinfo *gai_result;
|
||||
struct addrinfo hints;
|
||||
int ret;
|
||||
@@ -675,11 +635,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
|
||||
goto hba_syntax;
|
||||
db = lfirst(line_item);
|
||||
|
||||
/* Get the user. */
|
||||
/* Get the role. */
|
||||
line_item = lnext(line_item);
|
||||
if (!line_item)
|
||||
goto hba_syntax;
|
||||
user = lfirst(line_item);
|
||||
role = lfirst(line_item);
|
||||
|
||||
line_item = lnext(line_item);
|
||||
if (!line_item)
|
||||
@@ -735,11 +695,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
|
||||
goto hba_syntax;
|
||||
db = lfirst(line_item);
|
||||
|
||||
/* Get the user. */
|
||||
/* Get the role. */
|
||||
line_item = lnext(line_item);
|
||||
if (!line_item)
|
||||
goto hba_syntax;
|
||||
user = lfirst(line_item);
|
||||
role = lfirst(line_item);
|
||||
|
||||
/* Read the IP address field. (with or without CIDR netmask) */
|
||||
line_item = lnext(line_item);
|
||||
@@ -861,10 +821,10 @@ parse_hba(List *line, int line_num, hbaPort *port,
|
||||
else
|
||||
goto hba_syntax;
|
||||
|
||||
/* Does the entry match database and user? */
|
||||
/* Does the entry match database and role? */
|
||||
if (!check_db(port->database_name, port->user_name, db))
|
||||
return;
|
||||
if (!check_user(port->user_name, user))
|
||||
if (!check_role(port->user_name, role))
|
||||
return;
|
||||
|
||||
/* Success */
|
||||
@@ -923,27 +883,27 @@ check_hba(hbaPort *port)
|
||||
|
||||
|
||||
/*
|
||||
* Load group/user name mapping file
|
||||
* Load role/password mapping file
|
||||
*/
|
||||
void
|
||||
load_group(void)
|
||||
load_role(void)
|
||||
{
|
||||
char *filename;
|
||||
FILE *group_file;
|
||||
FILE *role_file;
|
||||
|
||||
/* Discard any old data */
|
||||
if (group_lines || group_line_nums)
|
||||
free_lines(&group_lines, &group_line_nums);
|
||||
if (group_sorted)
|
||||
pfree(group_sorted);
|
||||
group_sorted = NULL;
|
||||
group_length = 0;
|
||||
if (role_lines || role_line_nums)
|
||||
free_lines(&role_lines, &role_line_nums);
|
||||
if (role_sorted)
|
||||
pfree(role_sorted);
|
||||
role_sorted = NULL;
|
||||
role_length = 0;
|
||||
|
||||
/* Read in the file contents */
|
||||
filename = group_getflatfilename();
|
||||
group_file = AllocateFile(filename, "r");
|
||||
filename = auth_getflatfilename();
|
||||
role_file = AllocateFile(filename, "r");
|
||||
|
||||
if (group_file == NULL)
|
||||
if (role_file == NULL)
|
||||
{
|
||||
/* no complaint if not there */
|
||||
if (errno != ENOENT)
|
||||
@@ -954,84 +914,25 @@ load_group(void)
|
||||
return;
|
||||
}
|
||||
|
||||
tokenize_file(filename, group_file, &group_lines, &group_line_nums);
|
||||
tokenize_file(filename, role_file, &role_lines, &role_line_nums);
|
||||
|
||||
FreeFile(group_file);
|
||||
FreeFile(role_file);
|
||||
pfree(filename);
|
||||
|
||||
/* create sorted lines for binary searching */
|
||||
group_length = list_length(group_lines);
|
||||
if (group_length)
|
||||
/* create array for binary searching */
|
||||
role_length = list_length(role_lines);
|
||||
if (role_length)
|
||||
{
|
||||
int i = 0;
|
||||
ListCell *line;
|
||||
int i = 0;
|
||||
ListCell *line;
|
||||
|
||||
group_sorted = palloc(group_length * sizeof(List *));
|
||||
role_sorted = palloc(role_length * sizeof(List *));
|
||||
foreach(line, role_lines)
|
||||
{
|
||||
role_sorted[i++] = lfirst(line);
|
||||
}
|
||||
|
||||
foreach(line, group_lines)
|
||||
group_sorted[i++] = lfirst(line);
|
||||
|
||||
qsort((void *) group_sorted,
|
||||
group_length,
|
||||
sizeof(List *),
|
||||
user_group_qsort_cmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load user/password mapping file
|
||||
*/
|
||||
void
|
||||
load_user(void)
|
||||
{
|
||||
char *filename;
|
||||
FILE *user_file;
|
||||
|
||||
/* Discard any old data */
|
||||
if (user_lines || user_line_nums)
|
||||
free_lines(&user_lines, &user_line_nums);
|
||||
if (user_sorted)
|
||||
pfree(user_sorted);
|
||||
user_sorted = NULL;
|
||||
user_length = 0;
|
||||
|
||||
/* Read in the file contents */
|
||||
filename = user_getflatfilename();
|
||||
user_file = AllocateFile(filename, "r");
|
||||
|
||||
if (user_file == NULL)
|
||||
{
|
||||
/* no complaint if not there */
|
||||
if (errno != ENOENT)
|
||||
ereport(LOG,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not open file \"%s\": %m", filename)));
|
||||
pfree(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
tokenize_file(filename, user_file, &user_lines, &user_line_nums);
|
||||
|
||||
FreeFile(user_file);
|
||||
pfree(filename);
|
||||
|
||||
/* create sorted lines for binary searching */
|
||||
user_length = list_length(user_lines);
|
||||
if (user_length)
|
||||
{
|
||||
int i = 0;
|
||||
ListCell *line;
|
||||
|
||||
user_sorted = palloc(user_length * sizeof(List *));
|
||||
|
||||
foreach(line, user_lines)
|
||||
user_sorted[i++] = lfirst(line);
|
||||
|
||||
qsort((void *) user_sorted,
|
||||
user_length,
|
||||
sizeof(List *),
|
||||
user_group_qsort_cmp);
|
||||
/* We assume the flat file was written already-sorted */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1108,18 +1009,18 @@ read_pg_database_line(FILE *fp, char *dbname,
|
||||
/*
|
||||
* Process one line from the ident config file.
|
||||
*
|
||||
* Take the line and compare it to the needed map, pg_user and ident_user.
|
||||
* Take the line and compare it to the needed map, pg_role and ident_user.
|
||||
* *found_p and *error_p are set according to our results.
|
||||
*/
|
||||
static void
|
||||
parse_ident_usermap(List *line, int line_number, const char *usermap_name,
|
||||
const char *pg_user, const char *ident_user,
|
||||
const char *pg_role, const char *ident_user,
|
||||
bool *found_p, bool *error_p)
|
||||
{
|
||||
ListCell *line_item;
|
||||
char *token;
|
||||
char *file_map;
|
||||
char *file_pguser;
|
||||
char *file_pgrole;
|
||||
char *file_ident_user;
|
||||
|
||||
*found_p = false;
|
||||
@@ -1139,16 +1040,16 @@ parse_ident_usermap(List *line, int line_number, const char *usermap_name,
|
||||
token = lfirst(line_item);
|
||||
file_ident_user = token;
|
||||
|
||||
/* Get the PG username token */
|
||||
/* Get the PG rolename token */
|
||||
line_item = lnext(line_item);
|
||||
if (!line_item)
|
||||
goto ident_syntax;
|
||||
token = lfirst(line_item);
|
||||
file_pguser = token;
|
||||
file_pgrole = token;
|
||||
|
||||
/* Match? */
|
||||
if (strcmp(file_map, usermap_name) == 0 &&
|
||||
strcmp(file_pguser, pg_user) == 0 &&
|
||||
strcmp(file_pgrole, pg_role) == 0 &&
|
||||
strcmp(file_ident_user, ident_user) == 0)
|
||||
*found_p = true;
|
||||
|
||||
@@ -1167,17 +1068,17 @@ ident_syntax:
|
||||
* Scan the (pre-parsed) ident usermap file line by line, looking for a match
|
||||
*
|
||||
* See if the user with ident username "ident_user" is allowed to act
|
||||
* as Postgres user "pguser" according to usermap "usermap_name".
|
||||
* as Postgres user "pgrole" according to usermap "usermap_name".
|
||||
*
|
||||
* Special case: For usermap "sameuser", don't look in the usermap
|
||||
* file. That's an implied map where "pguser" must be identical to
|
||||
* Special case: For usermap "samerole", don't look in the usermap
|
||||
* file. That's an implied map where "pgrole" must be identical to
|
||||
* "ident_user" in order to be authorized.
|
||||
*
|
||||
* Iff authorized, return true.
|
||||
*/
|
||||
static bool
|
||||
check_ident_usermap(const char *usermap_name,
|
||||
const char *pg_user,
|
||||
const char *pg_role,
|
||||
const char *ident_user)
|
||||
{
|
||||
bool found_entry = false,
|
||||
@@ -1190,9 +1091,10 @@ check_ident_usermap(const char *usermap_name,
|
||||
errmsg("cannot use Ident authentication without usermap field")));
|
||||
found_entry = false;
|
||||
}
|
||||
else if (strcmp(usermap_name, "sameuser\n") == 0)
|
||||
else if (strcmp(usermap_name, "sameuser\n") == 0 ||
|
||||
strcmp(usermap_name, "samerole\n") == 0)
|
||||
{
|
||||
if (strcmp(pg_user, ident_user) == 0)
|
||||
if (strcmp(pg_role, ident_user) == 0)
|
||||
found_entry = true;
|
||||
else
|
||||
found_entry = false;
|
||||
@@ -1205,7 +1107,7 @@ check_ident_usermap(const char *usermap_name,
|
||||
forboth(line_cell, ident_lines, num_cell, ident_line_nums)
|
||||
{
|
||||
parse_ident_usermap(lfirst(line_cell), lfirst_int(num_cell),
|
||||
usermap_name, pg_user, ident_user,
|
||||
usermap_name, pg_role, ident_user,
|
||||
&found_entry, &error);
|
||||
if (found_entry || error)
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.309 2005/06/26 22:05:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.310 2005/06/28 05:08:56 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1761,8 +1761,7 @@ _copyPrivGrantee(PrivGrantee *from)
|
||||
{
|
||||
PrivGrantee *newnode = makeNode(PrivGrantee);
|
||||
|
||||
COPY_STRING_FIELD(username);
|
||||
COPY_STRING_FIELD(groupname);
|
||||
COPY_STRING_FIELD(rolname);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -1778,6 +1777,21 @@ _copyFuncWithArgs(FuncWithArgs *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static GrantRoleStmt *
|
||||
_copyGrantRoleStmt(GrantRoleStmt *from)
|
||||
{
|
||||
GrantRoleStmt *newnode = makeNode(GrantRoleStmt);
|
||||
|
||||
COPY_NODE_FIELD(granted_roles);
|
||||
COPY_NODE_FIELD(grantee_roles);
|
||||
COPY_SCALAR_FIELD(is_grant);
|
||||
COPY_SCALAR_FIELD(admin_opt);
|
||||
COPY_STRING_FIELD(grantor);
|
||||
COPY_SCALAR_FIELD(behavior);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static DeclareCursorStmt *
|
||||
_copyDeclareCursorStmt(DeclareCursorStmt *from)
|
||||
{
|
||||
@@ -2374,46 +2388,47 @@ _copyDropPLangStmt(DropPLangStmt *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static CreateUserStmt *
|
||||
_copyCreateUserStmt(CreateUserStmt *from)
|
||||
static CreateRoleStmt *
|
||||
_copyCreateRoleStmt(CreateRoleStmt *from)
|
||||
{
|
||||
CreateUserStmt *newnode = makeNode(CreateUserStmt);
|
||||
CreateRoleStmt *newnode = makeNode(CreateRoleStmt);
|
||||
|
||||
COPY_STRING_FIELD(user);
|
||||
COPY_STRING_FIELD(role);
|
||||
COPY_NODE_FIELD(options);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static AlterUserStmt *
|
||||
_copyAlterUserStmt(AlterUserStmt *from)
|
||||
static AlterRoleStmt *
|
||||
_copyAlterRoleStmt(AlterRoleStmt *from)
|
||||
{
|
||||
AlterUserStmt *newnode = makeNode(AlterUserStmt);
|
||||
AlterRoleStmt *newnode = makeNode(AlterRoleStmt);
|
||||
|
||||
COPY_STRING_FIELD(user);
|
||||
COPY_STRING_FIELD(role);
|
||||
COPY_NODE_FIELD(options);
|
||||
COPY_SCALAR_FIELD(action);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static AlterUserSetStmt *
|
||||
_copyAlterUserSetStmt(AlterUserSetStmt *from)
|
||||
static AlterRoleSetStmt *
|
||||
_copyAlterRoleSetStmt(AlterRoleSetStmt *from)
|
||||
{
|
||||
AlterUserSetStmt *newnode = makeNode(AlterUserSetStmt);
|
||||
AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
|
||||
|
||||
COPY_STRING_FIELD(user);
|
||||
COPY_STRING_FIELD(role);
|
||||
COPY_STRING_FIELD(variable);
|
||||
COPY_NODE_FIELD(value);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static DropUserStmt *
|
||||
_copyDropUserStmt(DropUserStmt *from)
|
||||
static DropRoleStmt *
|
||||
_copyDropRoleStmt(DropRoleStmt *from)
|
||||
{
|
||||
DropUserStmt *newnode = makeNode(DropUserStmt);
|
||||
DropRoleStmt *newnode = makeNode(DropRoleStmt);
|
||||
|
||||
COPY_NODE_FIELD(users);
|
||||
COPY_NODE_FIELD(roles);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -2441,39 +2456,6 @@ _copyConstraintsSetStmt(ConstraintsSetStmt *from)
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static CreateGroupStmt *
|
||||
_copyCreateGroupStmt(CreateGroupStmt *from)
|
||||
{
|
||||
CreateGroupStmt *newnode = makeNode(CreateGroupStmt);
|
||||
|
||||
COPY_STRING_FIELD(name);
|
||||
COPY_NODE_FIELD(options);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static AlterGroupStmt *
|
||||
_copyAlterGroupStmt(AlterGroupStmt *from)
|
||||
{
|
||||
AlterGroupStmt *newnode = makeNode(AlterGroupStmt);
|
||||
|
||||
COPY_STRING_FIELD(name);
|
||||
COPY_SCALAR_FIELD(action);
|
||||
COPY_NODE_FIELD(listUsers);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static DropGroupStmt *
|
||||
_copyDropGroupStmt(DropGroupStmt *from)
|
||||
{
|
||||
DropGroupStmt *newnode = makeNode(DropGroupStmt);
|
||||
|
||||
COPY_STRING_FIELD(name);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static ReindexStmt *
|
||||
_copyReindexStmt(ReindexStmt *from)
|
||||
{
|
||||
@@ -2927,6 +2909,9 @@ copyObject(void *from)
|
||||
case T_GrantStmt:
|
||||
retval = _copyGrantStmt(from);
|
||||
break;
|
||||
case T_GrantRoleStmt:
|
||||
retval = _copyGrantRoleStmt(from);
|
||||
break;
|
||||
case T_DeclareCursorStmt:
|
||||
retval = _copyDeclareCursorStmt(from);
|
||||
break;
|
||||
@@ -3071,17 +3056,17 @@ copyObject(void *from)
|
||||
case T_DropPLangStmt:
|
||||
retval = _copyDropPLangStmt(from);
|
||||
break;
|
||||
case T_CreateUserStmt:
|
||||
retval = _copyCreateUserStmt(from);
|
||||
case T_CreateRoleStmt:
|
||||
retval = _copyCreateRoleStmt(from);
|
||||
break;
|
||||
case T_AlterUserStmt:
|
||||
retval = _copyAlterUserStmt(from);
|
||||
case T_AlterRoleStmt:
|
||||
retval = _copyAlterRoleStmt(from);
|
||||
break;
|
||||
case T_AlterUserSetStmt:
|
||||
retval = _copyAlterUserSetStmt(from);
|
||||
case T_AlterRoleSetStmt:
|
||||
retval = _copyAlterRoleSetStmt(from);
|
||||
break;
|
||||
case T_DropUserStmt:
|
||||
retval = _copyDropUserStmt(from);
|
||||
case T_DropRoleStmt:
|
||||
retval = _copyDropRoleStmt(from);
|
||||
break;
|
||||
case T_LockStmt:
|
||||
retval = _copyLockStmt(from);
|
||||
@@ -3089,15 +3074,6 @@ copyObject(void *from)
|
||||
case T_ConstraintsSetStmt:
|
||||
retval = _copyConstraintsSetStmt(from);
|
||||
break;
|
||||
case T_CreateGroupStmt:
|
||||
retval = _copyCreateGroupStmt(from);
|
||||
break;
|
||||
case T_AlterGroupStmt:
|
||||
retval = _copyAlterGroupStmt(from);
|
||||
break;
|
||||
case T_DropGroupStmt:
|
||||
retval = _copyDropGroupStmt(from);
|
||||
break;
|
||||
case T_ReindexStmt:
|
||||
retval = _copyReindexStmt(from);
|
||||
break;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.246 2005/06/26 22:05:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.247 2005/06/28 05:08:57 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -778,8 +778,7 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
|
||||
static bool
|
||||
_equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(username);
|
||||
COMPARE_STRING_FIELD(groupname);
|
||||
COMPARE_STRING_FIELD(rolname);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -793,6 +792,19 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalGrantRoleStmt(GrantRoleStmt *a, GrantRoleStmt *b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(granted_roles);
|
||||
COMPARE_NODE_FIELD(grantee_roles);
|
||||
COMPARE_SCALAR_FIELD(is_grant);
|
||||
COMPARE_SCALAR_FIELD(admin_opt);
|
||||
COMPARE_STRING_FIELD(grantor);
|
||||
COMPARE_SCALAR_FIELD(behavior);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
|
||||
{
|
||||
@@ -1295,27 +1307,28 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
|
||||
_equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(user);
|
||||
COMPARE_STRING_FIELD(role);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
|
||||
_equalAlterRoleStmt(AlterRoleStmt *a, AlterRoleStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(user);
|
||||
COMPARE_STRING_FIELD(role);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
COMPARE_SCALAR_FIELD(action);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
|
||||
_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(user);
|
||||
COMPARE_STRING_FIELD(role);
|
||||
COMPARE_STRING_FIELD(variable);
|
||||
COMPARE_NODE_FIELD(value);
|
||||
|
||||
@@ -1323,9 +1336,9 @@ _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
|
||||
_equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
|
||||
{
|
||||
COMPARE_NODE_FIELD(users);
|
||||
COMPARE_NODE_FIELD(roles);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1349,33 +1362,6 @@ _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(name);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(name);
|
||||
COMPARE_SCALAR_FIELD(action);
|
||||
COMPARE_NODE_FIELD(listUsers);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
_equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
|
||||
{
|
||||
@@ -1971,6 +1957,9 @@ equal(void *a, void *b)
|
||||
case T_GrantStmt:
|
||||
retval = _equalGrantStmt(a, b);
|
||||
break;
|
||||
case T_GrantRoleStmt:
|
||||
retval = _equalGrantRoleStmt(a, b);
|
||||
break;
|
||||
case T_DeclareCursorStmt:
|
||||
retval = _equalDeclareCursorStmt(a, b);
|
||||
break;
|
||||
@@ -2115,17 +2104,17 @@ equal(void *a, void *b)
|
||||
case T_DropPLangStmt:
|
||||
retval = _equalDropPLangStmt(a, b);
|
||||
break;
|
||||
case T_CreateUserStmt:
|
||||
retval = _equalCreateUserStmt(a, b);
|
||||
case T_CreateRoleStmt:
|
||||
retval = _equalCreateRoleStmt(a, b);
|
||||
break;
|
||||
case T_AlterUserStmt:
|
||||
retval = _equalAlterUserStmt(a, b);
|
||||
case T_AlterRoleStmt:
|
||||
retval = _equalAlterRoleStmt(a, b);
|
||||
break;
|
||||
case T_AlterUserSetStmt:
|
||||
retval = _equalAlterUserSetStmt(a, b);
|
||||
case T_AlterRoleSetStmt:
|
||||
retval = _equalAlterRoleSetStmt(a, b);
|
||||
break;
|
||||
case T_DropUserStmt:
|
||||
retval = _equalDropUserStmt(a, b);
|
||||
case T_DropRoleStmt:
|
||||
retval = _equalDropRoleStmt(a, b);
|
||||
break;
|
||||
case T_LockStmt:
|
||||
retval = _equalLockStmt(a, b);
|
||||
@@ -2133,15 +2122,6 @@ equal(void *a, void *b)
|
||||
case T_ConstraintsSetStmt:
|
||||
retval = _equalConstraintsSetStmt(a, b);
|
||||
break;
|
||||
case T_CreateGroupStmt:
|
||||
retval = _equalCreateGroupStmt(a, b);
|
||||
break;
|
||||
case T_AlterGroupStmt:
|
||||
retval = _equalAlterGroupStmt(a, b);
|
||||
break;
|
||||
case T_DropGroupStmt:
|
||||
retval = _equalDropGroupStmt(a, b);
|
||||
break;
|
||||
case T_ReindexStmt:
|
||||
retval = _equalReindexStmt(a, b);
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.256 2005/06/26 22:05:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.257 2005/06/28 05:08:57 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every node type that can appear in stored rules' parsetrees *must*
|
||||
@@ -1535,7 +1535,7 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
|
||||
WRITE_BOOL_FIELD(inh);
|
||||
WRITE_BOOL_FIELD(inFromCl);
|
||||
WRITE_UINT_FIELD(requiredPerms);
|
||||
WRITE_UINT_FIELD(checkAsUser);
|
||||
WRITE_OID_FIELD(checkAsUser);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.179 2005/06/26 22:05:37 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.180 2005/06/28 05:08:57 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Path and Plan nodes do not have any readfuncs support, because we
|
||||
@@ -917,7 +917,7 @@ _readRangeTblEntry(void)
|
||||
READ_BOOL_FIELD(inh);
|
||||
READ_BOOL_FIELD(inFromCl);
|
||||
READ_UINT_FIELD(requiredPerms);
|
||||
READ_UINT_FIELD(checkAsUser);
|
||||
READ_OID_FIELD(checkAsUser);
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.498 2005/06/26 22:05:38 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.499 2005/06/28 05:08:57 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -133,19 +133,20 @@ static void doNegateFloat(Value *v);
|
||||
%type <node> stmt schema_stmt
|
||||
AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt
|
||||
AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt
|
||||
AlterRoleStmt AlterRoleSetStmt
|
||||
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
|
||||
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
|
||||
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
|
||||
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
|
||||
CreateAssertStmt CreateTrigStmt CreateUserStmt
|
||||
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
|
||||
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
|
||||
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
|
||||
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt
|
||||
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
|
||||
DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
|
||||
GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
|
||||
GrantRoleStmt GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
|
||||
LockStmt NotifyStmt ExplainableStmt PreparableStmt
|
||||
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
|
||||
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt
|
||||
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeRoleStmt RevokeStmt
|
||||
RuleActionStmt RuleActionStmtOrEmpty RuleStmt
|
||||
SelectStmt TransactionStmt TruncateStmt
|
||||
UnlistenStmt UpdateStmt VacuumStmt
|
||||
@@ -170,17 +171,16 @@ static void doNegateFloat(Value *v);
|
||||
%type <ival> opt_lock lock_type cast_context
|
||||
%type <boolean> opt_force opt_or_replace
|
||||
opt_grant_grant_option opt_revoke_grant_option
|
||||
opt_alter_admin_option
|
||||
opt_grant_admin_option opt_revoke_admin_option
|
||||
opt_nowait
|
||||
|
||||
%type <boolean> like_including_defaults
|
||||
|
||||
%type <list> user_list
|
||||
%type <list> role_list
|
||||
|
||||
%type <list> OptGroupList
|
||||
%type <defelt> OptGroupElem
|
||||
|
||||
%type <list> OptUserList
|
||||
%type <defelt> OptUserElem
|
||||
%type <list> OptRoleList
|
||||
%type <defelt> OptRoleElem
|
||||
|
||||
%type <str> OptSchemaName
|
||||
%type <list> OptSchemaEltList
|
||||
@@ -308,7 +308,7 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <ival> Iconst
|
||||
%type <str> Sconst comment_text
|
||||
%type <str> UserId opt_boolean ColId_or_Sconst
|
||||
%type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst
|
||||
%type <list> var_list var_list_or_default
|
||||
%type <str> ColId ColLabel var_name type_name param_name
|
||||
%type <node> var_value zone_value
|
||||
@@ -336,7 +336,7 @@ static void doNegateFloat(Value *v);
|
||||
*/
|
||||
|
||||
/* ordinary key words in alphabetical order */
|
||||
%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
|
||||
%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD ADMIN AFTER
|
||||
AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
|
||||
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
|
||||
|
||||
@@ -347,8 +347,8 @@ static void doNegateFloat(Value *v);
|
||||
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
|
||||
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
|
||||
COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
|
||||
CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
|
||||
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
|
||||
CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
|
||||
CURRENT_TIMESTAMP CURRENT_ROLE CURRENT_USER CURSOR CYCLE
|
||||
|
||||
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
|
||||
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
|
||||
@@ -360,7 +360,7 @@ static void doNegateFloat(Value *v);
|
||||
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
|
||||
FREEZE FROM FULL FUNCTION
|
||||
|
||||
GLOBAL GRANT GREATEST GROUP_P
|
||||
GLOBAL GRANT GRANTED GREATEST GROUP_P
|
||||
|
||||
HANDLER HAVING HEADER HOLD HOUR_P
|
||||
|
||||
@@ -375,13 +375,13 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
|
||||
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
|
||||
LOCK_P
|
||||
LOCK_P LOGIN
|
||||
|
||||
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
|
||||
|
||||
NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
|
||||
NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P
|
||||
NULLIF NUMERIC
|
||||
NOCREATEROLE NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P
|
||||
NULLIF NUMERIC NOLOGIN
|
||||
|
||||
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
|
||||
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER
|
||||
@@ -394,10 +394,10 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
|
||||
REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT
|
||||
ROLLBACK ROW ROWS RULE
|
||||
ROLE ROLLBACK ROW ROWS RULE
|
||||
|
||||
SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
|
||||
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
|
||||
SERIALIZABLE SESSION SESSION_ROLE SESSION_USER SET SETOF SHARE
|
||||
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
|
||||
STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC
|
||||
SYSID SYSTEM_P
|
||||
@@ -497,6 +497,8 @@ stmt :
|
||||
| AlterOwnerStmt
|
||||
| AlterSeqStmt
|
||||
| AlterTableStmt
|
||||
| AlterRoleSetStmt
|
||||
| AlterRoleStmt
|
||||
| AlterUserSetStmt
|
||||
| AlterUserStmt
|
||||
| AnalyzeStmt
|
||||
@@ -520,6 +522,7 @@ stmt :
|
||||
| CreateStmt
|
||||
| CreateTableSpaceStmt
|
||||
| CreateTrigStmt
|
||||
| CreateRoleStmt
|
||||
| CreateUserStmt
|
||||
| CreatedbStmt
|
||||
| DeallocateStmt
|
||||
@@ -535,11 +538,13 @@ stmt :
|
||||
| DropStmt
|
||||
| DropTableSpaceStmt
|
||||
| DropTrigStmt
|
||||
| DropRoleStmt
|
||||
| DropUserStmt
|
||||
| DropdbStmt
|
||||
| ExecuteStmt
|
||||
| ExplainStmt
|
||||
| FetchStmt
|
||||
| GrantRoleStmt
|
||||
| GrantStmt
|
||||
| IndexStmt
|
||||
| InsertStmt
|
||||
@@ -553,6 +558,7 @@ stmt :
|
||||
| RemoveFuncStmt
|
||||
| RemoveOperStmt
|
||||
| RenameStmt
|
||||
| RevokeRoleStmt
|
||||
| RevokeStmt
|
||||
| RuleStmt
|
||||
| SelectStmt
|
||||
@@ -571,16 +577,16 @@ stmt :
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Create a new Postgres DBMS user
|
||||
* Create a new Postgres DBMS role
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateUserStmt:
|
||||
CREATE USER UserId opt_with OptUserList
|
||||
CreateRoleStmt:
|
||||
CREATE ROLE RoleId opt_with OptRoleList
|
||||
{
|
||||
CreateUserStmt *n = makeNode(CreateUserStmt);
|
||||
n->user = $3;
|
||||
CreateRoleStmt *n = makeNode(CreateRoleStmt);
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
@@ -591,6 +597,80 @@ opt_with: WITH {}
|
||||
| /*EMPTY*/ {}
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Create a new Postgres DBMS user (role with implied login ability)
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateUserStmt:
|
||||
CREATE USER RoleId opt_with OptRoleList
|
||||
{
|
||||
CreateRoleStmt *n = makeNode(CreateRoleStmt);
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
n->options = lappend(n->options,makeDefElem("canlogin", (Node *)makeInteger(TRUE)));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Alter a postgresql DBMS role
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
AlterRoleStmt:
|
||||
ALTER ROLE RoleId opt_with OptRoleList
|
||||
{
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER ROLE RoleId add_drop ROLE role_list opt_alter_admin_option
|
||||
{
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->role = $3;
|
||||
n->action = $4;
|
||||
n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6));
|
||||
n->options = lappend(n->options,makeDefElem("adminopt", (Node *)makeInteger($7)));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
add_drop: ADD { $$ = +1; }
|
||||
| DROP { $$ = -1; }
|
||||
;
|
||||
|
||||
opt_alter_admin_option:
|
||||
ADMIN OPTION { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
AlterRoleSetStmt:
|
||||
ALTER ROLE RoleId SET set_rest
|
||||
{
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = $5->name;
|
||||
n->value = $5->args;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER ROLE RoleId VariableResetStmt
|
||||
{
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = ((VariableResetStmt *)$4)->name;
|
||||
n->value = NIL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Alter a postgresql DBMS user
|
||||
@@ -599,10 +679,10 @@ opt_with: WITH {}
|
||||
*****************************************************************************/
|
||||
|
||||
AlterUserStmt:
|
||||
ALTER USER UserId opt_with OptUserList
|
||||
ALTER USER RoleId opt_with OptRoleList
|
||||
{
|
||||
AlterUserStmt *n = makeNode(AlterUserStmt);
|
||||
n->user = $3;
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
@@ -610,18 +690,18 @@ AlterUserStmt:
|
||||
|
||||
|
||||
AlterUserSetStmt:
|
||||
ALTER USER UserId SET set_rest
|
||||
ALTER USER RoleId SET set_rest
|
||||
{
|
||||
AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
|
||||
n->user = $3;
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = $5->name;
|
||||
n->value = $5->args;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER USER UserId VariableResetStmt
|
||||
| ALTER USER RoleId VariableResetStmt
|
||||
{
|
||||
AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
|
||||
n->user = $3;
|
||||
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
|
||||
n->role = $3;
|
||||
n->variable = ((VariableResetStmt *)$4)->name;
|
||||
n->value = NIL;
|
||||
$$ = (Node *)n;
|
||||
@@ -629,6 +709,24 @@ AlterUserSetStmt:
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Drop a postgresql DBMS role
|
||||
*
|
||||
* XXX Ideally this would have CASCADE/RESTRICT options, but since a role
|
||||
* might own objects in multiple databases, there is presently no way to
|
||||
* implement either cascading or restricting. Caveat DBA.
|
||||
*****************************************************************************/
|
||||
|
||||
DropRoleStmt:
|
||||
DROP ROLE role_list
|
||||
{
|
||||
DropRoleStmt *n = makeNode(DropRoleStmt);
|
||||
n->roles = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Drop a postgresql DBMS user
|
||||
@@ -639,23 +737,23 @@ AlterUserSetStmt:
|
||||
*****************************************************************************/
|
||||
|
||||
DropUserStmt:
|
||||
DROP USER user_list
|
||||
DROP USER role_list
|
||||
{
|
||||
DropUserStmt *n = makeNode(DropUserStmt);
|
||||
n->users = $3;
|
||||
DropRoleStmt *n = makeNode(DropRoleStmt);
|
||||
n->roles = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* Options for CREATE USER and ALTER USER
|
||||
* Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER for backwards compat)
|
||||
*/
|
||||
OptUserList:
|
||||
OptUserList OptUserElem { $$ = lappend($1, $2); }
|
||||
OptRoleList:
|
||||
OptRoleList OptRoleElem { $$ = lappend($1, $2); }
|
||||
| /* EMPTY */ { $$ = NIL; }
|
||||
;
|
||||
|
||||
OptUserElem:
|
||||
OptRoleElem:
|
||||
PASSWORD Sconst
|
||||
{
|
||||
$$ = makeDefElem("password", (Node *)makeString($2));
|
||||
@@ -680,66 +778,75 @@ OptUserElem:
|
||||
{
|
||||
$$ = makeDefElem("createdb", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| CREATEROLE
|
||||
{
|
||||
$$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| CREATEUSER
|
||||
{
|
||||
$$ = makeDefElem("createuser", (Node *)makeInteger(TRUE));
|
||||
$$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| LOGIN
|
||||
{
|
||||
$$ = makeDefElem("canlogin", (Node *)makeInteger(TRUE));
|
||||
}
|
||||
| NOCREATEROLE
|
||||
{
|
||||
$$ = makeDefElem("createrole", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| NOCREATEUSER
|
||||
{
|
||||
$$ = makeDefElem("createuser", (Node *)makeInteger(FALSE));
|
||||
$$ = makeDefElem("createrole", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| IN_P GROUP_P user_list
|
||||
| NOLOGIN
|
||||
{
|
||||
$$ = makeDefElem("groupElts", (Node *)$3);
|
||||
$$ = makeDefElem("canlogin", (Node *)makeInteger(FALSE));
|
||||
}
|
||||
| IN_P ROLE role_list
|
||||
{
|
||||
$$ = makeDefElem("roleElts", (Node *)$3);
|
||||
}
|
||||
| IN_P GROUP_P role_list
|
||||
{
|
||||
$$ = makeDefElem("roleElts", (Node *)$3);
|
||||
}
|
||||
| VALID UNTIL Sconst
|
||||
{
|
||||
$$ = makeDefElem("validUntil", (Node *)makeString($3));
|
||||
}
|
||||
| ROLE role_list
|
||||
{
|
||||
$$ = makeDefElem("rolememElts", (Node *)$2);
|
||||
}
|
||||
| USER role_list
|
||||
{
|
||||
$$ = makeDefElem("rolememElts", (Node *)$2);
|
||||
}
|
||||
;
|
||||
|
||||
user_list: user_list ',' UserId { $$ = lappend($1, makeString($3)); }
|
||||
| UserId { $$ = list_make1(makeString($1)); }
|
||||
role_list: role_list ',' RoleId { $$ = lappend($1, makeString($3)); }
|
||||
| RoleId { $$ = list_make1(makeString($1)); }
|
||||
;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Create a postgresql group
|
||||
* Create a postgresql group (role without login ability)
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
CreateGroupStmt:
|
||||
CREATE GROUP_P UserId opt_with OptGroupList
|
||||
CREATE GROUP_P RoleId opt_with OptRoleList
|
||||
{
|
||||
CreateGroupStmt *n = makeNode(CreateGroupStmt);
|
||||
n->name = $3;
|
||||
CreateRoleStmt *n = makeNode(CreateRoleStmt);
|
||||
n->role = $3;
|
||||
n->options = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* Options for CREATE GROUP
|
||||
*/
|
||||
OptGroupList:
|
||||
OptGroupList OptGroupElem { $$ = lappend($1, $2); }
|
||||
| /* EMPTY */ { $$ = NIL; }
|
||||
;
|
||||
|
||||
OptGroupElem:
|
||||
USER user_list
|
||||
{
|
||||
$$ = makeDefElem("userElts", (Node *)$2);
|
||||
}
|
||||
| SYSID Iconst
|
||||
{
|
||||
$$ = makeDefElem("sysid", (Node *)makeInteger($2));
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -749,20 +856,16 @@ OptGroupElem:
|
||||
*****************************************************************************/
|
||||
|
||||
AlterGroupStmt:
|
||||
ALTER GROUP_P UserId add_drop USER user_list
|
||||
ALTER GROUP_P RoleId add_drop USER role_list
|
||||
{
|
||||
AlterGroupStmt *n = makeNode(AlterGroupStmt);
|
||||
n->name = $3;
|
||||
AlterRoleStmt *n = makeNode(AlterRoleStmt);
|
||||
n->role = $3;
|
||||
n->action = $4;
|
||||
n->listUsers = $6;
|
||||
n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6));
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
add_drop: ADD { $$ = +1; }
|
||||
| DROP { $$ = -1; }
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -772,10 +875,10 @@ add_drop: ADD { $$ = +1; }
|
||||
*****************************************************************************/
|
||||
|
||||
DropGroupStmt:
|
||||
DROP GROUP_P UserId
|
||||
DROP GROUP_P role_list
|
||||
{
|
||||
DropGroupStmt *n = makeNode(DropGroupStmt);
|
||||
n->name = $3;
|
||||
DropRoleStmt *n = makeNode(DropRoleStmt);
|
||||
n->roles = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@@ -788,7 +891,7 @@ DropGroupStmt:
|
||||
*****************************************************************************/
|
||||
|
||||
CreateSchemaStmt:
|
||||
CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList
|
||||
CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
|
||||
{
|
||||
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
|
||||
/* One can omit the schema name or the authorization id. */
|
||||
@@ -1307,8 +1410,8 @@ alter_rel_cmds:
|
||||
|
||||
/* Subcommands that are for ALTER TABLE or ALTER INDEX */
|
||||
alter_rel_cmd:
|
||||
/* ALTER [TABLE|INDEX] <name> OWNER TO UserId */
|
||||
OWNER TO UserId
|
||||
/* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
|
||||
OWNER TO RoleId
|
||||
{
|
||||
AlterTableCmd *n = makeNode(AlterTableCmd);
|
||||
n->subtype = AT_ChangeOwner;
|
||||
@@ -3013,6 +3116,36 @@ from_in: FROM {}
|
||||
;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* GRANT and REVOKE ROLE statements
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
GrantRoleStmt: GRANT ROLE role_list TO role_list opt_grant_admin_option
|
||||
opt_granted_by
|
||||
{
|
||||
GrantRoleStmt *n = makeNode(GrantRoleStmt);
|
||||
n->granted_roles = $3;
|
||||
n->grantee_roles = $5;
|
||||
n->is_grant = true;
|
||||
n->admin_opt = $6;
|
||||
n->grantor = $7;
|
||||
$$ = (Node*)n;
|
||||
}
|
||||
|
||||
RevokeRoleStmt: REVOKE ROLE opt_revoke_admin_option role_list FROM role_list
|
||||
opt_drop_behavior
|
||||
{
|
||||
GrantRoleStmt *n = makeNode(GrantRoleStmt);
|
||||
n->granted_roles = $4;
|
||||
n->grantee_roles = $6;
|
||||
n->is_grant = false;
|
||||
n->admin_opt = $3;
|
||||
n->behavior = $7;
|
||||
$$ = (Node*)n;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* GRANT and REVOKE statements
|
||||
@@ -3139,26 +3272,24 @@ grantee_list:
|
||||
| grantee_list ',' grantee { $$ = lappend($1, $3); }
|
||||
;
|
||||
|
||||
grantee: ColId
|
||||
grantee: RoleId
|
||||
{
|
||||
PrivGrantee *n = makeNode(PrivGrantee);
|
||||
/* This hack lets us avoid reserving PUBLIC as a keyword*/
|
||||
if (strcmp($1, "public") == 0)
|
||||
n->username = NULL;
|
||||
n->rolname = NULL;
|
||||
else
|
||||
n->username = $1;
|
||||
n->groupname = NULL;
|
||||
n->rolname = $1;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| GROUP_P ColId
|
||||
| GROUP_P RoleId
|
||||
{
|
||||
PrivGrantee *n = makeNode(PrivGrantee);
|
||||
/* Treat GROUP PUBLIC as a synonym for PUBLIC */
|
||||
if (strcmp($2, "public") == 0)
|
||||
n->groupname = NULL;
|
||||
n->rolname = NULL;
|
||||
else
|
||||
n->groupname = $2;
|
||||
n->username = NULL;
|
||||
n->rolname = $2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@@ -3169,11 +3300,26 @@ opt_grant_grant_option:
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
opt_grant_admin_option:
|
||||
WITH ADMIN OPTION { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
opt_granted_by:
|
||||
GRANTED BY RoleId { $$ = $3; }
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
opt_revoke_grant_option:
|
||||
GRANT OPTION FOR { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
opt_revoke_admin_option:
|
||||
ADMIN OPTION FOR { $$ = TRUE; }
|
||||
| /*EMPTY*/ { $$ = FALSE; }
|
||||
;
|
||||
|
||||
|
||||
function_with_argtypes_list:
|
||||
function_with_argtypes { $$ = list_make1($1); }
|
||||
@@ -3727,10 +3873,10 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
|
||||
n->newname = $7;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER GROUP_P UserId RENAME TO UserId
|
||||
| ALTER GROUP_P RoleId RENAME TO RoleId
|
||||
{
|
||||
RenameStmt *n = makeNode(RenameStmt);
|
||||
n->renameType = OBJECT_GROUP;
|
||||
n->renameType = OBJECT_ROLE;
|
||||
n->subname = $3;
|
||||
n->newname = $6;
|
||||
$$ = (Node *)n;
|
||||
@@ -3796,10 +3942,18 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
|
||||
n->renameType = OBJECT_TRIGGER;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER USER UserId RENAME TO UserId
|
||||
| ALTER ROLE RoleId RENAME TO RoleId
|
||||
{
|
||||
RenameStmt *n = makeNode(RenameStmt);
|
||||
n->renameType = OBJECT_USER;
|
||||
n->renameType = OBJECT_ROLE;
|
||||
n->subname = $3;
|
||||
n->newname = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER USER RoleId RENAME TO RoleId
|
||||
{
|
||||
RenameStmt *n = makeNode(RenameStmt);
|
||||
n->renameType = OBJECT_ROLE;
|
||||
n->subname = $3;
|
||||
n->newname = $6;
|
||||
$$ = (Node *)n;
|
||||
@@ -3825,7 +3979,7 @@ opt_column: COLUMN { $$ = COLUMN; }
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_AGGREGATE;
|
||||
@@ -3834,7 +3988,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $9;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER CONVERSION_P any_name OWNER TO UserId
|
||||
| ALTER CONVERSION_P any_name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_CONVERSION;
|
||||
@@ -3842,7 +3996,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER DATABASE database_name OWNER TO UserId
|
||||
| ALTER DATABASE database_name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_DATABASE;
|
||||
@@ -3850,7 +4004,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER DOMAIN_P any_name OWNER TO UserId
|
||||
| ALTER DOMAIN_P any_name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_DOMAIN;
|
||||
@@ -3858,7 +4012,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER FUNCTION func_name func_args OWNER TO UserId
|
||||
| ALTER FUNCTION func_name func_args OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_FUNCTION;
|
||||
@@ -3867,7 +4021,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $7;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO UserId
|
||||
| ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_OPERATOR;
|
||||
@@ -3876,7 +4030,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $9;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER OPERATOR CLASS any_name USING access_method OWNER TO UserId
|
||||
| ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_OPCLASS;
|
||||
@@ -3885,7 +4039,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $9;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER SCHEMA name OWNER TO UserId
|
||||
| ALTER SCHEMA name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_SCHEMA;
|
||||
@@ -3893,7 +4047,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER TYPE_P any_name OWNER TO UserId
|
||||
| ALTER TYPE_P any_name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_TYPE;
|
||||
@@ -3901,7 +4055,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
|
||||
n->newowner = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ALTER TABLESPACE name OWNER TO UserId
|
||||
| ALTER TABLESPACE name OWNER TO RoleId
|
||||
{
|
||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||
n->objectType = OBJECT_TABLESPACE;
|
||||
@@ -6903,6 +7057,33 @@ func_expr: func_name '(' ')'
|
||||
|
||||
$$ = (Node *)makeTypeCast((Node *)s, d);
|
||||
}
|
||||
| CURRENT_ROLE
|
||||
{
|
||||
FuncCall *n = makeNode(FuncCall);
|
||||
n->funcname = SystemFuncName("current_user");
|
||||
n->args = NIL;
|
||||
n->agg_star = FALSE;
|
||||
n->agg_distinct = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| SESSION_ROLE
|
||||
{
|
||||
FuncCall *n = makeNode(FuncCall);
|
||||
n->funcname = SystemFuncName("session_user");
|
||||
n->args = NIL;
|
||||
n->agg_star = FALSE;
|
||||
n->agg_distinct = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| ROLE
|
||||
{
|
||||
FuncCall *n = makeNode(FuncCall);
|
||||
n->funcname = SystemFuncName("current_user");
|
||||
n->args = NIL;
|
||||
n->agg_star = FALSE;
|
||||
n->agg_distinct = FALSE;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CURRENT_USER
|
||||
{
|
||||
FuncCall *n = makeNode(FuncCall);
|
||||
@@ -7685,7 +7866,7 @@ AexprConst: Iconst
|
||||
|
||||
Iconst: ICONST { $$ = $1; };
|
||||
Sconst: SCONST { $$ = $1; };
|
||||
UserId: ColId { $$ = $1; };
|
||||
RoleId: ColId { $$ = $1; };
|
||||
|
||||
/*
|
||||
* Name classification hierarchy.
|
||||
@@ -7774,6 +7955,7 @@ unreserved_keyword:
|
||||
| CONVERSION_P
|
||||
| COPY
|
||||
| CREATEDB
|
||||
| CREATEROLE
|
||||
| CREATEUSER
|
||||
| CSV
|
||||
| CURSOR
|
||||
@@ -7834,6 +8016,7 @@ unreserved_keyword:
|
||||
| LOCAL
|
||||
| LOCATION
|
||||
| LOCK_P
|
||||
| LOGIN
|
||||
| MATCH
|
||||
| MAXVALUE
|
||||
| MINUTE_P
|
||||
@@ -7845,7 +8028,9 @@ unreserved_keyword:
|
||||
| NEXT
|
||||
| NO
|
||||
| NOCREATEDB
|
||||
| NOCREATEROLE
|
||||
| NOCREATEUSER
|
||||
| NOLOGIN
|
||||
| NOTHING
|
||||
| NOTIFY
|
||||
| NOWAIT
|
||||
@@ -8045,6 +8230,7 @@ reserved_keyword:
|
||||
| CURRENT_DATE
|
||||
| CURRENT_TIME
|
||||
| CURRENT_TIMESTAMP
|
||||
| CURRENT_ROLE
|
||||
| CURRENT_USER
|
||||
| DEFAULT
|
||||
| DEFERRABLE
|
||||
@@ -8083,6 +8269,7 @@ reserved_keyword:
|
||||
| PRIMARY
|
||||
| REFERENCES
|
||||
| SELECT
|
||||
| SESSION_ROLE
|
||||
| SESSION_USER
|
||||
| SOME
|
||||
| SYMMETRIC
|
||||
@@ -8093,6 +8280,7 @@ reserved_keyword:
|
||||
| TRUE_P
|
||||
| UNION
|
||||
| UNIQUE
|
||||
| ROLE
|
||||
| USER
|
||||
| USING
|
||||
| WHEN
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.159 2005/06/26 22:05:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.160 2005/06/28 05:08:58 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -269,6 +269,7 @@ static const ScanKeyword ScanKeywords[] = {
|
||||
{"returns", RETURNS},
|
||||
{"revoke", REVOKE},
|
||||
{"right", RIGHT},
|
||||
{"role", ROLE},
|
||||
{"rollback", ROLLBACK},
|
||||
{"row", ROW},
|
||||
{"rows", ROWS},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.111 2005/06/05 00:38:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.112 2005/06/28 05:08:58 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -567,7 +567,7 @@ addRangeTableEntry(ParseState *pstate,
|
||||
rte->inFromCl = inFromCl;
|
||||
|
||||
rte->requiredPerms = ACL_SELECT;
|
||||
rte->checkAsUser = 0; /* not set-uid by default, either */
|
||||
rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
|
||||
|
||||
/*
|
||||
* Add completed RTE to pstate's range table list, but not to join
|
||||
@@ -620,7 +620,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
|
||||
rte->inFromCl = inFromCl;
|
||||
|
||||
rte->requiredPerms = ACL_SELECT;
|
||||
rte->checkAsUser = 0; /* not set-uid by default, either */
|
||||
rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
|
||||
|
||||
/*
|
||||
* Add completed RTE to pstate's range table list, but not to join
|
||||
@@ -698,7 +698,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
|
||||
rte->inFromCl = inFromCl;
|
||||
|
||||
rte->requiredPerms = 0;
|
||||
rte->checkAsUser = 0;
|
||||
rte->checkAsUser = InvalidOid;
|
||||
|
||||
/*
|
||||
* Add completed RTE to pstate's range table list, but not to join
|
||||
@@ -823,7 +823,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
|
||||
rte->inFromCl = inFromCl;
|
||||
|
||||
rte->requiredPerms = 0;
|
||||
rte->checkAsUser = 0;
|
||||
rte->checkAsUser = InvalidOid;
|
||||
|
||||
/*
|
||||
* Add completed RTE to pstate's range table list, but not to join
|
||||
@@ -882,7 +882,7 @@ addRangeTableEntryForJoin(ParseState *pstate,
|
||||
rte->inFromCl = inFromCl;
|
||||
|
||||
rte->requiredPerms = 0;
|
||||
rte->checkAsUser = 0;
|
||||
rte->checkAsUser = InvalidOid;
|
||||
|
||||
/*
|
||||
* Add completed RTE to pstate's range table list, but not to join
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
*
|
||||
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.96 2005/06/25 23:58:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.97 2005/06/28 05:08:59 tgl Exp $
|
||||
* ----------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "access/heapam.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "libpq/libpq.h"
|
||||
#include "libpq/pqsignal.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.454 2005/06/17 22:32:44 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.455 2005/06/28 05:08:59 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
@@ -2032,12 +2032,11 @@ reaper(SIGNAL_ARGS)
|
||||
FatalError = false;
|
||||
|
||||
/*
|
||||
* Load the flat user/group files into postmaster's caches.
|
||||
* The startup process has recomputed these from the database
|
||||
* contents, so we wait till it finishes before loading them.
|
||||
* Load the flat authorization file into postmaster's cache.
|
||||
* The startup process has recomputed this from the database
|
||||
* contents, so we wait till it finishes before loading it.
|
||||
*/
|
||||
load_user();
|
||||
load_group();
|
||||
load_role();
|
||||
|
||||
/*
|
||||
* Crank up the background writer. It doesn't matter if this
|
||||
@@ -2664,8 +2663,7 @@ BackendRun(Port *port)
|
||||
|
||||
load_hba();
|
||||
load_ident();
|
||||
load_user();
|
||||
load_group();
|
||||
load_role();
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -3290,10 +3288,9 @@ sigusr1_handler(SIGNAL_ARGS)
|
||||
if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE))
|
||||
{
|
||||
/*
|
||||
* Password or group file has changed.
|
||||
* Authorization file has changed.
|
||||
*/
|
||||
load_user();
|
||||
load_group();
|
||||
load_role();
|
||||
}
|
||||
|
||||
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.104 2005/04/14 20:03:25 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.105 2005/06/28 05:08:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
static void setRuleCheckAsUser_Query(Query *qry, AclId userid);
|
||||
static void setRuleCheckAsUser_Expr(Node *node, AclId userid);
|
||||
static bool setRuleCheckAsUser_walker(Node *node, AclId *context);
|
||||
static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
|
||||
static void setRuleCheckAsUser_Expr(Node *node, Oid userid);
|
||||
static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
|
||||
|
||||
|
||||
/*
|
||||
@@ -505,7 +505,7 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||
* them always.
|
||||
*/
|
||||
static void
|
||||
setRuleCheckAsUser_Query(Query *qry, AclId userid)
|
||||
setRuleCheckAsUser_Query(Query *qry, Oid userid)
|
||||
{
|
||||
ListCell *l;
|
||||
|
||||
@@ -534,13 +534,13 @@ setRuleCheckAsUser_Query(Query *qry, AclId userid)
|
||||
* Expression-tree walker to find sublink queries
|
||||
*/
|
||||
static void
|
||||
setRuleCheckAsUser_Expr(Node *node, AclId userid)
|
||||
setRuleCheckAsUser_Expr(Node *node, Oid userid)
|
||||
{
|
||||
(void) setRuleCheckAsUser_walker(node, &userid);
|
||||
}
|
||||
|
||||
static bool
|
||||
setRuleCheckAsUser_walker(Node *node, AclId *context)
|
||||
setRuleCheckAsUser_walker(Node *node, Oid *context)
|
||||
{
|
||||
if (node == NULL)
|
||||
return false;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.154 2005/06/04 19:19:42 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.155 2005/06/28 05:08:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -945,7 +945,7 @@ ApplyRetrieveRule(Query *parsetree,
|
||||
subrte->checkAsUser = rte->checkAsUser;
|
||||
|
||||
rte->requiredPerms = 0; /* no permission check on subquery itself */
|
||||
rte->checkAsUser = 0;
|
||||
rte->checkAsUser = InvalidOid;
|
||||
|
||||
/*
|
||||
* FOR UPDATE/SHARE of view?
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.238 2005/06/22 21:14:30 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.239 2005/06/28 05:09:00 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "access/twophase.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "commands/alter.h"
|
||||
#include "commands/async.h"
|
||||
#include "commands/cluster.h"
|
||||
@@ -279,12 +278,11 @@ check_xact_readonly(Node *parsetree)
|
||||
case T_AlterDatabaseSetStmt:
|
||||
case T_AlterDomainStmt:
|
||||
case T_AlterFunctionStmt:
|
||||
case T_AlterGroupStmt:
|
||||
case T_AlterRoleStmt:
|
||||
case T_AlterRoleSetStmt:
|
||||
case T_AlterOwnerStmt:
|
||||
case T_AlterSeqStmt:
|
||||
case T_AlterTableStmt:
|
||||
case T_AlterUserStmt:
|
||||
case T_AlterUserSetStmt:
|
||||
case T_RenameStmt:
|
||||
case T_CommentStmt:
|
||||
case T_DefineStmt:
|
||||
@@ -293,7 +291,7 @@ check_xact_readonly(Node *parsetree)
|
||||
case T_CreatedbStmt:
|
||||
case T_CreateDomainStmt:
|
||||
case T_CreateFunctionStmt:
|
||||
case T_CreateGroupStmt:
|
||||
case T_CreateRoleStmt:
|
||||
case T_IndexStmt:
|
||||
case T_CreatePLangStmt:
|
||||
case T_CreateOpClassStmt:
|
||||
@@ -304,7 +302,6 @@ check_xact_readonly(Node *parsetree)
|
||||
case T_CreateTableSpaceStmt:
|
||||
case T_CreateTrigStmt:
|
||||
case T_CompositeTypeStmt:
|
||||
case T_CreateUserStmt:
|
||||
case T_ViewStmt:
|
||||
case T_RemoveAggrStmt:
|
||||
case T_DropCastStmt:
|
||||
@@ -312,13 +309,13 @@ check_xact_readonly(Node *parsetree)
|
||||
case T_DropdbStmt:
|
||||
case T_DropTableSpaceStmt:
|
||||
case T_RemoveFuncStmt:
|
||||
case T_DropGroupStmt:
|
||||
case T_DropRoleStmt:
|
||||
case T_DropPLangStmt:
|
||||
case T_RemoveOperStmt:
|
||||
case T_RemoveOpClassStmt:
|
||||
case T_DropPropertyStmt:
|
||||
case T_DropUserStmt:
|
||||
case T_GrantStmt:
|
||||
case T_GrantRoleStmt:
|
||||
case T_TruncateStmt:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
|
||||
@@ -679,11 +676,14 @@ ProcessUtility(Node *parsetree,
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case T_GrantStmt:
|
||||
ExecuteGrantStmt((GrantStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_GrantRoleStmt:
|
||||
GrantRole((GrantRoleStmt *) parsetree);
|
||||
break;
|
||||
|
||||
/*
|
||||
* ******************************** object creation /
|
||||
* destruction ********************************
|
||||
@@ -958,22 +958,22 @@ ProcessUtility(Node *parsetree,
|
||||
break;
|
||||
|
||||
/*
|
||||
* ******************************** USER statements ****
|
||||
* ******************************** ROLE statements ****
|
||||
*/
|
||||
case T_CreateUserStmt:
|
||||
CreateUser((CreateUserStmt *) parsetree);
|
||||
case T_CreateRoleStmt:
|
||||
CreateRole((CreateRoleStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_AlterUserStmt:
|
||||
AlterUser((AlterUserStmt *) parsetree);
|
||||
case T_AlterRoleStmt:
|
||||
AlterRole((AlterRoleStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_AlterUserSetStmt:
|
||||
AlterUserSet((AlterUserSetStmt *) parsetree);
|
||||
case T_AlterRoleSetStmt:
|
||||
AlterRoleSet((AlterRoleSetStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_DropUserStmt:
|
||||
DropUser((DropUserStmt *) parsetree);
|
||||
case T_DropRoleStmt:
|
||||
DropRole((DropRoleStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_LockStmt:
|
||||
@@ -984,18 +984,6 @@ ProcessUtility(Node *parsetree,
|
||||
AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_CreateGroupStmt:
|
||||
CreateGroup((CreateGroupStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_AlterGroupStmt:
|
||||
AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
|
||||
break;
|
||||
|
||||
case T_DropGroupStmt:
|
||||
DropGroup((DropGroupStmt *) parsetree);
|
||||
break;
|
||||
|
||||
case T_CheckPointStmt:
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
@@ -1350,9 +1338,6 @@ CreateCommandTag(Node *parsetree)
|
||||
case OBJECT_FUNCTION:
|
||||
tag = "ALTER FUNCTION";
|
||||
break;
|
||||
case OBJECT_GROUP:
|
||||
tag = "ALTER GROUP";
|
||||
break;
|
||||
case OBJECT_INDEX:
|
||||
tag = "ALTER INDEX";
|
||||
break;
|
||||
@@ -1362,6 +1347,9 @@ CreateCommandTag(Node *parsetree)
|
||||
case OBJECT_OPCLASS:
|
||||
tag = "ALTER OPERATOR CLASS";
|
||||
break;
|
||||
case OBJECT_ROLE:
|
||||
tag = "ALTER ROLE";
|
||||
break;
|
||||
case OBJECT_SCHEMA:
|
||||
tag = "ALTER SCHEMA";
|
||||
break;
|
||||
@@ -1371,9 +1359,6 @@ CreateCommandTag(Node *parsetree)
|
||||
case OBJECT_TRIGGER:
|
||||
tag = "ALTER TRIGGER";
|
||||
break;
|
||||
case OBJECT_USER:
|
||||
tag = "ALTER USER";
|
||||
break;
|
||||
default:
|
||||
tag = "ALTER TABLE";
|
||||
}
|
||||
@@ -1450,6 +1435,14 @@ CreateCommandTag(Node *parsetree)
|
||||
}
|
||||
break;
|
||||
|
||||
case T_GrantRoleStmt:
|
||||
{
|
||||
GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
|
||||
|
||||
tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
|
||||
}
|
||||
break;
|
||||
|
||||
case T_DefineStmt:
|
||||
switch (((DefineStmt *) parsetree)->kind)
|
||||
{
|
||||
@@ -1588,20 +1581,20 @@ CreateCommandTag(Node *parsetree)
|
||||
tag = "DROP LANGUAGE";
|
||||
break;
|
||||
|
||||
case T_CreateUserStmt:
|
||||
tag = "CREATE USER";
|
||||
case T_CreateRoleStmt:
|
||||
tag = "CREATE ROLE";
|
||||
break;
|
||||
|
||||
case T_AlterUserStmt:
|
||||
tag = "ALTER USER";
|
||||
case T_AlterRoleStmt:
|
||||
tag = "ALTER ROLE";
|
||||
break;
|
||||
|
||||
case T_AlterUserSetStmt:
|
||||
tag = "ALTER USER";
|
||||
case T_AlterRoleSetStmt:
|
||||
tag = "ALTER ROLE";
|
||||
break;
|
||||
|
||||
case T_DropUserStmt:
|
||||
tag = "DROP USER";
|
||||
case T_DropRoleStmt:
|
||||
tag = "DROP ROLE";
|
||||
break;
|
||||
|
||||
case T_LockStmt:
|
||||
@@ -1612,18 +1605,6 @@ CreateCommandTag(Node *parsetree)
|
||||
tag = "SET CONSTRAINTS";
|
||||
break;
|
||||
|
||||
case T_CreateGroupStmt:
|
||||
tag = "CREATE GROUP";
|
||||
break;
|
||||
|
||||
case T_AlterGroupStmt:
|
||||
tag = "ALTER GROUP";
|
||||
break;
|
||||
|
||||
case T_DropGroupStmt:
|
||||
tag = "DROP GROUP";
|
||||
break;
|
||||
|
||||
case T_CheckPointStmt:
|
||||
tag = "CHECKPOINT";
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,14 +8,13 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.22 2005/05/11 01:41:41 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.23 2005/06/28 05:09:00 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/xact.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "fmgr.h"
|
||||
#include "funcapi.h"
|
||||
#include "miscadmin.h"
|
||||
@@ -306,7 +305,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
|
||||
if (!OidIsValid(beentry->userid))
|
||||
PG_RETURN_NULL();
|
||||
|
||||
PG_RETURN_INT32(beentry->userid);
|
||||
PG_RETURN_OID(beentry->userid);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.79 2005/05/30 07:20:58 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.80 2005/06/28 05:09:00 tgl Exp $
|
||||
*
|
||||
* ----------
|
||||
*/
|
||||
@@ -3036,7 +3036,7 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
|
||||
{
|
||||
void *qplan;
|
||||
Relation query_rel;
|
||||
AclId save_uid;
|
||||
Oid save_uid;
|
||||
|
||||
/*
|
||||
* The query is always run against the FK table except when this is an
|
||||
@@ -3089,7 +3089,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
|
||||
Snapshot crosscheck_snapshot;
|
||||
int limit;
|
||||
int spi_result;
|
||||
AclId save_uid;
|
||||
Oid save_uid;
|
||||
Datum vals[RI_MAX_NUMKEYS * 2];
|
||||
char nulls[RI_MAX_NUMKEYS * 2];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* back to source text
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.201 2005/06/26 22:05:40 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.202 2005/06/28 05:09:01 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@@ -46,13 +46,13 @@
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_cast.h"
|
||||
#include "catalog/pg_constraint.h"
|
||||
#include "catalog/pg_depend.h"
|
||||
#include "catalog/pg_index.h"
|
||||
#include "catalog/pg_opclass.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_trigger.h"
|
||||
#include "executor/spi.h"
|
||||
#include "funcapi.h"
|
||||
@@ -1194,17 +1194,17 @@ pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags)
|
||||
|
||||
|
||||
/* ----------
|
||||
* get_userbyid - Get a user name by usesysid and
|
||||
* fallback to 'unknown (UID=n)'
|
||||
* get_userbyid - Get a user name by roleid and
|
||||
* fallback to 'unknown (OID=n)'
|
||||
* ----------
|
||||
*/
|
||||
Datum
|
||||
pg_get_userbyid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int32 uid = PG_GETARG_INT32(0);
|
||||
Oid roleid = PG_GETARG_OID(0);
|
||||
Name result;
|
||||
HeapTuple usertup;
|
||||
Form_pg_shadow user_rec;
|
||||
HeapTuple roletup;
|
||||
Form_pg_authid role_rec;
|
||||
|
||||
/*
|
||||
* Allocate space for the result
|
||||
@@ -1213,19 +1213,19 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
|
||||
memset(NameStr(*result), 0, NAMEDATALEN);
|
||||
|
||||
/*
|
||||
* Get the pg_shadow entry and print the result
|
||||
* Get the pg_authid entry and print the result
|
||||
*/
|
||||
usertup = SearchSysCache(SHADOWSYSID,
|
||||
ObjectIdGetDatum(uid),
|
||||
roletup = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(roleid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(usertup))
|
||||
if (HeapTupleIsValid(roletup))
|
||||
{
|
||||
user_rec = (Form_pg_shadow) GETSTRUCT(usertup);
|
||||
StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN);
|
||||
ReleaseSysCache(usertup);
|
||||
role_rec = (Form_pg_authid) GETSTRUCT(roletup);
|
||||
StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN);
|
||||
ReleaseSysCache(roletup);
|
||||
}
|
||||
else
|
||||
sprintf(NameStr(*result), "unknown (UID=%d)", uid);
|
||||
sprintf(NameStr(*result), "unknown (OID=%u)", roleid);
|
||||
|
||||
PG_RETURN_NAME(result);
|
||||
}
|
||||
|
||||
73
src/backend/utils/cache/lsyscache.c
vendored
73
src/backend/utils/cache/lsyscache.c
vendored
@@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.125 2005/05/01 18:56:19 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.126 2005/06/28 05:09:01 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Eventually, the index information should go through here, too.
|
||||
@@ -24,8 +24,6 @@
|
||||
#include "catalog/pg_opclass.h"
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/pg_statistic.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
@@ -2010,66 +2008,35 @@ get_namespace_name(Oid nspid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ---------- PG_SHADOW CACHE ---------- */
|
||||
/* ---------- PG_AUTHID CACHE ---------- */
|
||||
|
||||
/*
|
||||
* get_usesysid
|
||||
*
|
||||
* Given a user name, look up the user's sysid.
|
||||
* Raises an error if no such user (rather than returning zero,
|
||||
* which might possibly be a valid usesysid).
|
||||
*
|
||||
* Note: the type of usesysid is currently int4, but may change to Oid
|
||||
* someday. It'd be reasonable to return zero on failure if we were
|
||||
* using Oid ...
|
||||
* get_roleid
|
||||
* Given a role name, look up the role's OID.
|
||||
* Returns InvalidOid if no such role.
|
||||
*/
|
||||
AclId
|
||||
get_usesysid(const char *username)
|
||||
Oid
|
||||
get_roleid(const char *rolname)
|
||||
{
|
||||
AclId userId;
|
||||
HeapTuple userTup;
|
||||
|
||||
userTup = SearchSysCache(SHADOWNAME,
|
||||
PointerGetDatum(username),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(userTup))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("user \"%s\" does not exist", username)));
|
||||
|
||||
userId = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
|
||||
|
||||
ReleaseSysCache(userTup);
|
||||
|
||||
return userId;
|
||||
return GetSysCacheOid(AUTHNAME,
|
||||
PointerGetDatum(rolname),
|
||||
0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_grosysid
|
||||
*
|
||||
* Given a group name, look up the group's sysid.
|
||||
* Raises an error if no such group (rather than returning zero,
|
||||
* which might possibly be a valid grosysid).
|
||||
*
|
||||
* get_roleid_checked
|
||||
* Given a role name, look up the role's OID.
|
||||
* ereports if no such role.
|
||||
*/
|
||||
AclId
|
||||
get_grosysid(char *groname)
|
||||
Oid
|
||||
get_roleid_checked(const char *rolname)
|
||||
{
|
||||
AclId groupId;
|
||||
HeapTuple groupTup;
|
||||
Oid roleid;
|
||||
|
||||
groupTup = SearchSysCache(GRONAME,
|
||||
PointerGetDatum(groname),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(groupTup))
|
||||
roleid = get_roleid(rolname);
|
||||
if (!OidIsValid(roleid))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("group \"%s\" does not exist", groname)));
|
||||
|
||||
groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid;
|
||||
|
||||
ReleaseSysCache(groupTup);
|
||||
|
||||
return groupId;
|
||||
errmsg("role \"%s\" does not exist", rolname)));
|
||||
return roleid;
|
||||
}
|
||||
|
||||
|
||||
86
src/backend/utils/cache/syscache.c
vendored
86
src/backend/utils/cache/syscache.c
vendored
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.99 2005/05/11 01:26:02 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.100 2005/06/28 05:09:01 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* These routines allow the parser/planner/executor to perform
|
||||
@@ -27,9 +27,10 @@
|
||||
#include "catalog/pg_aggregate.h"
|
||||
#include "catalog/pg_amop.h"
|
||||
#include "catalog/pg_amproc.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_auth_members.h"
|
||||
#include "catalog/pg_cast.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/pg_index.h"
|
||||
#include "catalog/pg_inherits.h"
|
||||
#include "catalog/pg_language.h"
|
||||
@@ -38,7 +39,6 @@
|
||||
#include "catalog/pg_operator.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_rewrite.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_statistic.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "utils/catcache.h"
|
||||
@@ -172,6 +172,46 @@ static const struct cachedesc cacheinfo[] = {
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{AuthMemRelationId, /* AUTHMEMMEMROLE */
|
||||
AuthMemMemRoleIndexId,
|
||||
0,
|
||||
2,
|
||||
{
|
||||
Anum_pg_auth_members_member,
|
||||
Anum_pg_auth_members_roleid,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{AuthMemRelationId, /* AUTHMEMROLEMEM */
|
||||
AuthMemRoleMemIndexId,
|
||||
0,
|
||||
2,
|
||||
{
|
||||
Anum_pg_auth_members_roleid,
|
||||
Anum_pg_auth_members_member,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{AuthIdRelationId, /* AUTHNAME */
|
||||
AuthIdRolnameIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
Anum_pg_authid_rolname,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{AuthIdRelationId, /* AUTHOID */
|
||||
AuthIdOidIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
ObjectIdAttributeNumber,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{
|
||||
CastRelationId, /* CASTSOURCETARGET */
|
||||
CastSourceTargetIndexId,
|
||||
@@ -233,26 +273,6 @@ static const struct cachedesc cacheinfo[] = {
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{GroupRelationId, /* GRONAME */
|
||||
GroupNameIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
Anum_pg_group_groname,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{GroupRelationId, /* GROSYSID */
|
||||
GroupSysidIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
Anum_pg_group_grosysid,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{IndexRelationId, /* INDEXRELID */
|
||||
IndexRelidIndexId,
|
||||
Anum_pg_index_indrelid,
|
||||
@@ -383,26 +403,6 @@ static const struct cachedesc cacheinfo[] = {
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{ShadowRelationId, /* SHADOWNAME */
|
||||
ShadowNameIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
Anum_pg_shadow_usename,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{ShadowRelationId, /* SHADOWSYSID */
|
||||
ShadowSysidIndexId,
|
||||
0,
|
||||
1,
|
||||
{
|
||||
Anum_pg_shadow_usesysid,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
}},
|
||||
{StatisticRelationId, /* STATRELATT */
|
||||
StatisticRelidAttnumIndexId,
|
||||
Anum_pg_statistic_starelid,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.95 2005/05/29 04:23:06 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.96 2005/06/28 05:09:01 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -769,7 +769,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
|
||||
struct fmgr_security_definer_cache
|
||||
{
|
||||
FmgrInfo flinfo;
|
||||
AclId userid;
|
||||
Oid userid;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -786,7 +786,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
|
||||
Datum result;
|
||||
FmgrInfo *save_flinfo;
|
||||
struct fmgr_security_definer_cache * volatile fcache;
|
||||
AclId save_userid;
|
||||
Oid save_userid;
|
||||
HeapTuple tuple;
|
||||
|
||||
if (!fcinfo->flinfo->fn_extra)
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
* Routines for maintaining "flat file" images of the shared catalogs.
|
||||
*
|
||||
* We use flat files so that the postmaster and not-yet-fully-started
|
||||
* backends can look at the contents of pg_database, pg_shadow, and pg_group
|
||||
* for authentication purposes. This module is responsible for keeping the
|
||||
* flat-file images as nearly in sync with database reality as possible.
|
||||
* backends can look at the contents of pg_database, pg_authid, and
|
||||
* pg_auth_members for authentication purposes. This module is
|
||||
* responsible for keeping the flat-file images as nearly in sync with
|
||||
* database reality as possible.
|
||||
*
|
||||
* The tricky part of the write_xxx_file() routines in this module is that
|
||||
* they need to be able to operate in the context of the database startup
|
||||
@@ -22,7 +23,7 @@
|
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.8 2005/06/17 22:32:47 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.9 2005/06/28 05:09:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -31,12 +32,14 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "access/twophase_rmgr.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_auth_members.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_group.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "miscadmin.h"
|
||||
@@ -45,19 +48,18 @@
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/flatfiles.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/resowner.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/* Actual names of the flat files (within $PGDATA/global/) */
|
||||
#define DATABASE_FLAT_FILE "pg_database"
|
||||
#define GROUP_FLAT_FILE "pg_group"
|
||||
#define USER_FLAT_FILE "pg_pwd"
|
||||
#define AUTH_FLAT_FILE "pg_auth"
|
||||
|
||||
/* Info bits in a flatfiles 2PC record */
|
||||
#define FF_BIT_DATABASE 1
|
||||
#define FF_BIT_GROUP 2
|
||||
#define FF_BIT_USER 4
|
||||
#define FF_BIT_AUTH 2
|
||||
|
||||
|
||||
/*
|
||||
@@ -73,8 +75,7 @@
|
||||
* SubTransactionId is seen at top-level commit.
|
||||
*/
|
||||
static SubTransactionId database_file_update_subid = InvalidSubTransactionId;
|
||||
static SubTransactionId group_file_update_subid = InvalidSubTransactionId;
|
||||
static SubTransactionId user_file_update_subid = InvalidSubTransactionId;
|
||||
static SubTransactionId auth_file_update_subid = InvalidSubTransactionId;
|
||||
|
||||
|
||||
/*
|
||||
@@ -88,23 +89,13 @@ database_file_update_needed(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark flat group file as needing an update (because pg_group changed)
|
||||
* Mark flat auth file as needing an update (because pg_auth changed)
|
||||
*/
|
||||
void
|
||||
group_file_update_needed(void)
|
||||
auth_file_update_needed(void)
|
||||
{
|
||||
if (group_file_update_subid == InvalidSubTransactionId)
|
||||
group_file_update_subid = GetCurrentSubTransactionId();
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark flat user file as needing an update (because pg_shadow changed)
|
||||
*/
|
||||
void
|
||||
user_file_update_needed(void)
|
||||
{
|
||||
if (user_file_update_subid == InvalidSubTransactionId)
|
||||
user_file_update_subid = GetCurrentSubTransactionId();
|
||||
if (auth_file_update_subid == InvalidSubTransactionId)
|
||||
auth_file_update_subid = GetCurrentSubTransactionId();
|
||||
}
|
||||
|
||||
|
||||
@@ -128,39 +119,20 @@ database_getflatfilename(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* group_getflatfilename --- get full pathname of group file
|
||||
* Get full pathname of auth file.
|
||||
*
|
||||
* Note that result string is palloc'd, and should be freed by the caller.
|
||||
*/
|
||||
char *
|
||||
group_getflatfilename(void)
|
||||
auth_getflatfilename(void)
|
||||
{
|
||||
int bufsize;
|
||||
char *pfnam;
|
||||
|
||||
bufsize = strlen(DataDir) + strlen("/global/") +
|
||||
strlen(GROUP_FLAT_FILE) + 1;
|
||||
strlen(AUTH_FLAT_FILE) + 1;
|
||||
pfnam = (char *) palloc(bufsize);
|
||||
snprintf(pfnam, bufsize, "%s/global/%s", DataDir, GROUP_FLAT_FILE);
|
||||
|
||||
return pfnam;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get full pathname of password file.
|
||||
*
|
||||
* Note that result string is palloc'd, and should be freed by the caller.
|
||||
*/
|
||||
char *
|
||||
user_getflatfilename(void)
|
||||
{
|
||||
int bufsize;
|
||||
char *pfnam;
|
||||
|
||||
bufsize = strlen(DataDir) + strlen("/global/") +
|
||||
strlen(USER_FLAT_FILE) + 1;
|
||||
pfnam = (char *) palloc(bufsize);
|
||||
snprintf(pfnam, bufsize, "%s/global/%s", DataDir, USER_FLAT_FILE);
|
||||
snprintf(pfnam, bufsize, "%s/global/%s", DataDir, AUTH_FLAT_FILE);
|
||||
|
||||
return pfnam;
|
||||
}
|
||||
@@ -189,7 +161,7 @@ fputs_quote(const char *str, FILE *fp)
|
||||
/*
|
||||
* name_okay
|
||||
*
|
||||
* We must disallow newlines in user and group names because
|
||||
* We must disallow newlines in role names because
|
||||
* hba.c's parser won't handle fields split across lines, even if quoted.
|
||||
*/
|
||||
static bool
|
||||
@@ -322,165 +294,81 @@ write_database_file(Relation drel)
|
||||
|
||||
|
||||
/*
|
||||
* write_group_file: update the flat group file
|
||||
* Support for write_auth_file
|
||||
*/
|
||||
static void
|
||||
write_group_file(Relation grel)
|
||||
|
||||
typedef struct {
|
||||
Oid roleid;
|
||||
char* rolname;
|
||||
char* rolpassword;
|
||||
char* rolvaliduntil;
|
||||
List* roles_names;
|
||||
} auth_entry;
|
||||
|
||||
typedef struct {
|
||||
Oid roleid;
|
||||
Oid memberid;
|
||||
} authmem_entry;
|
||||
|
||||
static int
|
||||
oid_compar(const void *a, const void *b)
|
||||
{
|
||||
char *filename,
|
||||
*tempname;
|
||||
int bufsize;
|
||||
FILE *fp;
|
||||
mode_t oumask;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
const auth_entry *a_auth = (const auth_entry*) a;
|
||||
const auth_entry *b_auth = (const auth_entry*) b;
|
||||
|
||||
/*
|
||||
* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the flat file while the postmaster
|
||||
* might be reading from it.
|
||||
*/
|
||||
filename = group_getflatfilename();
|
||||
bufsize = strlen(filename) + 12;
|
||||
tempname = (char *) palloc(bufsize);
|
||||
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
|
||||
|
||||
oumask = umask((mode_t) 077);
|
||||
fp = AllocateFile(tempname, "w");
|
||||
umask(oumask);
|
||||
if (fp == NULL)
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to temporary file \"%s\": %m",
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Read pg_group and write the file.
|
||||
*/
|
||||
scan = heap_beginscan(grel, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_group grpform = (Form_pg_group) GETSTRUCT(tuple);
|
||||
HeapTupleHeader tup = tuple->t_data;
|
||||
char *tp; /* ptr to tuple data */
|
||||
long off; /* offset in tuple data */
|
||||
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
|
||||
Datum datum;
|
||||
char *groname;
|
||||
IdList *grolist_p;
|
||||
AclId *aidp;
|
||||
int i,
|
||||
num;
|
||||
|
||||
groname = NameStr(grpform->groname);
|
||||
|
||||
/*
|
||||
* Check for illegal characters in the group name.
|
||||
*/
|
||||
if (!name_okay(groname))
|
||||
{
|
||||
ereport(LOG,
|
||||
(errmsg("invalid group name \"%s\"", groname)));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't use heap_getattr() here because during startup we will
|
||||
* not have any tupdesc for pg_group. Fortunately it's not too
|
||||
* hard to work around this. grolist is the first possibly-null
|
||||
* field so we can compute its offset directly.
|
||||
*/
|
||||
tp = (char *) tup + tup->t_hoff;
|
||||
off = offsetof(FormData_pg_group, grolist);
|
||||
|
||||
if (HeapTupleHasNulls(tuple) &&
|
||||
att_isnull(Anum_pg_group_grolist - 1, bp))
|
||||
{
|
||||
/* grolist is null, so we can ignore this group */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* assume grolist is pass-by-ref */
|
||||
datum = PointerGetDatum(tp + off);
|
||||
|
||||
/*
|
||||
* We can't currently support out-of-line toasted group lists in
|
||||
* startup mode (the tuptoaster won't work). This sucks, but it
|
||||
* should be something of a corner case. Live with it until we
|
||||
* can redesign pg_group.
|
||||
*
|
||||
* Detect startup mode by noting whether we got a tupdesc.
|
||||
*/
|
||||
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)) &&
|
||||
RelationGetDescr(grel) == NULL)
|
||||
continue;
|
||||
|
||||
/* be sure the IdList is not toasted */
|
||||
grolist_p = DatumGetIdListP(datum);
|
||||
|
||||
/*
|
||||
* The file format is: "groupname" usesysid1 usesysid2 ...
|
||||
*
|
||||
* We ignore groups that have no members.
|
||||
*/
|
||||
aidp = IDLIST_DAT(grolist_p);
|
||||
num = IDLIST_NUM(grolist_p);
|
||||
if (num > 0)
|
||||
{
|
||||
fputs_quote(groname, fp);
|
||||
fprintf(fp, "\t%u", aidp[0]);
|
||||
for (i = 1; i < num; ++i)
|
||||
fprintf(fp, " %u", aidp[i]);
|
||||
fputs("\n", fp);
|
||||
}
|
||||
|
||||
/* if IdList was toasted, free detoasted copy */
|
||||
if ((Pointer) grolist_p != DatumGetPointer(datum))
|
||||
pfree(grolist_p);
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
if (FreeFile(fp))
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not write to temporary file \"%s\": %m",
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Rename the temp file to its final name, deleting the old flat file.
|
||||
* We expect that rename(2) is an atomic action.
|
||||
*/
|
||||
if (rename(tempname, filename))
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not rename file \"%s\" to \"%s\": %m",
|
||||
tempname, filename)));
|
||||
|
||||
pfree(tempname);
|
||||
pfree(filename);
|
||||
if (a_auth->roleid < b_auth->roleid) return -1;
|
||||
if (a_auth->roleid > b_auth->roleid) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
name_compar(const void *a, const void *b)
|
||||
{
|
||||
const auth_entry *a_auth = (const auth_entry*) a;
|
||||
const auth_entry *b_auth = (const auth_entry*) b;
|
||||
|
||||
return strcmp(a_auth->rolname,b_auth->rolname);
|
||||
}
|
||||
|
||||
static int
|
||||
mem_compar(const void *a, const void *b)
|
||||
{
|
||||
const authmem_entry *a_auth = (const authmem_entry*) a;
|
||||
const authmem_entry *b_auth = (const authmem_entry*) b;
|
||||
|
||||
if (a_auth->memberid < b_auth->memberid) return -1;
|
||||
if (a_auth->memberid > b_auth->memberid) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* write_user_file: update the flat password file
|
||||
* write_auth_file: update the flat auth file
|
||||
*/
|
||||
static void
|
||||
write_user_file(Relation urel)
|
||||
write_auth_file(Relation rel_auth, Relation rel_authmem, bool startup)
|
||||
{
|
||||
char *filename,
|
||||
*tempname;
|
||||
int bufsize;
|
||||
BlockNumber totalblocks;
|
||||
FILE *fp;
|
||||
mode_t oumask;
|
||||
HeapScanDesc scan;
|
||||
HeapTuple tuple;
|
||||
int curr_role = 0;
|
||||
int total_roles = 0;
|
||||
int curr_mem = 0;
|
||||
int total_mem = 0;
|
||||
int est_rows;
|
||||
auth_entry *auth_info;
|
||||
authmem_entry *authmem_info = NULL;
|
||||
|
||||
/*
|
||||
* Create a temporary filename to be renamed later. This prevents the
|
||||
* backend from clobbering the flat file while the postmaster might
|
||||
* backend from clobbering the pg_auth file while the postmaster might
|
||||
* be reading from it.
|
||||
*/
|
||||
filename = user_getflatfilename();
|
||||
filename = auth_getflatfilename();
|
||||
bufsize = strlen(filename) + 12;
|
||||
tempname = (char *) palloc(bufsize);
|
||||
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
|
||||
@@ -495,39 +383,41 @@ write_user_file(Relation urel)
|
||||
tempname)));
|
||||
|
||||
/*
|
||||
* Read pg_shadow and write the file.
|
||||
* Read pg_authid and fill temporary data structures.
|
||||
*/
|
||||
scan = heap_beginscan(urel, SnapshotNow, 0, NULL);
|
||||
totalblocks = RelationGetNumberOfBlocks(rel_auth);
|
||||
totalblocks = totalblocks ? totalblocks : 1;
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_authid)));
|
||||
auth_info = (auth_entry*) palloc(est_rows*sizeof(auth_entry));
|
||||
|
||||
scan = heap_beginscan(rel_auth, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_shadow pwform = (Form_pg_shadow) GETSTRUCT(tuple);
|
||||
Form_pg_authid pwform = (Form_pg_authid) GETSTRUCT(tuple);
|
||||
HeapTupleHeader tup = tuple->t_data;
|
||||
char *tp; /* ptr to tuple data */
|
||||
long off; /* offset in tuple data */
|
||||
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
|
||||
Datum datum;
|
||||
char *usename,
|
||||
*passwd,
|
||||
*valuntil;
|
||||
AclId usesysid;
|
||||
|
||||
usename = NameStr(pwform->usename);
|
||||
usesysid = pwform->usesysid;
|
||||
auth_info[curr_role].roleid = HeapTupleGetOid(tuple);
|
||||
auth_info[curr_role].rolname = pstrdup(NameStr(pwform->rolname));
|
||||
auth_info[curr_role].roles_names = NIL;
|
||||
|
||||
/*
|
||||
* We can't use heap_getattr() here because during startup we will
|
||||
* not have any tupdesc for pg_shadow. Fortunately it's not too
|
||||
* hard to work around this. passwd is the first possibly-null
|
||||
* not have any tupdesc for pg_authid. Fortunately it's not too
|
||||
* hard to work around this. rolpassword is the first possibly-null
|
||||
* field so we can compute its offset directly.
|
||||
*/
|
||||
tp = (char *) tup + tup->t_hoff;
|
||||
off = offsetof(FormData_pg_shadow, passwd);
|
||||
off = offsetof(FormData_pg_authid, rolpassword);
|
||||
|
||||
if (HeapTupleHasNulls(tuple) &&
|
||||
att_isnull(Anum_pg_shadow_passwd - 1, bp))
|
||||
att_isnull(Anum_pg_authid_rolpassword - 1, bp))
|
||||
{
|
||||
/* passwd is null, emit as an empty string */
|
||||
passwd = pstrdup("");
|
||||
auth_info[curr_role].rolpassword = pstrdup("");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -539,60 +429,176 @@ write_user_file(Relation urel)
|
||||
* if it is, ignore it, since we can't handle that in startup mode.
|
||||
*/
|
||||
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
|
||||
passwd = pstrdup("");
|
||||
auth_info[curr_role].rolpassword = pstrdup("");
|
||||
else
|
||||
passwd = DatumGetCString(DirectFunctionCall1(textout, datum));
|
||||
auth_info[curr_role].rolpassword = DatumGetCString(DirectFunctionCall1(textout, datum));
|
||||
|
||||
/* assume passwd has attlen -1 */
|
||||
off = att_addlength(off, -1, tp + off);
|
||||
}
|
||||
|
||||
if (HeapTupleHasNulls(tuple) &&
|
||||
att_isnull(Anum_pg_shadow_valuntil - 1, bp))
|
||||
att_isnull(Anum_pg_authid_rolvaliduntil - 1, bp))
|
||||
{
|
||||
/* valuntil is null, emit as an empty string */
|
||||
valuntil = pstrdup("");
|
||||
/* rolvaliduntil is null, emit as an empty string */
|
||||
auth_info[curr_role].rolvaliduntil = pstrdup("");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* assume valuntil has attalign 'i' */
|
||||
off = att_align(off, 'i');
|
||||
/* assume valuntil is pass-by-value, integer size */
|
||||
datum = Int32GetDatum(*((int32 *) (tp + off)));
|
||||
valuntil = DatumGetCString(DirectFunctionCall1(abstimeout, datum));
|
||||
/*
|
||||
* rolvaliduntil is timestamptz, which we assume is double
|
||||
* alignment and pass-by-reference.
|
||||
*/
|
||||
off = att_align(off, 'd');
|
||||
datum = PointerGetDatum(tp + off);
|
||||
auth_info[curr_role].rolvaliduntil = DatumGetCString(DirectFunctionCall1(timestamptz_out, datum));
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for illegal characters in the user name and password.
|
||||
*/
|
||||
if (!name_okay(usename))
|
||||
if (!name_okay(auth_info[curr_role].rolname))
|
||||
{
|
||||
ereport(LOG,
|
||||
(errmsg("invalid user name \"%s\"", usename)));
|
||||
(errmsg("invalid role name \"%s\"",
|
||||
auth_info[curr_role].rolname)));
|
||||
pfree(auth_info[curr_role].rolname);
|
||||
pfree(auth_info[curr_role].rolpassword);
|
||||
pfree(auth_info[curr_role].rolvaliduntil);
|
||||
continue;
|
||||
}
|
||||
if (!name_okay(passwd))
|
||||
if (!name_okay(auth_info[curr_role].rolpassword))
|
||||
{
|
||||
ereport(LOG,
|
||||
(errmsg("invalid user password \"%s\"", passwd)));
|
||||
(errmsg("invalid role password \"%s\"",
|
||||
auth_info[curr_role].rolpassword)));
|
||||
pfree(auth_info[curr_role].rolname);
|
||||
pfree(auth_info[curr_role].rolpassword);
|
||||
pfree(auth_info[curr_role].rolvaliduntil);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The file format is: "usename" usesysid "passwd" "valuntil"
|
||||
*/
|
||||
fputs_quote(usename, fp);
|
||||
fprintf(fp, " %u ", usesysid);
|
||||
fputs_quote(passwd, fp);
|
||||
fputs(" ", fp);
|
||||
fputs_quote(valuntil, fp);
|
||||
fputs("\n", fp);
|
||||
|
||||
pfree(passwd);
|
||||
pfree(valuntil);
|
||||
curr_role++;
|
||||
total_roles++;
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
Assert(total_roles <= est_rows);
|
||||
|
||||
qsort(auth_info, total_roles, sizeof(auth_entry), oid_compar);
|
||||
|
||||
/*
|
||||
* Read pg_auth_members into temporary data structure, too
|
||||
*/
|
||||
totalblocks = RelationGetNumberOfBlocks(rel_authmem);
|
||||
totalblocks = totalblocks ? totalblocks : 1;
|
||||
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_auth_members)));
|
||||
authmem_info = (authmem_entry*) palloc(est_rows*sizeof(authmem_entry));
|
||||
|
||||
scan = heap_beginscan(rel_authmem, SnapshotNow, 0, NULL);
|
||||
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
|
||||
{
|
||||
Form_pg_auth_members memform = (Form_pg_auth_members) GETSTRUCT(tuple);
|
||||
|
||||
authmem_info[curr_mem].roleid = memform->roleid;
|
||||
authmem_info[curr_mem].memberid = memform->member;
|
||||
curr_mem++;
|
||||
total_mem++;
|
||||
}
|
||||
heap_endscan(scan);
|
||||
|
||||
Assert(total_mem <= est_rows);
|
||||
|
||||
qsort(authmem_info, total_mem, sizeof(authmem_entry), mem_compar);
|
||||
|
||||
for (curr_role = 0; curr_role < total_roles; curr_role++)
|
||||
{
|
||||
int first_found, last_found, curr_mem;
|
||||
List *roles_list_hunt = NIL;
|
||||
List *roles_list = NIL;
|
||||
ListCell *mem = NULL;
|
||||
auth_entry *found_role = NULL, key_auth;
|
||||
authmem_entry key;
|
||||
authmem_entry *found_mem = NULL;
|
||||
|
||||
roles_list_hunt = lappend_oid(roles_list_hunt,
|
||||
auth_info[curr_role].roleid);
|
||||
|
||||
while (roles_list_hunt)
|
||||
{
|
||||
key.memberid = linitial_oid(roles_list_hunt);
|
||||
roles_list_hunt = list_delete_first(roles_list_hunt);
|
||||
if (total_mem)
|
||||
found_mem = bsearch(&key, authmem_info, total_mem,
|
||||
sizeof(authmem_entry), mem_compar);
|
||||
if (found_mem)
|
||||
{
|
||||
/*
|
||||
* bsearch found a match for us; but if there were multiple
|
||||
* matches it could have found any one of them.
|
||||
*/
|
||||
first_found = last_found = (found_mem - authmem_info);
|
||||
while (first_found > 0 &&
|
||||
mem_compar(&key, &authmem_info[first_found - 1]) == 0)
|
||||
first_found--;
|
||||
while (last_found + 1 < total_mem &&
|
||||
mem_compar(&key, &authmem_info[last_found + 1]) == 0)
|
||||
last_found++;
|
||||
|
||||
for (curr_mem = first_found; curr_mem <= last_found; curr_mem++)
|
||||
{
|
||||
Oid otherrole = authmem_info[curr_mem].roleid;
|
||||
|
||||
if (!list_member_oid(roles_list, otherrole))
|
||||
{
|
||||
roles_list = lappend_oid(roles_list,
|
||||
otherrole);
|
||||
roles_list_hunt = lappend_oid(roles_list_hunt,
|
||||
otherrole);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(mem, roles_list)
|
||||
{
|
||||
key_auth.roleid = lfirst_oid(mem);
|
||||
found_role = bsearch(&key_auth, auth_info, total_roles, sizeof(auth_entry), oid_compar);
|
||||
auth_info[curr_role].roles_names = lappend(auth_info[curr_role].roles_names,found_role->rolname);
|
||||
}
|
||||
}
|
||||
|
||||
qsort(auth_info, total_roles, sizeof(auth_entry), name_compar);
|
||||
|
||||
for (curr_role = 0; curr_role < total_roles; curr_role++)
|
||||
{
|
||||
ListCell *mem = NULL;
|
||||
|
||||
/*----------
|
||||
* The file format is:
|
||||
* "rolename" "password" "validuntil" "member" "member" ...
|
||||
* where lines are expected to be in order by rolename
|
||||
*----------
|
||||
*/
|
||||
fputs_quote(auth_info[curr_role].rolname, fp);
|
||||
fputs(" ", fp);
|
||||
fputs_quote(auth_info[curr_role].rolpassword, fp);
|
||||
fputs(" ", fp);
|
||||
fputs_quote(auth_info[curr_role].rolvaliduntil, fp);
|
||||
|
||||
foreach(mem, auth_info[curr_role].roles_names)
|
||||
{
|
||||
fputs(" ", fp);
|
||||
fputs_quote(lfirst(mem), fp);
|
||||
}
|
||||
|
||||
fputs("\n", fp);
|
||||
|
||||
pfree(auth_info[curr_role].rolname);
|
||||
pfree(auth_info[curr_role].rolpassword);
|
||||
pfree(auth_info[curr_role].rolvaliduntil);
|
||||
}
|
||||
|
||||
if (FreeFile(fp))
|
||||
ereport(ERROR,
|
||||
(errcode_for_file_access(),
|
||||
@@ -609,6 +615,8 @@ write_user_file(Relation urel)
|
||||
errmsg("could not rename file \"%s\" to \"%s\": %m",
|
||||
tempname, filename)));
|
||||
|
||||
pfree(auth_info);
|
||||
pfree(authmem_info);
|
||||
pfree(tempname);
|
||||
pfree(filename);
|
||||
}
|
||||
@@ -634,7 +642,7 @@ BuildFlatFiles(bool database_only)
|
||||
{
|
||||
ResourceOwner owner;
|
||||
RelFileNode rnode;
|
||||
Relation rel;
|
||||
Relation rel, rel_auth, rel_authmem;
|
||||
|
||||
/*
|
||||
* We don't have any hope of running a real relcache, but we can use
|
||||
@@ -657,21 +665,16 @@ BuildFlatFiles(bool database_only)
|
||||
|
||||
if (!database_only)
|
||||
{
|
||||
/* hard-wired path to pg_group */
|
||||
/* hard-wired path to pg_auth */
|
||||
rnode.spcNode = GLOBALTABLESPACE_OID;
|
||||
rnode.dbNode = 0;
|
||||
rnode.relNode = GroupRelationId;
|
||||
rnode.relNode = AuthIdRelationId;
|
||||
rel_auth = XLogOpenRelation(rnode);
|
||||
|
||||
rel = XLogOpenRelation(rnode);
|
||||
write_group_file(rel);
|
||||
|
||||
/* hard-wired path to pg_shadow */
|
||||
rnode.spcNode = GLOBALTABLESPACE_OID;
|
||||
rnode.dbNode = 0;
|
||||
rnode.relNode = ShadowRelationId;
|
||||
|
||||
rel = XLogOpenRelation(rnode);
|
||||
write_user_file(rel);
|
||||
rnode.relNode = AuthMemRelationId;
|
||||
rel_authmem = XLogOpenRelation(rnode);
|
||||
}
|
||||
|
||||
CurrentResourceOwner = NULL;
|
||||
@@ -699,19 +702,17 @@ void
|
||||
AtEOXact_UpdateFlatFiles(bool isCommit)
|
||||
{
|
||||
Relation drel = NULL;
|
||||
Relation grel = NULL;
|
||||
Relation urel = NULL;
|
||||
Relation arel = NULL;
|
||||
Relation mrel = NULL;
|
||||
|
||||
if (database_file_update_subid == InvalidSubTransactionId &&
|
||||
group_file_update_subid == InvalidSubTransactionId &&
|
||||
user_file_update_subid == InvalidSubTransactionId)
|
||||
auth_file_update_subid == InvalidSubTransactionId)
|
||||
return; /* nothing to do */
|
||||
|
||||
if (!isCommit)
|
||||
{
|
||||
database_file_update_subid = InvalidSubTransactionId;
|
||||
group_file_update_subid = InvalidSubTransactionId;
|
||||
user_file_update_subid = InvalidSubTransactionId;
|
||||
auth_file_update_subid = InvalidSubTransactionId;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -731,10 +732,10 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
|
||||
*/
|
||||
if (database_file_update_subid != InvalidSubTransactionId)
|
||||
drel = heap_open(DatabaseRelationId, ExclusiveLock);
|
||||
if (group_file_update_subid != InvalidSubTransactionId)
|
||||
grel = heap_open(GroupRelationId, ExclusiveLock);
|
||||
if (user_file_update_subid != InvalidSubTransactionId)
|
||||
urel = heap_open(ShadowRelationId, ExclusiveLock);
|
||||
if (auth_file_update_subid != InvalidSubTransactionId) {
|
||||
arel = heap_open(AuthIdRelationId, ExclusiveLock);
|
||||
mrel = heap_open(AuthMemRelationId, ExclusiveLock);
|
||||
}
|
||||
|
||||
/* Okay to write the files */
|
||||
if (database_file_update_subid != InvalidSubTransactionId)
|
||||
@@ -744,18 +745,12 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
|
||||
heap_close(drel, NoLock);
|
||||
}
|
||||
|
||||
if (group_file_update_subid != InvalidSubTransactionId)
|
||||
if (auth_file_update_subid != InvalidSubTransactionId)
|
||||
{
|
||||
group_file_update_subid = InvalidSubTransactionId;
|
||||
write_group_file(grel);
|
||||
heap_close(grel, NoLock);
|
||||
}
|
||||
|
||||
if (user_file_update_subid != InvalidSubTransactionId)
|
||||
{
|
||||
user_file_update_subid = InvalidSubTransactionId;
|
||||
write_user_file(urel);
|
||||
heap_close(urel, NoLock);
|
||||
auth_file_update_subid = InvalidSubTransactionId;
|
||||
write_auth_file(arel, mrel, false);
|
||||
heap_close(arel, NoLock);
|
||||
heap_close(mrel, NoLock);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -785,15 +780,10 @@ AtPrepare_UpdateFlatFiles(void)
|
||||
database_file_update_subid = InvalidSubTransactionId;
|
||||
info |= FF_BIT_DATABASE;
|
||||
}
|
||||
if (group_file_update_subid != InvalidSubTransactionId)
|
||||
if (auth_file_update_subid != InvalidSubTransactionId)
|
||||
{
|
||||
group_file_update_subid = InvalidSubTransactionId;
|
||||
info |= FF_BIT_GROUP;
|
||||
}
|
||||
if (user_file_update_subid != InvalidSubTransactionId)
|
||||
{
|
||||
user_file_update_subid = InvalidSubTransactionId;
|
||||
info |= FF_BIT_USER;
|
||||
auth_file_update_subid = InvalidSubTransactionId;
|
||||
info |= FF_BIT_AUTH;
|
||||
}
|
||||
if (info != 0)
|
||||
RegisterTwoPhaseRecord(TWOPHASE_RM_FLATFILES_ID, info,
|
||||
@@ -817,29 +807,23 @@ AtEOSubXact_UpdateFlatFiles(bool isCommit,
|
||||
if (database_file_update_subid == mySubid)
|
||||
database_file_update_subid = parentSubid;
|
||||
|
||||
if (group_file_update_subid == mySubid)
|
||||
group_file_update_subid = parentSubid;
|
||||
|
||||
if (user_file_update_subid == mySubid)
|
||||
user_file_update_subid = parentSubid;
|
||||
if (auth_file_update_subid == mySubid)
|
||||
auth_file_update_subid = parentSubid;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (database_file_update_subid == mySubid)
|
||||
database_file_update_subid = InvalidSubTransactionId;
|
||||
|
||||
if (group_file_update_subid == mySubid)
|
||||
group_file_update_subid = InvalidSubTransactionId;
|
||||
|
||||
if (user_file_update_subid == mySubid)
|
||||
user_file_update_subid = InvalidSubTransactionId;
|
||||
if (auth_file_update_subid == mySubid)
|
||||
auth_file_update_subid = InvalidSubTransactionId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This trigger is fired whenever someone modifies pg_database, pg_shadow
|
||||
* or pg_group via general-purpose INSERT/UPDATE/DELETE commands.
|
||||
* This trigger is fired whenever someone modifies pg_database, pg_authid
|
||||
* or pg_auth_members via general-purpose INSERT/UPDATE/DELETE commands.
|
||||
*
|
||||
* It is sufficient for this to be a STATEMENT trigger since we don't
|
||||
* care which individual rows changed. It doesn't much matter whether
|
||||
@@ -862,11 +846,11 @@ flatfile_update_trigger(PG_FUNCTION_ARGS)
|
||||
case DatabaseRelationId:
|
||||
database_file_update_needed();
|
||||
break;
|
||||
case GroupRelationId:
|
||||
group_file_update_needed();
|
||||
case AuthIdRelationId:
|
||||
auth_file_update_needed();
|
||||
break;
|
||||
case ShadowRelationId:
|
||||
user_file_update_needed();
|
||||
case AuthMemRelationId:
|
||||
auth_file_update_needed();
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "flatfile_update_trigger was called for wrong table");
|
||||
@@ -895,8 +879,6 @@ flatfile_twophase_postcommit(TransactionId xid, uint16 info,
|
||||
*/
|
||||
if (info & FF_BIT_DATABASE)
|
||||
database_file_update_needed();
|
||||
if (info & FF_BIT_GROUP)
|
||||
group_file_update_needed();
|
||||
if (info & FF_BIT_USER)
|
||||
user_file_update_needed();
|
||||
if (info & FF_BIT_AUTH)
|
||||
auth_file_update_needed();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.142 2005/06/20 02:17:30 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.143 2005/06/28 05:09:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "libpq/libpq-be.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/fd.h"
|
||||
@@ -251,7 +251,7 @@ make_absolute_path(const char *path)
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* User ID things
|
||||
* Role ID things
|
||||
*
|
||||
* The authenticated user is determined at connection start and never
|
||||
* changes. The session user can be changed only by SET SESSION
|
||||
@@ -261,60 +261,60 @@ make_absolute_path(const char *path)
|
||||
* restore the current user id if you need to change it.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static AclId AuthenticatedUserId = 0;
|
||||
static AclId SessionUserId = 0;
|
||||
static AclId CurrentUserId = 0;
|
||||
static Oid AuthenticatedUserId = InvalidOid;
|
||||
static Oid SessionUserId = InvalidOid;
|
||||
static Oid CurrentUserId = InvalidOid;
|
||||
|
||||
static bool AuthenticatedUserIsSuperuser = false;
|
||||
|
||||
/*
|
||||
* This function is relevant for all privilege checks.
|
||||
*/
|
||||
AclId
|
||||
Oid
|
||||
GetUserId(void)
|
||||
{
|
||||
AssertState(AclIdIsValid(CurrentUserId));
|
||||
AssertState(OidIsValid(CurrentUserId));
|
||||
return CurrentUserId;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetUserId(AclId newid)
|
||||
SetUserId(Oid roleid)
|
||||
{
|
||||
AssertArg(AclIdIsValid(newid));
|
||||
CurrentUserId = newid;
|
||||
AssertArg(OidIsValid(roleid));
|
||||
CurrentUserId = roleid;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This value is only relevant for informational purposes.
|
||||
*/
|
||||
AclId
|
||||
Oid
|
||||
GetSessionUserId(void)
|
||||
{
|
||||
AssertState(AclIdIsValid(SessionUserId));
|
||||
AssertState(OidIsValid(SessionUserId));
|
||||
return SessionUserId;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SetSessionUserId(AclId newid)
|
||||
SetSessionUserId(Oid roleid)
|
||||
{
|
||||
AssertArg(AclIdIsValid(newid));
|
||||
SessionUserId = newid;
|
||||
AssertArg(OidIsValid(roleid));
|
||||
SessionUserId = roleid;
|
||||
/* Current user defaults to session user. */
|
||||
if (!AclIdIsValid(CurrentUserId))
|
||||
CurrentUserId = newid;
|
||||
if (!OidIsValid(CurrentUserId))
|
||||
CurrentUserId = roleid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitializeSessionUserId(const char *username)
|
||||
InitializeSessionUserId(const char *rolename)
|
||||
{
|
||||
HeapTuple userTup;
|
||||
HeapTuple roleTup;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
AclId usesysid;
|
||||
Oid roleid;
|
||||
|
||||
/*
|
||||
* Don't do scans if we're bootstrapping, none of the system catalogs
|
||||
@@ -325,23 +325,23 @@ InitializeSessionUserId(const char *username)
|
||||
/* call only once */
|
||||
AssertState(!OidIsValid(AuthenticatedUserId));
|
||||
|
||||
userTup = SearchSysCache(SHADOWNAME,
|
||||
PointerGetDatum(username),
|
||||
roleTup = SearchSysCache(AUTHNAME,
|
||||
PointerGetDatum(rolename),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(userTup))
|
||||
if (!HeapTupleIsValid(roleTup))
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("user \"%s\" does not exist", username)));
|
||||
errmsg("role \"%s\" does not exist", rolename)));
|
||||
|
||||
usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
|
||||
roleid = HeapTupleGetOid(roleTup);
|
||||
|
||||
AuthenticatedUserId = usesysid;
|
||||
AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
|
||||
AuthenticatedUserId = roleid;
|
||||
AuthenticatedUserIsSuperuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
|
||||
|
||||
SetSessionUserId(usesysid); /* sets CurrentUserId too */
|
||||
SetSessionUserId(roleid); /* sets CurrentUserId too */
|
||||
|
||||
/* Record username and superuser status as GUC settings too */
|
||||
SetConfigOption("session_authorization", username,
|
||||
SetConfigOption("session_authorization", rolename,
|
||||
PGC_BACKEND, PGC_S_OVERRIDE);
|
||||
SetConfigOption("is_superuser",
|
||||
AuthenticatedUserIsSuperuser ? "on" : "off",
|
||||
@@ -349,11 +349,11 @@ InitializeSessionUserId(const char *username)
|
||||
|
||||
/*
|
||||
* Set up user-specific configuration variables. This is a good place
|
||||
* to do it so we don't have to read pg_shadow twice during session
|
||||
* to do it so we don't have to read pg_authid twice during session
|
||||
* startup.
|
||||
*/
|
||||
datum = SysCacheGetAttr(SHADOWNAME, userTup,
|
||||
Anum_pg_shadow_useconfig, &isnull);
|
||||
datum = SysCacheGetAttr(AUTHNAME, roleTup,
|
||||
Anum_pg_authid_rolconfig, &isnull);
|
||||
if (!isnull)
|
||||
{
|
||||
ArrayType *a = DatumGetArrayTypeP(datum);
|
||||
@@ -361,7 +361,7 @@ InitializeSessionUserId(const char *username)
|
||||
ProcessGUCArray(a, PGC_S_USER);
|
||||
}
|
||||
|
||||
ReleaseSysCache(userTup);
|
||||
ReleaseSysCache(roleTup);
|
||||
}
|
||||
|
||||
|
||||
@@ -374,10 +374,10 @@ InitializeSessionUserIdStandalone(void)
|
||||
/* call only once */
|
||||
AssertState(!OidIsValid(AuthenticatedUserId));
|
||||
|
||||
AuthenticatedUserId = BOOTSTRAP_USESYSID;
|
||||
AuthenticatedUserId = BOOTSTRAP_SUPERUSERID;
|
||||
AuthenticatedUserIsSuperuser = true;
|
||||
|
||||
SetSessionUserId(BOOTSTRAP_USESYSID);
|
||||
SetSessionUserId(BOOTSTRAP_SUPERUSERID);
|
||||
}
|
||||
|
||||
|
||||
@@ -390,19 +390,19 @@ InitializeSessionUserIdStandalone(void)
|
||||
* to indicate whether the *current* session userid is a superuser.
|
||||
*/
|
||||
void
|
||||
SetSessionAuthorization(AclId userid, bool is_superuser)
|
||||
SetSessionAuthorization(Oid roleid, bool is_superuser)
|
||||
{
|
||||
/* Must have authenticated already, else can't make permission check */
|
||||
AssertState(AclIdIsValid(AuthenticatedUserId));
|
||||
AssertState(OidIsValid(AuthenticatedUserId));
|
||||
|
||||
if (userid != AuthenticatedUserId &&
|
||||
if (roleid != AuthenticatedUserId &&
|
||||
!AuthenticatedUserIsSuperuser)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied to set session authorization")));
|
||||
|
||||
SetSessionUserId(userid);
|
||||
SetUserId(userid);
|
||||
SetSessionUserId(roleid);
|
||||
SetUserId(roleid);
|
||||
|
||||
SetConfigOption("is_superuser",
|
||||
is_superuser ? "on" : "off",
|
||||
@@ -411,30 +411,29 @@ SetSessionAuthorization(AclId userid, bool is_superuser)
|
||||
|
||||
|
||||
/*
|
||||
* Get user name from user id
|
||||
* Get user name from user oid
|
||||
*/
|
||||
char *
|
||||
GetUserNameFromId(AclId userid)
|
||||
GetUserNameFromId(Oid roleid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
char *result;
|
||||
|
||||
tuple = SearchSysCache(SHADOWSYSID,
|
||||
ObjectIdGetDatum(userid),
|
||||
tuple = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(roleid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("invalid user ID: %d", userid)));
|
||||
errmsg("invalid role OID: %u", roleid)));
|
||||
|
||||
result = pstrdup(NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename));
|
||||
result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Interlock-file support
|
||||
*
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.149 2005/06/24 01:06:26 neilc Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.150 2005/06/28 05:09:02 tgl Exp $
|
||||
*
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
@@ -20,11 +20,11 @@
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "catalog/catalog.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_database.h"
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "libpq/hba.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/sinval.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/flatfiles.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/guc.h"
|
||||
@@ -49,7 +50,7 @@ static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace);
|
||||
static void ReverifyMyDatabase(const char *name);
|
||||
static void InitCommunication(void);
|
||||
static void ShutdownPostgres(int code, Datum arg);
|
||||
static bool ThereIsAtLeastOneUser(void);
|
||||
static bool ThereIsAtLeastOneRole(void);
|
||||
|
||||
|
||||
/*** InitPostgres support ***/
|
||||
@@ -415,12 +416,12 @@ InitPostgres(const char *dbname, const char *username)
|
||||
else if (!IsUnderPostmaster)
|
||||
{
|
||||
InitializeSessionUserIdStandalone();
|
||||
if (!ThereIsAtLeastOneUser())
|
||||
if (!ThereIsAtLeastOneRole())
|
||||
ereport(WARNING,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("no users are defined in this database system"),
|
||||
errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.",
|
||||
username, BOOTSTRAP_USESYSID)));
|
||||
errmsg("no roles are defined in this database system"),
|
||||
errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.",
|
||||
username)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -469,6 +470,9 @@ InitPostgres(const char *dbname, const char *username)
|
||||
/* set default namespace search path */
|
||||
InitializeSearchPath();
|
||||
|
||||
/* set up ACL framework (currently just sets RolMemCache callback) */
|
||||
InitializeAcl();
|
||||
|
||||
/* initialize client encoding */
|
||||
InitializeClientEncoding();
|
||||
|
||||
@@ -530,22 +534,22 @@ ShutdownPostgres(int code, Datum arg)
|
||||
|
||||
|
||||
/*
|
||||
* Returns true if at least one user is defined in this database cluster.
|
||||
* Returns true if at least one role is defined in this database cluster.
|
||||
*/
|
||||
static bool
|
||||
ThereIsAtLeastOneUser(void)
|
||||
ThereIsAtLeastOneRole(void)
|
||||
{
|
||||
Relation pg_shadow_rel;
|
||||
Relation pg_authid_rel;
|
||||
HeapScanDesc scan;
|
||||
bool result;
|
||||
|
||||
pg_shadow_rel = heap_open(ShadowRelationId, AccessExclusiveLock);
|
||||
pg_authid_rel = heap_open(AuthIdRelationId, AccessExclusiveLock);
|
||||
|
||||
scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
|
||||
scan = heap_beginscan(pg_authid_rel, SnapshotNow, 0, NULL);
|
||||
result = (heap_getnext(scan, ForwardScanDirection) != NULL);
|
||||
|
||||
heap_endscan(scan);
|
||||
heap_close(pg_shadow_rel, AccessExclusiveLock);
|
||||
heap_close(pg_authid_rel, AccessExclusiveLock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.270 2005/06/26 19:16:06 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.271 2005/06/28 05:09:02 tgl Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
@@ -5108,7 +5108,7 @@ ParseLongOption(const char *string, char **name, char **value)
|
||||
|
||||
|
||||
/*
|
||||
* Handle options fetched from pg_database.datconfig or pg_shadow.useconfig.
|
||||
* Handle options fetched from pg_database.datconfig or pg_authid.rolconfig.
|
||||
* The array parameter must be an array of TEXT (it must not be NULL).
|
||||
*/
|
||||
void
|
||||
@@ -5154,7 +5154,7 @@ ProcessGUCArray(ArrayType *array, GucSource source)
|
||||
|
||||
/*
|
||||
* We process all these options at SUSET level. We assume that
|
||||
* the right to insert an option into pg_database or pg_shadow was
|
||||
* the right to insert an option into pg_database or pg_authid was
|
||||
* checked when it was inserted.
|
||||
*/
|
||||
SetConfigOption(name, value, PGC_SUSET, source);
|
||||
|
||||
@@ -14,29 +14,29 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.31 2005/05/29 20:38:06 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.32 2005/06/28 05:09:02 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/pg_shadow.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "miscadmin.h"
|
||||
|
||||
|
||||
/*
|
||||
* In common cases the same userid (ie, the session or current ID) will
|
||||
* In common cases the same roleid (ie, the session or current ID) will
|
||||
* be queried repeatedly. So we maintain a simple one-entry cache for
|
||||
* the status of the last requested userid. The cache can be flushed
|
||||
* at need by watching for cache update events on pg_shadow.
|
||||
* the status of the last requested roleid. The cache can be flushed
|
||||
* at need by watching for cache update events on pg_authid.
|
||||
*/
|
||||
static AclId last_userid = 0; /* 0 == cache not valid */
|
||||
static bool last_userid_is_super = false;
|
||||
static bool userid_callback_registered = false;
|
||||
static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */
|
||||
static bool last_roleid_is_super = false;
|
||||
static bool roleid_callback_registered = false;
|
||||
|
||||
static void UseridCallback(Datum arg, Oid relid);
|
||||
static void RoleidCallback(Datum arg, Oid relid);
|
||||
|
||||
|
||||
/*
|
||||
@@ -50,49 +50,49 @@ superuser(void)
|
||||
|
||||
|
||||
/*
|
||||
* The specified userid has Postgres superuser privileges
|
||||
* The specified role has Postgres superuser privileges
|
||||
*/
|
||||
bool
|
||||
superuser_arg(AclId userid)
|
||||
superuser_arg(Oid roleid)
|
||||
{
|
||||
bool result;
|
||||
HeapTuple utup;
|
||||
HeapTuple rtup;
|
||||
|
||||
/* Quick out for cache hit */
|
||||
if (AclIdIsValid(last_userid) && last_userid == userid)
|
||||
return last_userid_is_super;
|
||||
if (OidIsValid(last_roleid) && last_roleid == roleid)
|
||||
return last_roleid_is_super;
|
||||
|
||||
/* Special escape path in case you deleted all your users. */
|
||||
if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID)
|
||||
if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
|
||||
return true;
|
||||
|
||||
/* OK, look up the information in pg_shadow */
|
||||
utup = SearchSysCache(SHADOWSYSID,
|
||||
Int32GetDatum(userid),
|
||||
/* OK, look up the information in pg_authid */
|
||||
rtup = SearchSysCache(AUTHOID,
|
||||
ObjectIdGetDatum(roleid),
|
||||
0, 0, 0);
|
||||
if (HeapTupleIsValid(utup))
|
||||
if (HeapTupleIsValid(rtup))
|
||||
{
|
||||
result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
|
||||
ReleaseSysCache(utup);
|
||||
result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
|
||||
ReleaseSysCache(rtup);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Report "not superuser" for invalid userids */
|
||||
/* Report "not superuser" for invalid roleids */
|
||||
result = false;
|
||||
}
|
||||
|
||||
/* If first time through, set up callback for cache flushes */
|
||||
if (!userid_callback_registered)
|
||||
if (!roleid_callback_registered)
|
||||
{
|
||||
CacheRegisterSyscacheCallback(SHADOWSYSID,
|
||||
UseridCallback,
|
||||
CacheRegisterSyscacheCallback(AUTHOID,
|
||||
RoleidCallback,
|
||||
(Datum) 0);
|
||||
userid_callback_registered = true;
|
||||
roleid_callback_registered = true;
|
||||
}
|
||||
|
||||
/* Cache the result for next time */
|
||||
last_userid = userid;
|
||||
last_userid_is_super = result;
|
||||
last_roleid = roleid;
|
||||
last_roleid_is_super = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -102,8 +102,8 @@ superuser_arg(AclId userid)
|
||||
* Syscache inval callback function
|
||||
*/
|
||||
static void
|
||||
UseridCallback(Datum arg, Oid relid)
|
||||
RoleidCallback(Datum arg, Oid relid)
|
||||
{
|
||||
/* Invalidate our local cache in case user's superuserness changed */
|
||||
last_userid = 0;
|
||||
/* Invalidate our local cache in case role's superuserness changed */
|
||||
last_roleid = InvalidOid;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user